[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-multimedia
Subject:    [PATCH] correct resampling
From:       Stefan Westerfeld <stefan () space ! twc ! de>
Date:       2000-08-23 19:44:30
[Download RAW message or body]

Hi!

I think I have found a cure for the following problem reported by Martin:

Playing wav/mp3 files with sampling rates like 32000 Hz, where division
with something like 44100 Hz leads to a number with lots of decimals,
sounds strange.

The following patch to kdelibs/arts should correct this. What it does is
increasing the precision of the "sample positions" from float to double.
Unfortunately, it is *binary incompatible* to the plugins like the mpeglib
plugin, which means that it requires a rebuild of kdemultimedia as well.

However, I see no reasonable alternative, as using "float" for specifying
a sample based position in a wave file >= 2^24 samples (which is approx.
6 minutes of 44100 Hz sampled data) definitely will lead to problems anyway.

Please have a look at it.

   Cu... Stefan
-- 
  -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany
     KDE Developer, project infos at http://space.twc.de/~stefan/kde *-         

["correct-resampling.diff" (text/plain)]

Index: flow/convert.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/flow/convert.cc,v
retrieving revision 1.7
diff -u -r1.7 convert.cc
--- flow/convert.cc	2000/07/17 12:54:59	1.7
+++ flow/convert.cc	2000/08/23 19:24:12
@@ -67,14 +67,14 @@
 	} \
 } \
 void interpolate_mono_ ## from_format ## _ ## to_format (unsigned long samples,\
-									float startpos, float speed, \
+									double startpos, double speed, \
 									datatype_ ## from_format *from, \
                                     datatype_ ## to_format *to) \
 { \
-	float flpos = startpos; \
+	double flpos = startpos; \
 	while(samples) { \
 		long position = ((long)(flpos)) * (datasize_ ## from_format); \
-		float error = flpos - floor(flpos); \
+		double error = flpos - floor(flpos); \
 		*to =	(convert_ ## from_format ## _ ## to_format(from[position])) * \
 				(1.0-error) + (convert_ ## from_format ## _ ## \
 				to_format(from[position + datasize_ ## from_format])) * error; \
@@ -99,15 +99,15 @@
 	} \
 } \
 void interpolate_stereo_i ## from_format ## _2 ## to_format (unsigned long samples,\
-									float startpos, float speed, \
+									double startpos, double speed, \
 									datatype_ ## from_format *from, \
                                     datatype_ ## to_format *left, \
                                     datatype_ ## to_format *right) \
 { \
-	float flpos = startpos; \
+	double flpos = startpos; \
 	while(samples) { \
 		long position = ((long)(flpos)) * (datasize_ ## from_format) * 2; \
-		float error = flpos - floor(flpos); \
+		double error = flpos - floor(flpos); \
 		*left =	(convert_ ## from_format ## _ ## to_format(from[position])) * \
 				(1.0-error) + (convert_ ## from_format ## _ ## \
 				to_format(from[position + 2*datasize_ ## from_format]))*error; \
@@ -215,18 +215,18 @@
 	    unsigned int fromChannels,  // channels stored in the buffer
 		unsigned int fromBits,		// number of bits per sample
 	    float *left, float *right,	// output buffers for left and right channel
-		float speed,				// speed (2.0 means twice as fast)
-		float startposition			// startposition
+		double speed,				// speed (2.0 means twice as fast)
+		double startposition		// startposition
 	)
 {
 	unsigned long doSamples = 0;
 
 	// how many samples does the from-buffer contain?
-	float allSamples = (fromLen*8) / (fromChannels * fromBits);
+	double allSamples = (fromLen*8) / (fromChannels * fromBits);
 
 	// how many samples are remaining?
 	//    subtract one due to interpolation and another against rounding errors
-	float fHaveSamples = allSamples - startposition - 2.0;
+	double fHaveSamples = allSamples - startposition - 2.0;
 	fHaveSamples /= speed;
 
 	// convert do "how many samples to do"?
Index: flow/convert.h
===================================================================
RCS file: /home/kde/kdelibs/arts/flow/convert.h,v
retrieving revision 1.4
diff -u -r1.4 convert.h
--- flow/convert.h	2000/03/26 12:27:42	1.4
+++ flow/convert.h	2000/08/23 19:24:12
@@ -45,28 +45,28 @@
 			unsigned char *from, float *to);
 
 void interpolate_mono_8_float(unsigned long samples,
-		    float startpos, float speed,
+		    double startpos, double speed,
 			unsigned char *from, float *to);
 
 void convert_mono_16le_float(unsigned long samples,
 			unsigned char *from, float *to);
 
 void interpolate_mono_16le_float(unsigned long samples,
-		    float startpos, float speed,
+		    double startpos, double speed,
 			unsigned char *from, float *to);
 
 void convert_stereo_i8_2float(unsigned long samples,
 			unsigned char *from, float *left, float *right);
 
 void interpolate_stereo_i8_2float(unsigned long samples,
-		    float startpos, float speed,
+		    double startpos, double speed,
 			unsigned char *from, float *left, float *right);
 
 void convert_stereo_i16le_2float(unsigned long samples,
 			unsigned char *from, float *left, float *right);
 
 void interpolate_stereo_i16le_2float(unsigned long samples,
-		    float startpos, float speed,
+		    double startpos, double speed,
 			unsigned char *from, float *left, float *right);
 
 // downconversions from float to integer
@@ -90,6 +90,6 @@
 	    unsigned int fromChannels,  // channels stored in the buffer
 		unsigned int fromBits,		// number of bits per sample
 	    float *left, float *right,	// output buffers for left and right channel
-		float speed,				// speed (2.0 means twice as fast)
-		float startposition			// startposition
+		double speed,				// speed (2.0 means twice as fast)
+		double startposition		// startposition
 	);
Index: soundserver/wavplayobject_impl.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/soundserver/wavplayobject_impl.cc,v
retrieving revision 1.11
diff -u -r1.11 wavplayobject_impl.cc
--- soundserver/wavplayobject_impl.cc	2000/08/13 12:12:03	1.11
+++ soundserver/wavplayobject_impl.cc	2000/08/23 19:24:14
@@ -15,7 +15,7 @@
 class WavPlayObject_impl :public WavPlayObject_skel, public StdSynthModule {
 protected:
 	CachedWav *wav;
-	float flpos;
+	double flpos;
 	poState _state;
 
 	int sampleCount()
@@ -137,13 +137,13 @@
 
 		if(wav && _state == posPlaying)
 		{
-			float speed = wav->samplingRate / samplingRateFloat;
+			double speed = wav->samplingRate / samplingRateFloat;
 
 			haveSamples = uni_convert_stereo_2float(samples, wav->buffer,
 		   		wav->bufferSize,wav->channelCount,wav->sampleWidth,
 		   		left,right,speed,flpos);
 
-			flpos += (float)haveSamples * speed;
+			flpos += (double)haveSamples * speed;
 		}
 
 		if(haveSamples != samples)

_______________________________________________
Kde-multimedia mailing list
Kde-multimedia@master.kde.org
http://master.kde.org/mailman/listinfo/kde-multimedia


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic