changeset 2662:5470680ca587 gsoc2008_audio_resampling

Made a very significant optimization to the FIR filter which I believe I can take a little further. Right now the FIR filter size is 768 and I get some free() bugs, so this is something I need to debug.
author Aaron Wishnick <schnarf@gmail.com>
date Thu, 10 Jul 2008 07:02:18 +0000
parents d38309be5178
children 0caed045d01b
files src/audio/SDL_audiocvt.c
diffstat 1 files changed, 13 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/audio/SDL_audiocvt.c	Wed Jul 02 08:04:50 2008 +0000
+++ b/src/audio/SDL_audiocvt.c	Thu Jul 10 07:02:18 2008 +0000
@@ -1536,6 +1536,7 @@
 	   significantly fewer multiplications and additions. However, this
 	   depends on the zero stuffing ratio, so it may not pay off.
 	*/
+	/* We only calculate the values of samples which are 0 (mod len_div) because those are the only ones used */
 #define filter_sinc(type, mult) { \
 			type *sinc = (type *)cvt->coeff; \
 			type *state = (type *)cvt->state_buf; \
@@ -1543,9 +1544,11 @@
 			for(i = 0; i < n; ++i) { \
 				state[cvt->state_pos] = buf[i]; \
 				buf[i] = 0; \
-				for(j = 0; j < m;  ++j) { \
-					buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
-				} \
+				if( i % cvt->len_div == 0 ) { \
+					for(j = 0; j < m;  ++j) { \
+						buf[i] += mult(sinc[j], state[(cvt->state_pos + j) % m]); \
+					} \
+				}\
 				cvt->state_pos = (cvt->state_pos + 1) % m; \
 			} \
 		}
@@ -1616,7 +1619,6 @@
 #ifdef DEBUG_CONVERT
 	printf("Lowpass cutoff frequency = %f\n", fc);
 #endif
-//	fc = 0.02f;
 	two_pi_fc = 2.0f * M_PI * fc;
 	two_pi_over_m = 2.0f * M_PI / (float)m;
 	four_pi_over_m = 2.0f * two_pi_over_m;
@@ -1635,7 +1637,7 @@
 	}
 		
 #define convert_fixed(type, fix) { \
-		norm_fact = 0.7f / norm_sum; \
+		norm_fact = 0.5f / norm_sum; \
 		type *dst = (type *)cvt->coeff; \
 		for( i = 0; i <= m; ++i ) { \
 			dst[i] = fix(fSinc[i] * norm_fact); \
@@ -1709,7 +1711,7 @@
 #define discard_mono(type) { \
         const type *src = (const type *) (cvt->buf); \
         type *dst = (type *) (cvt->buf); \
-        for (i = 0; i < cvt->len_cvt / cvt->len_div / sizeof (type); ++i) { \
+        for (i = 0; i < (cvt->len_cvt / sizeof(type)) / cvt->len_div; ++i) { \
             dst[0] = src[0]; \
             src += cvt->len_div; \
             ++dst; \
@@ -1735,9 +1737,12 @@
 	cvt->len_cvt *= cvt->len_mult;
 
 	// Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies
-	SDL_FilterFIR( cvt, format );
+	QSDL_FilterFIR( cvt, format );
+	
+	// OPTIMIZATION: we only need to calculate the non-discarded samples. This could be a big speedup!
 	
 	// Step 3: Discard unnecessary samples
+
 #ifdef DEBUG_CONVERT
 	printf("Discarding samples by a factor of %u\n", cvt->len_div);
 #endif
@@ -1859,7 +1864,7 @@
 	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
 	cvt->filters[cvt->filter_index++] = SDL_Resample;
 	//SDL_BuildIIRLowpass(cvt, dst_fmt);
-	SDL_BuildWindowedSinc(cvt, dst_fmt, 20);
+	SDL_BuildWindowedSinc(cvt, dst_fmt, 768);
 	
     /*cvt->rate_incr = 0.0;
     if ((src_rate / 100) != (dst_rate / 100)) {