tags 311343 + upstream
tags 311343 + patch
thanks

Attached is a patch that shows how to add libsamplerate support to mpd.
I've left it as an exercise for the reader to change configure.ac to
properly detect libsamplerate presence and to add to link with it.  One
would probably also want to make the conversion quality configurable,
because the best quality mode uses a lot of CPU power.

-- 
Met vriendelijke groet / with kind regards,
      Guus Sliepen <[EMAIL PROTECTED]>
diff -urN mpd-0.12.1/src/pcm_utils.c mpd-0.12.1.libsamplerate/src/pcm_utils.c
--- mpd-0.12.1/src/pcm_utils.c	2006-10-11 01:56:58.000000000 +0200
+++ mpd-0.12.1.libsamplerate/src/pcm_utils.c	2007-01-13 13:16:47.286900500 +0100
@@ -26,6 +26,10 @@
 #include <math.h>
 #include <assert.h>
 
+#ifdef HAVE_LIBSAMPLERATE
+#include <samplerate.h>
+#endif
+
 void pcm_volumeChange(char *buffer, int bufferSize, AudioFormat * format,
 		      int volume)
 {
@@ -234,6 +238,43 @@
 	if (inFormat->sampleRate == outFormat->sampleRate) {
 		memcpy(outBuffer, dataChannelConv, dataChannelLen);
 	} else {
+#ifdef HAVE_LIBSAMPLERATE
+		static SRC_STATE *state = NULL;
+		static SRC_DATA data;
+		int error;
+		static double ratio = 0;
+		double newratio;
+
+		if(!state) {
+			state = src_new(SRC_SINC_BEST_QUALITY, outFormat->channels, &error);
+			if(!state) {
+				ERROR("Cannot initialise libsamplerate: %s\n", src_strerror(error));
+				exit(EXIT_FAILURE);
+			}
+		}
+
+		newratio = (double)outFormat->sampleRate / (double)inFormat->sampleRate;
+		if(newratio != ratio)
+			src_set_ratio(state, ratio = newratio);
+
+		data.src_ratio = ratio;
+		data.input_frames = dataChannelLen / 2 / outFormat->channels;
+		data.output_frames = data.input_frames * data.src_ratio;
+
+		float conversionInBuffer[data.input_frames * outFormat->channels];
+		float conversionOutBuffer[data.output_frames * outFormat->channels];
+		data.data_in = conversionInBuffer;
+		data.data_out = conversionOutBuffer;
+
+		src_short_to_float_array((short *)dataChannelConv, data.data_in, data.input_frames * outFormat->channels);
+		error = src_process(state, &data);
+		if(error) {
+			ERROR("Error while converting samplerate: %s\n", src_strerror(error));
+			exit(EXIT_FAILURE);
+		}
+
+		src_float_to_short_array(data.data_out, (short *)outBuffer, data.output_frames * outFormat->channels);
+#else
 		/* only works if outFormat is 16-bit stereo! */
 		/* resampling code blatantly ripped from ESD */
 		mpd_uint32 rd_dat = 0;
@@ -272,6 +313,7 @@
 			}
 			break;
 		}
+#endif
 	}
 
 	return;

Attachment: signature.asc
Description: Digital signature

Reply via email to