aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm_utils.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-12 11:51:19 +0200
committerMax Kellermann <max@duempel.org>2008-10-12 11:51:19 +0200
commit52949453dfbe685d38df6f7992f6fc38d3a20088 (patch)
treed8612f6d37efd0f1dc4a594f9fd28c805dd307a6 /src/pcm_utils.c
parenta7924d141dd51a7715307fea5e191f1c5a38f092 (diff)
downloadmpd-52949453dfbe685d38df6f7992f6fc38d3a20088.tar.gz
mpd-52949453dfbe685d38df6f7992f6fc38d3a20088.tar.xz
mpd-52949453dfbe685d38df6f7992f6fc38d3a20088.zip
pcm_utils: pass output channel count to pcm_convertChannels()
In order to be able to deal with non-trivial conversions, pcm_convertChannels() needs to know both the input and the output channel count. Simplify buffer allocation in that function.
Diffstat (limited to 'src/pcm_utils.c')
-rw-r--r--src/pcm_utils.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index 9dfcbd1e6..52f9294b7 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -386,47 +386,33 @@ pcm_convert_channels_2_to_1(int16_t *dest, const int16_t *src,
}
static const int16_t *
-pcm_convertChannels(int8_t channels, const int16_t *inBuffer,
- size_t inSize, size_t *outSize)
+pcm_convertChannels(int8_t dest_channels,
+ int8_t src_channels, const int16_t *src,
+ size_t src_size, size_t *dest_size_r)
{
static int16_t *buf;
static size_t len;
- int16_t *outBuffer = NULL;
+ unsigned num_frames = src_size / src_channels / sizeof(*src);
+ unsigned dest_size = num_frames * dest_channels * sizeof(*src);
- switch (channels) {
- /* convert from 1 -> 2 channels */
- case 1:
- *outSize = (inSize >> 1) << 2;
- if (*outSize > len) {
- len = *outSize;
- buf = xrealloc(buf, len);
- }
-
- outBuffer = buf;
- pcm_convert_channels_1_to_2((int16_t *)buf,
- (const int16_t *)inBuffer,
- inSize >> 1);
- break;
-
- /* convert from 2 -> 1 channels */
- case 2:
- *outSize = inSize >> 1;
- if (*outSize > len) {
- len = *outSize;
- buf = xrealloc(buf, len);
- }
- outBuffer = buf;
+ if (dest_size > len) {
+ len = dest_size;
+ buf = xrealloc(buf, len);
+ }
- pcm_convert_channels_2_to_1((int16_t *)buf,
- (const int16_t *)inBuffer,
- inSize >> 2);
- break;
+ *dest_size_r = dest_size;
- default:
- ERROR("only 1 or 2 channels are supported for conversion!\n");
+ if (src_channels == 1 && dest_channels == 2)
+ pcm_convert_channels_1_to_2(buf, src, num_frames);
+ else if (src_channels == 2 && dest_channels == 1)
+ pcm_convert_channels_2_to_1(buf, src, num_frames);
+ else {
+ ERROR("conversion %u->%u channels is not supported\n",
+ src_channels, dest_channels);
+ return NULL;
}
- return outBuffer;
+ return buf;
}
static void
@@ -504,7 +490,6 @@ size_t pcm_convertAudioFormat(const struct audio_format *inFormat,
size_t outSize = pcm_sizeOfConvBuffer(inFormat, inSize, outFormat);
assert(outFormat->bits == 16);
- assert(outFormat->channels == 2 || outFormat->channels == 1);
/* everything else supports 16 bit only, so convert to that first */
buf = pcm_convertTo16bit(inFormat->bits, inBuffer, inSize, &len);
@@ -512,7 +497,9 @@ size_t pcm_convertAudioFormat(const struct audio_format *inFormat,
exit(EXIT_FAILURE);
if (inFormat->channels != outFormat->channels) {
- buf = pcm_convertChannels(inFormat->channels, buf, len, &len);
+ buf = pcm_convertChannels(outFormat->channels,
+ inFormat->channels,
+ buf, len, &len);
if (!buf)
exit(EXIT_FAILURE);
}