[Openal-devel] [patch] No more extrapolation
Adam D. Moss
adam at gimp.org
Wed Jun 22 15:04:36 PDT 2005
A long long time ago, one of my patches went into the
SI tree which increased fidelity when stretching an audio
sample's data x2. The downside of this is a slight
crackle at the end of some sample blocks, where we have nothing
to interpolate against so we make an extrapolated guess
instead which turns out to be a bad guess.
Well, I've finally decided that the crackle isn't totally
in my imagination and is actually more annoying than the tinny
sounds of the non-interpolated x2 scaling.
So here's a patch to disable the interpolation by default.
The code remains until I figure out whether it'd be easy
for the caller to tell the scaler what the preceding sample
was so that interpolation can happen properly, though I
fear that's not gonna happen...
This patch is reflected in the AL-0 prebuilt lib at
<http://icculus.org/~aspirin/openal/libopenal.so.0.0.8>
if anyone wants to quickly compare. I'll check it into
the trunk some time if there are no objections.
--adam
--
Adam D. Moss - adam at gimp.org
-------------- next part --------------
Index: ac_freq.c
===================================================================
RCS file: /usr/local/cvs-repository/openal/linux/audioconvert/ac_freq.c,v
retrieving revision 1.6
diff -u -u -r1.6 ac_freq.c
--- ac_freq.c 7 Jan 2004 11:18:56 -0000 1.6
+++ ac_freq.c 22 Jun 2005 21:34:24 -0000
@@ -13,6 +13,11 @@
#include <stdio.h>
+/* defining this option increases fidelity but introduces subtle
+ crackles on sample borders, sadly. */
+#undef EXTRAPOLATE_SAMPLES
+
+
/* Convert rate up by multiple of 2 */
void acFreqMUL2(acAudioCVT *cvt, ALushort format) {
int i;
@@ -27,6 +32,7 @@
ALubyte *dst8 = (ALubyte*) dst;
src8 -= 1;
dst8 -= 2;
+#ifdef EXTRAPOLATE_SAMPLES
/* For the first sample to be processed (last sample
in the buffer) there's no 'next' sample in the
buffer to interpolate against. So we use a value
@@ -52,11 +58,20 @@
dst8[0] = src8[0];
dst8[1] = src8[0];
}
+#else
+ dst8[0] = dst8[1] = src8[0];
+ for ( i=cvt->len_cvt/2-1; i; --i ) {
+ src8 -= 1;
+ dst8 -= 2;
+ dst8[0] = dst8[1] = src8[0];
+ }
+#endif
} else if (format == AUDIO_S8) {
ALbyte *src8 = (ALbyte*) src;
ALbyte *dst8 = (ALbyte*) dst;
src8 -= 1;
dst8 -= 2;
+#ifdef EXTRAPOLATE_SAMPLES
if (cvt->len_cvt >= 2) {
int ex; /* extrapolated sample, damped */
ex = src8[0] + (src8[0]-(int)src8[-1])/8;
@@ -76,6 +91,14 @@
dst8[0] = src8[0];
dst8[1] = src8[0];
}
+#else
+ dst8[0] = dst8[1] = src8[0];
+ for ( i=cvt->len_cvt/2-1; i; --i ) {
+ src8 -= 1;
+ dst8 -= 2;
+ dst8[0] = dst8[1] = src8[0];
+ }
+#endif
}
break;
case 16:
@@ -84,9 +107,10 @@
ALshort *dst16 = (ALshort*) dst;
src16 -= 1;
dst16 -= 2;
+#ifdef EXTRAPOLATE_SAMPLES
if (cvt->len_cvt >= 4) {
int ex; /* extrapolated sample, damped */
- ex = src16[0] + (src16[0]-(int)src16[-1])/8;
+ ex = src16[0] + (src16[0]-(int)src16[-1])*0;
if ( ex > 32767 )
ex = 32767;
else if ( ex < -32768 )
@@ -103,11 +127,20 @@
dst16[0] = src16[0];
dst16[1] = src16[0];
}
+#else
+ dst16[0] = dst16[1] = src16[0];
+ for ( i=cvt->len_cvt/2-1; i; --i ) {
+ src16 -= 1;
+ dst16 -= 2;
+ dst16[0] = dst16[1] = src16[0];
+ }
+#endif
} else if (format == AUDIO_U16) {
ALushort *src16 = (ALushort*) src;
ALushort *dst16 = (ALushort*) dst;
src16 -= 1;
dst16 -= 2;
+#ifdef EXTRAPOLATE_SAMPLES
if (cvt->len_cvt >= 4) {
int ex; /* extrapolated sample, damped */
ex = src16[0] + (src16[0]-(int)src16[-1])/8;
@@ -127,12 +160,17 @@
dst16[0] = src16[0];
dst16[1] = src16[0];
}
+#else
+ dst16[0] = dst16[1] = src16[0];
+ for ( i=cvt->len_cvt/2-1; i; --i ) {
+ src16 -= 1;
+ dst16 -= 2;
+ dst16[0] = dst16[1] = src16[0];
+ }
+#endif
} else {
/* this is a 16-bit format that doesn't correspond
- to a native type, so sample interpolation isn't
- completely trivial; we'll just do sample
- duplication. Not too hard to fix though, for
- future work. */
+ to a native type. */
ALushort *src16 = (ALushort*) src;
ALushort *dst16 = (ALushort*) dst;
for ( i=cvt->len_cvt/2; i; --i ) {
More information about the Openal-devel
mailing list