[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