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.
This commit is contained in:
Max Kellermann 2009-01-17 13:11:16 +01:00
parent e726e2a004
commit 356526457c
7 changed files with 43 additions and 86 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);