fix bugs in interpolating resampler :
* I got the downsampling version completely wrong. It should now be much better. * A small bug in the delta calculation sometimes caused an off-by-one read to the source and a crash of the media add-on server Effect of this resampler can be heard very clearly using the following setup in Cortex : * Demo Audio producer producing a sinewave at any frequency (sampling rate is hardcoded at 44100Hz) * Audio output set to 48000 Hz * system mixer in between select either resampler in the mixer and you'll hear the difference immediately. Should finally fix #1351. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42435 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4ee20b83b4
commit
61215fd53d
@ -44,32 +44,19 @@ Interpolate::float_to_float(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#define SRC(n) *(const float*)(src + n * srcSampleOffset)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
*(float*)dest = gain
|
||||
* (SRC(0) + (SRC((int)skipcount) - SRC(0)) * offset);
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,33 +82,20 @@ Interpolate::int32_to_float(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#undef SRC
|
||||
#define SRC(n) *(const int32*)(src + n * srcSampleOffset)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
*(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - SRC(0))
|
||||
* offset);
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,33 +121,20 @@ Interpolate::int16_to_float(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#undef SRC
|
||||
#define SRC(n) *(const int16*)(src + n * srcSampleOffset)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
*(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - SRC(0))
|
||||
* offset);
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,33 +160,20 @@ Interpolate::int8_to_float(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#undef SRC
|
||||
#define SRC(n) *(const int8*)(src + n * srcSampleOffset)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
*(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - SRC(0))
|
||||
* offset);
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,33 +199,20 @@ Interpolate::uint8_to_float(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#undef SRC
|
||||
#define SRC(n) ( *(const uint8*)(src + n * srcSampleOffset) - 128)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
*(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - SRC(0))
|
||||
* offset);
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
*(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,46 +244,27 @@ Interpolate::float_to_int32(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
#undef SRC
|
||||
#define SRC(n) *(const float*)(src + n * srcSampleOffset)
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 2147483647.0f)
|
||||
*(int32 *)dest = 2147483647L;
|
||||
else if (sample < -2147483647.0f)
|
||||
*(int32 *)dest = -2147483647L;
|
||||
else
|
||||
*(int32 *)dest = (int32)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
register float sample = gain * (SRC(0) + (SRC((int)skipcount)
|
||||
- SRC(0)) * offset);
|
||||
if (sample > 2147483647.0f)
|
||||
*(int32 *)dest = 2147483647L;
|
||||
else if (sample < -2147483647.0f)
|
||||
*(int32 *)dest = -2147483647L;
|
||||
else
|
||||
*(int32 *)dest = (int32)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 2147483647.0f)
|
||||
*(int32 *)dest = 2147483647L;
|
||||
else if (sample < -2147483647.0f)
|
||||
*(int32 *)dest = -2147483647L;
|
||||
else
|
||||
*(int32 *)dest = (int32)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,43 +296,24 @@ Interpolate::float_to_int16(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 32767.0f)
|
||||
*(int16 *)dest = 32767;
|
||||
else if (sample < -32767.0f)
|
||||
*(int16 *)dest = -32767;
|
||||
else
|
||||
*(int16 *)dest = (int16)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
register float sample = gain * (SRC(0) + (SRC((int)skipcount)
|
||||
- SRC(0)) * offset);
|
||||
if (sample > 32767.0f)
|
||||
*(int16 *)dest = 32767;
|
||||
else if (sample < -32767.0f)
|
||||
*(int16 *)dest = -32767;
|
||||
else
|
||||
*(int16 *)dest = (int16)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 32767.0f)
|
||||
*(int16 *)dest = 32767;
|
||||
else if (sample < -32767.0f)
|
||||
*(int16 *)dest = -32767;
|
||||
else
|
||||
*(int16 *)dest = (int16)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,43 +345,24 @@ Interpolate::float_to_int8(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 127.0f)
|
||||
*(int8 *)dest = 127;
|
||||
else if (sample < -127.0f)
|
||||
*(int8 *)dest = -127;
|
||||
else
|
||||
*(int8 *)dest = (int8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
register float sample = gain * (SRC(0) + (SRC((int)skipcount)
|
||||
- SRC(0)) * offset);
|
||||
if (sample > 127.0f)
|
||||
*(int8 *)dest = 127;
|
||||
else if (sample < -127.0f)
|
||||
*(int8 *)dest = -127;
|
||||
else
|
||||
*(int8 *)dest = (int8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 127.0f)
|
||||
*(int8 *)dest = 127;
|
||||
else if (sample < -127.0f)
|
||||
*(int8 *)dest = -127;
|
||||
else
|
||||
*(int8 *)dest = (int8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -516,43 +394,24 @@ Interpolate::float_to_uint8(const void *_src, int32 srcSampleOffset,
|
||||
return;
|
||||
}
|
||||
|
||||
register float delta = float(srcSampleCount) / float(destSampleCount);
|
||||
register float delta = float(srcSampleCount - 1) / float(destSampleCount - 1);
|
||||
register float current = 0.0f;
|
||||
|
||||
if (delta < 1.0) {
|
||||
// upsample
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 255.0f)
|
||||
*(uint8 *)dest = 255;
|
||||
else if (sample < 1.0f)
|
||||
*(uint8 *)dest = 1;
|
||||
else
|
||||
*(uint8 *)dest = (uint8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
current -= 1.0f;
|
||||
src += srcSampleOffset;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// downsample
|
||||
while (count--) {
|
||||
double skipcount;
|
||||
register float offset = modf(current, &skipcount);
|
||||
register float sample = gain * (SRC(0) + (SRC((int)skipcount)
|
||||
- SRC(0)) * offset) + 128.0f;
|
||||
if (sample > 255.0f)
|
||||
*(uint8 *)dest = 255;
|
||||
else if (sample < 1.0f)
|
||||
*(uint8 *)dest = 1;
|
||||
else
|
||||
*(uint8 *)dest = (uint8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta - skipcount;
|
||||
src += (int)skipcount * srcSampleOffset;
|
||||
while (count--) {
|
||||
register float sample = gain * (SRC(0) + (SRC(1) - SRC(0))
|
||||
* current);
|
||||
if (sample > 255.0f)
|
||||
*(uint8 *)dest = 255;
|
||||
else if (sample < 1.0f)
|
||||
*(uint8 *)dest = 1;
|
||||
else
|
||||
*(uint8 *)dest = (uint8)sample;
|
||||
dest += destSampleOffset;
|
||||
current += delta;
|
||||
if (current >= 1.0f) {
|
||||
double ipart;
|
||||
current = modf(current, &ipart);
|
||||
src += srcSampleOffset * (int)ipart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user