aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/decoder_api.c26
-rw-r--r--src/output_control.c2
-rw-r--r--src/output_init.c3
-rw-r--r--src/output_internal.h2
-rw-r--r--src/output_thread.c29
-rw-r--r--src/pcm_convert.c56
-rw-r--r--src/pcm_convert.h11
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);