From 356526457c49384d6ff5b652aa0f33dc74d23508 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 17 Jan 2009 13:11:16 +0100 Subject: pcm_convert: return PCM buffer from pcm_convert() Removed yet another superfluous buffer layer: return the PCM buffer from pcm_convert() instead of copying PCM data into the caller-supplied buffer. --- src/decoder_api.c | 26 ++++++------------------ src/output_control.c | 2 -- src/output_init.c | 3 --- src/output_internal.h | 2 -- src/output_thread.c | 29 ++++---------------------- src/pcm_convert.c | 56 +++++++++++++++++++++++++-------------------------- src/pcm_convert.h | 11 +++++----- 7 files changed, 43 insertions(+), 86 deletions(-) diff --git a/src/decoder_api.c b/src/decoder_api.c index 0ddb4ab90..831fb24b2 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -191,9 +191,7 @@ decoder_data(struct decoder *decoder, float data_time, uint16_t bitRate, struct replay_gain_info *replay_gain_info) { - static char *conv_buffer; - static size_t conv_buffer_size; - char *data; + const char *data = _data; assert(dc.state == DECODE_STATE_DECODE); assert(length % audio_format_frame_size(&dc.in_audio_format) == 0); @@ -224,28 +222,16 @@ decoder_data(struct decoder *decoder, return cmd; } - if (audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) { - data = _data; - } else { - size_t out_length = - pcm_convert_size(&dc.in_audio_format, length, - &dc.out_audio_format); - if (out_length > conv_buffer_size) { - g_free(conv_buffer); - conv_buffer = g_malloc(out_length); - conv_buffer_size = out_length; - } - - data = conv_buffer; - length = pcm_convert(&dc.in_audio_format, _data, - length, &dc.out_audio_format, - data, &decoder->conv_state); + if (!audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) { + data = pcm_convert(&decoder->conv_state, + &dc.in_audio_format, data, length, + &dc.out_audio_format, &length); /* under certain circumstances, pcm_convert() may return an empty buffer - this condition should be investigated further, but for now, do this check as a workaround: */ - if (length == 0) + if (data == NULL) return DECODE_COMMAND_NONE; } diff --git a/src/output_control.c b/src/output_control.c index 503001470..db3ab5622 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -142,8 +142,6 @@ void audio_output_finish(struct audio_output *audioOutput) if (audioOutput->plugin->finish) audioOutput->plugin->finish(audioOutput->data); - if (audioOutput->convBuffer) - free(audioOutput->convBuffer); notify_deinit(&audioOutput->notify); } diff --git a/src/output_init.c b/src/output_init.c index 8423e4bbb..bf92cc852 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -90,9 +90,6 @@ int audio_output_init(struct audio_output *ao, ConfigParam * param) ao->open = false; ao->reopen_after = 0; - ao->convBuffer = NULL; - ao->convBufferLen = 0; - pcm_convert_init(&ao->convState); if (format) { diff --git a/src/output_internal.h b/src/output_internal.h index 17209dd5a..dc363a6b9 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -79,8 +79,6 @@ struct audio_output { struct audio_format reqAudioFormat; struct pcm_convert_state convState; - char *convBuffer; - size_t convBufferLen; /** * The thread handle, or NULL if the output thread isn't diff --git a/src/output_thread.c b/src/output_thread.c index 3d5fe57d6..66f66e88c 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -38,29 +38,6 @@ static void ao_command_finished(struct audio_output *ao) notify_signal(&audio_output_client_notify); } -static void convertAudioFormat(struct audio_output *audioOutput, - const char **chunkArgPtr, size_t *sizeArgPtr) -{ - size_t size = pcm_convert_size(&(audioOutput->inAudioFormat), - *sizeArgPtr, - &(audioOutput->outAudioFormat)); - - if (size > audioOutput->convBufferLen) { - if (audioOutput->convBuffer != NULL) - free(audioOutput->convBuffer); - audioOutput->convBuffer = g_malloc(size); - audioOutput->convBufferLen = size; - } - - *sizeArgPtr = pcm_convert(&(audioOutput->inAudioFormat), - *chunkArgPtr, *sizeArgPtr, - &(audioOutput->outAudioFormat), - audioOutput->convBuffer, - &audioOutput->convState); - - *chunkArgPtr = audioOutput->convBuffer; -} - static void ao_play(struct audio_output *ao) { const char *data = ao->args.play.data; @@ -70,13 +47,15 @@ static void ao_play(struct audio_output *ao) assert(size > 0); if (!audio_format_equals(&ao->inAudioFormat, &ao->outAudioFormat)) { - convertAudioFormat(ao, &data, &size); + data = pcm_convert(&ao->convState, + &ao->inAudioFormat, data, size, + &ao->outAudioFormat, &size); /* under certain circumstances, pcm_convert() may return an empty buffer - this condition should be investigated further, but for now, do this check as a workaround: */ - if (size == 0) + if (data == NULL) return; } diff --git a/src/pcm_convert.c b/src/pcm_convert.c index 2209249a6..42d72e367 100644 --- a/src/pcm_convert.c +++ b/src/pcm_convert.c @@ -48,12 +48,12 @@ void pcm_convert_deinit(struct pcm_convert_state *state) pcm_buffer_deinit(&state->channels_buffer); } -static size_t -pcm_convert_16(const struct audio_format *src_format, +static const int16_t * +pcm_convert_16(struct pcm_convert_state *state, + const struct audio_format *src_format, const void *src_buffer, size_t src_size, const struct audio_format *dest_format, - int16_t *dest_buffer, - struct pcm_convert_state *state) + size_t *dest_size_r) { const int16_t *buf; size_t len; @@ -82,18 +82,16 @@ pcm_convert_16(const struct audio_format *src_format, dest_format->sample_rate, &len); - assert(pcm_convert_size(src_format, src_size, dest_format) >= len); - memcpy(dest_buffer, buf, len); - - return len; + *dest_size_r = len; + return buf; } -static size_t -pcm_convert_24(const struct audio_format *src_format, +static const int32_t * +pcm_convert_24(struct pcm_convert_state *state, + const struct audio_format *src_format, const void *src_buffer, size_t src_size, const struct audio_format *dest_format, - int32_t *dest_buffer, - struct pcm_convert_state *state) + size_t *dest_size_r) { const int32_t *buf; size_t len; @@ -121,30 +119,30 @@ pcm_convert_24(const struct audio_format *src_format, dest_format->sample_rate, &len); - assert(pcm_convert_size(src_format, src_size, dest_format) >= len); - memcpy(dest_buffer, buf, len); - - return len; + *dest_size_r = len; + return buf; } -size_t pcm_convert(const struct audio_format *inFormat, - const void *src, size_t src_size, - const struct audio_format *outFormat, - void *dest, - struct pcm_convert_state *convState) +const void * +pcm_convert(struct pcm_convert_state *state, + const struct audio_format *src_format, + const void *src, size_t src_size, + const struct audio_format *dest_format, + size_t *dest_size_r) { - switch (outFormat->bits) { + switch (dest_format->bits) { case 16: - return pcm_convert_16(inFormat, src, src_size, - outFormat, (int16_t*)dest, - convState); + return pcm_convert_16(state, + src_format, src, src_size, + dest_format, dest_size_r); + case 24: - return pcm_convert_24(inFormat, src, src_size, - outFormat, (int32_t*)dest, - convState); + return pcm_convert_24(state, + src_format, src, src_size, + dest_format, dest_size_r); default: - g_error("cannot convert to %u bit\n", outFormat->bits); + g_error("cannot convert to %u bit\n", dest_format->bits); return 0; } } diff --git a/src/pcm_convert.h b/src/pcm_convert.h index 46ee55407..49dc64973 100644 --- a/src/pcm_convert.h +++ b/src/pcm_convert.h @@ -41,11 +41,12 @@ void pcm_convert_init(struct pcm_convert_state *state); void pcm_convert_deinit(struct pcm_convert_state *state); -size_t pcm_convert(const struct audio_format *inFormat, - const void *src, size_t src_size, - const struct audio_format *outFormat, - void *dest, - struct pcm_convert_state *convState); +const void * +pcm_convert(struct pcm_convert_state *state, + const struct audio_format *src_format, + const void *src, size_t src_size, + const struct audio_format *dest_format, + size_t *dest_size_r); size_t pcm_convert_size(const struct audio_format *inFormat, size_t inSize, const struct audio_format *outFormat); -- cgit v1.2.3