diff options
author | Max Kellermann <max@duempel.org> | 2008-10-23 20:00:51 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-10-23 20:00:51 +0200 |
commit | 6b1c54ef9646abddfbd4960c207b32426300a90c (patch) | |
tree | 5b3ae6bf5fc377cf9c705c85948ab5b85e31743c /src/pcm_utils.c | |
parent | 098991f8e8a974d2eee39645fa23c43a4c8b06c1 (diff) | |
download | mpd-6b1c54ef9646abddfbd4960c207b32426300a90c.tar.gz mpd-6b1c54ef9646abddfbd4960c207b32426300a90c.tar.xz mpd-6b1c54ef9646abddfbd4960c207b32426300a90c.zip |
pcm_utils: moved code to pcm_resample.c
Separate the resampling code from the rest of pcm_utils.c. Create two
sub-libraries: pcm_resample_libsamplerate.c and
pcm_resample_fallback.c.
Diffstat (limited to 'src/pcm_utils.c')
-rw-r--r-- | src/pcm_utils.c | 168 |
1 files changed, 6 insertions, 162 deletions
diff --git a/src/pcm_utils.c b/src/pcm_utils.c index 8d5bed990..6d76aba90 100644 --- a/src/pcm_utils.c +++ b/src/pcm_utils.c @@ -209,166 +209,10 @@ void pcm_convert_init(struct pcm_convert_state *state) { memset(state, 0, sizeof(*state)); + pcm_resample_init(&state->resample); pcm_dither_24_init(&state->dither); } -#ifdef HAVE_LIBSAMPLERATE -static int pcm_resample_get_converter(void) -{ - const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER); - long convalgo; - char *test; - const char *test2; - size_t len; - - if (!conf) { - convalgo = SRC_SINC_FASTEST; - goto out; - } - - convalgo = strtol(conf, &test, 10); - if (*test == '\0' && src_get_name(convalgo)) - goto out; - - len = strlen(conf); - for (convalgo = 0 ; ; convalgo++) { - test2 = src_get_name(convalgo); - if (!test2) { - convalgo = SRC_SINC_FASTEST; - break; - } - if (strncasecmp(test2, conf, len) == 0) - goto out; - } - - ERROR("unknown samplerate converter \"%s\"\n", conf); -out: - DEBUG("selecting samplerate converter \"%s\"\n", - src_get_name(convalgo)); - - return convalgo; -} -#endif - -#ifdef HAVE_LIBSAMPLERATE -static size_t pcm_resample(int8_t channels, uint32_t inSampleRate, - const int16_t *src, size_t src_size, - uint32_t outSampleRate, int16_t *outBuffer, - size_t outSize, - struct pcm_convert_state *convState) -{ - static int convalgo = -1; - SRC_DATA *data = &convState->data; - size_t dataInSize; - size_t dataOutSize; - int error; - - if (convalgo < 0) - convalgo = pcm_resample_get_converter(); - - /* (re)set the state/ratio if the in or out format changed */ - if ((channels != convState->lastChannels) || - (inSampleRate != convState->lastInSampleRate) || - (outSampleRate != convState->lastOutSampleRate)) { - convState->error = 0; - convState->lastChannels = channels; - convState->lastInSampleRate = inSampleRate; - convState->lastOutSampleRate = outSampleRate; - - if (convState->state) - convState->state = src_delete(convState->state); - - convState->state = src_new(convalgo, channels, &error); - if (!convState->state) { - ERROR("cannot create new libsamplerate state: %s\n", - src_strerror(error)); - convState->error = 1; - return 0; - } - - data->src_ratio = (double)outSampleRate / (double)inSampleRate; - DEBUG("setting samplerate conversion ratio to %.2lf\n", - data->src_ratio); - src_set_ratio(convState->state, data->src_ratio); - } - - /* there was an error previously, and nothing has changed */ - if (convState->error) - return 0; - - data->input_frames = src_size / 2 / channels; - dataInSize = data->input_frames * sizeof(float) * channels; - if (dataInSize > convState->dataInSize) { - convState->dataInSize = dataInSize; - data->data_in = xrealloc(data->data_in, dataInSize); - } - - data->output_frames = outSize / 2 / channels; - dataOutSize = data->output_frames * sizeof(float) * channels; - if (dataOutSize > convState->dataOutSize) { - convState->dataOutSize = dataOutSize; - data->data_out = xrealloc(data->data_out, dataOutSize); - } - - src_short_to_float_array((const short *)src, data->data_in, - data->input_frames * channels); - - error = src_process(convState->state, data); - if (error) { - ERROR("error processing samples with libsamplerate: %s\n", - src_strerror(error)); - convState->error = 1; - return 0; - } - - src_float_to_short_array(data->data_out, (short *)outBuffer, - data->output_frames_gen * channels); - - return data->output_frames_gen * 2 * channels; -} -#else /* !HAVE_LIBSAMPLERATE */ -/* resampling code blatantly ripped from ESD */ -static size_t pcm_resample(int8_t channels, uint32_t inSampleRate, - const int16_t *src, mpd_unused size_t src_size, - uint32_t outSampleRate, char *outBuffer, - size_t outSize, - mpd_unused struct pcm_convert_state *convState) -{ - uint32_t rd_dat = 0; - uint32_t wr_dat = 0; - const int16_t *in = (const int16_t *)src; - int16_t *out = (int16_t *)outBuffer; - uint32_t nlen = outSize / 2; - int16_t lsample, rsample; - - switch (channels) { - case 1: - while (wr_dat < nlen) { - rd_dat = wr_dat * inSampleRate / outSampleRate; - - lsample = in[rd_dat++]; - - out[wr_dat++] = lsample; - } - break; - case 2: - while (wr_dat < nlen) { - rd_dat = wr_dat * inSampleRate / outSampleRate; - rd_dat &= ~1; - - lsample = in[rd_dat++]; - rsample = in[rd_dat++]; - - out[wr_dat++] = lsample; - out[wr_dat++] = rsample; - } - break; - } - - return outSize; -} -#endif /* !HAVE_LIBSAMPLERATE */ - static void pcm_convert_channels_1_to_2(int16_t *dest, const int16_t *src, unsigned num_frames) @@ -542,11 +386,11 @@ size_t pcm_convert(const struct audio_format *inFormat, assert(dest_size >= len); memcpy(outBuffer, buf, len); } else { - len = pcm_resample(outFormat->channels, - inFormat->sample_rate, buf, len, - outFormat->sample_rate, - (int16_t*)outBuffer, - dest_size, convState); + len = pcm_resample_16(outFormat->channels, + inFormat->sample_rate, buf, len, + outFormat->sample_rate, + (int16_t*)outBuffer, + dest_size, &convState->resample); if (len == 0) exit(EXIT_FAILURE); } |