aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm_utils.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-23 20:00:51 +0200
committerMax Kellermann <max@duempel.org>2008-10-23 20:00:51 +0200
commit6b1c54ef9646abddfbd4960c207b32426300a90c (patch)
tree5b3ae6bf5fc377cf9c705c85948ab5b85e31743c /src/pcm_utils.c
parent098991f8e8a974d2eee39645fa23c43a4c8b06c1 (diff)
downloadmpd-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.c168
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);
}