From 872af2077706da859b5a64c2e06bfd06de80387b Mon Sep 17 00:00:00 2001
From: Warren Dukes <warren.dukes@gmail.com>
Date: Mon, 10 May 2004 15:21:40 +0000
Subject: [PATCH] resampling code blatantly ripped from xmms, needs testing and
 need to right conversion routines for bit conversion and channel conversion

git-svn-id: https://svn.musicpd.org/mpd/trunk@971 09075e82-0dd4-0310-85a5-a0d7c8717e4f
---
 src/audio.c     |  4 ++--
 src/pcm_utils.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/audio.c b/src/audio.c
index de5296f2e..5de64b447 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -159,7 +159,7 @@ void initAudioConfig() {
                 exit(EXIT_FAILURE);
         }
 
-        audio_configFormat->bits = strtol(test,&test,10);
+        audio_configFormat->bits = strtol(test+1,&test,10);
         
         if(*test!=':') {
                 ERROR("error parsing audio output format: %s\n",conf);
@@ -175,7 +175,7 @@ void initAudioConfig() {
                 exit(EXIT_FAILURE);
         }
 
-        audio_configFormat->channels = strtol(test,&test,10);
+        audio_configFormat->channels = strtol(test+1,&test,10);
         
         if(*test!='\0') {
                 ERROR("error parsing audio output format: %s\n",conf);
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index 741cb3d7b..8ef431841 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -24,6 +24,7 @@
 
 #include <string.h>
 #include <math.h>
+#include <assert.h>
 
 void pcm_changeBufferEndianness(char * buffer, int bufferSize, int bits) {
 	char temp;
@@ -140,7 +141,47 @@ void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1,
 void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
                 inSize, AudioFormat * outFormat, char * outBuffer)
 {
-	abort();
+	/*int inSampleSize = inFormat->bits*inFormat->channels/8;
+	int outSampleSize = outFormat->bits*outFormat->channels/8;*/
+
+	assert(inFormat->bits==16);
+	assert(outFormat->bits==16);
+	assert(inFormat->channels==2);
+	assert(outFormat->channels==2);
+
+	if(inFormat->sampleRate == outFormat->sampleRate) return;
+
+	/* only works if outFormat is 16-bit stereo! */
+	/* resampling code blatantly ripped from XMMS */
+	{
+		const int shift = sizeof(mpd_sint16);
+		mpd_sint32 i, in_samples, out_samples, x, delta;
+		mpd_sint16 * inptr = (mpd_sint16 *)inBuffer;
+		mpd_sint16 * outptr = (mpd_sint16 *)outBuffer;
+		mpd_uint32 nlen = (((inSize >> shift) * 
+				(mpd_uint32)(outFormat->sampleRate)) / 
+				inFormat->sampleRate);
+		nlen <<= shift;
+		in_samples = inSize >> shift;
+		out_samples = nlen >> shift;
+		delta = (in_samples << 12) / out_samples;
+		for(x = 0, i = 0; i < out_samples; i++) {
+			int x1, frac;
+			x1 = (x >> 12) << 12;
+			frac = x - x1;
+			*outptr++ = 
+				((inptr[(x1 >> 12) << 1] * 
+				((1<<12) - frac) +
+				inptr[((x1 >> 12) + 1) << 1 ] *
+				frac) >> 12);
+			*outptr++ =
+				((inptr[((x1 >> 12) << 1) + 1] *
+				((1<<12) - frac) +
+				inptr[(((x1 >> 12) + 1) << 1) + 1] *
+				frac) >> 12);
+			x += delta;
+		}
+	}
 
 	return;
 }
@@ -148,9 +189,20 @@ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
 size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
 		char * inBuffer, size_t inSize, AudioFormat * outFormat)
 {
-	abort();
+	const int shift = sizeof(mpd_sint16);
+	mpd_uint32 nlen = (((inSize >> shift) * 
+				(mpd_uint32)(outFormat->sampleRate)) / 
+				inFormat->sampleRate);
 
-	return 0;
+	nlen <<= shift;
+
+
+	assert(inFormat->bits==16);
+	assert(outFormat->bits==16);
+	assert(inFormat->channels==2);
+	assert(outFormat->channels==2);
+
+	return nlen;
 }
 
 /* vim:set shiftwidth=8 tabstop=8 expandtab: */