aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm_utils.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-12 11:47:42 +0200
committerMax Kellermann <max@duempel.org>2008-10-12 11:47:42 +0200
commita7924d141dd51a7715307fea5e191f1c5a38f092 (patch)
treefb0c57db8219a3ba3cfea28d24db7c2c1bc0974b /src/pcm_utils.c
parent1a74d7be4143c8afb51cd2c2a338ac165866d047 (diff)
downloadmpd-a7924d141dd51a7715307fea5e191f1c5a38f092.tar.gz
mpd-a7924d141dd51a7715307fea5e191f1c5a38f092.tar.xz
mpd-a7924d141dd51a7715307fea5e191f1c5a38f092.zip
pcm_utils: moved code from pcm_convertChannels() to separate functions
Moved code from pcm_convertChannels() to pcm_convert_channels_1_to_2() and pcm_convert_channels_2_to_1(). Improved the quality of pcm_convert_channels_2_to_1() by calculating the arithmetic mean value of both samples.
Diffstat (limited to '')
-rw-r--r--src/pcm_utils.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index f128c3123..9dfcbd1e6 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -362,6 +362,29 @@ static size_t pcm_convertSampleRate(int8_t channels, uint32_t inSampleRate,
}
#endif /* !HAVE_LIBSAMPLERATE */
+static void
+pcm_convert_channels_1_to_2(int16_t *dest, const int16_t *src,
+ unsigned num_frames)
+{
+ while (num_frames-- > 0) {
+ int16_t value = *src++;
+
+ *dest++ = value;
+ *dest++ = value;
+ }
+}
+
+static void
+pcm_convert_channels_2_to_1(int16_t *dest, const int16_t *src,
+ unsigned num_frames)
+{
+ while (num_frames-- > 0) {
+ int32_t a = *src++, b = *src++;
+
+ *dest++ = (a + b) / 2;
+ }
+}
+
static const int16_t *
pcm_convertChannels(int8_t channels, const int16_t *inBuffer,
size_t inSize, size_t *outSize)
@@ -369,9 +392,6 @@ pcm_convertChannels(int8_t channels, const int16_t *inBuffer,
static int16_t *buf;
static size_t len;
int16_t *outBuffer = NULL;
- const int16_t *in;
- int16_t *out;
- int inSamples, i;
switch (channels) {
/* convert from 1 -> 2 channels */
@@ -381,17 +401,13 @@ pcm_convertChannels(int8_t channels, const int16_t *inBuffer,
len = *outSize;
buf = xrealloc(buf, len);
}
- outBuffer = buf;
-
- inSamples = inSize >> 1;
- in = (const int16_t *)inBuffer;
- out = (int16_t *)outBuffer;
- for (i = 0; i < inSamples; i++) {
- *out++ = *in;
- *out++ = *in++;
- }
+ 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;
@@ -401,15 +417,11 @@ pcm_convertChannels(int8_t channels, const int16_t *inBuffer,
}
outBuffer = buf;
- inSamples = inSize >> 2;
- in = (const int16_t *)inBuffer;
- out = (int16_t *)outBuffer;
- for (i = 0; i < inSamples; i++) {
- *out = (*in++) / 2;
- *out++ += (*in++) / 2;
- }
-
+ pcm_convert_channels_2_to_1((int16_t *)buf,
+ (const int16_t *)inBuffer,
+ inSize >> 2);
break;
+
default:
ERROR("only 1 or 2 channels are supported for conversion!\n");
}