[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