src/audio/SDL_audiocvt.c
branchgsoc2008_audio_resampling
changeset 2659 8da698bc1205
parent 2658 de29a03cb108
child 2660 a55543cef395
     1.1 --- a/src/audio/SDL_audiocvt.c	Thu Jun 19 20:11:06 2008 +0000
     1.2 +++ b/src/audio/SDL_audiocvt.c	Sun Jun 22 00:36:35 2008 +0000
     1.3 @@ -54,12 +54,12 @@
     1.4  #define SDL_FixMpy16(a, b) ((((Sint32)a * (Sint32)b) >> 14) & 0xffff)
     1.5  #define SDL_FixMpy8(a, b) ((((Sint16)a * (Sint16)b) >> 7) & 0xff)
     1.6  /* Everything is signed! */
     1.7 -#define SDL_Make_1_7(a) (Sint8)(a * 128.0f)
     1.8 -#define SDL_Make_1_15(a) (Sint16)(a * 32768.0f)
     1.9 -#define SDL_Make_1_31(a) (Sint32)(a * 2147483648.0f)
    1.10 -#define SDL_Make_2_6(a) (Sint8)(a * 64.0f)
    1.11 -#define SDL_Make_2_14(a) (Sint16)(a * 16384.0f)
    1.12 -#define SDL_Make_2_30(a) (Sint32)(a * 1073741824.0f)
    1.13 +#define SDL_Make_1_7(a) (Sint8)(a * 127.0f)
    1.14 +#define SDL_Make_1_15(a) (Sint16)(a * 32767.0f)
    1.15 +#define SDL_Make_1_31(a) (Sint32)(a * 2147483647.0f)
    1.16 +#define SDL_Make_2_6(a) (Sint8)(a * 63.0f)
    1.17 +#define SDL_Make_2_14(a) (Sint16)(a * 16383.0f)
    1.18 +#define SDL_Make_2_30(a) (Sint32)(a * 1073741823.0f)
    1.19  
    1.20  /* Effectively mix right and left channels into a single channel */
    1.21  static void SDLCALL
    1.22 @@ -1526,10 +1526,10 @@
    1.23  
    1.24  /* Apply the windowed sinc FIR filter to the given SDL_AudioCVT struct */
    1.25  static void SDL_FilterFIR(SDL_AudioCVT * cvt, SDL_AudioFormat format) {
    1.26 -	int n = cvt->len_cvt / (SDL_AUDIO_BITSIZE(format) / 4);
    1.27 +	int n = 8 * cvt->len_cvt / SDL_AUDIO_BITSIZE(format);
    1.28  	int m = cvt->len_sinc;
    1.29  	int i, j;
    1.30 -	
    1.31 +				
    1.32  	/* Note: this makes use of the symmetry of the sinc filter.
    1.33  	   We can also make a big optimization here by taking advantage
    1.34  	   of the fact that the signal is zero stuffed, so we can do
    1.35 @@ -1540,10 +1540,12 @@
    1.36  			type *state = (type *)cvt->state_buf; \
    1.37  			type *buf = (type *)cvt->buf; \
    1.38  			for(i = 0; i < n; ++i) { \
    1.39 -				if(cvt->state_pos == m) cvt->state_pos = 0; \
    1.40 +				cvt->state_pos++; \
    1.41 +				if(cvt->state_pos >= m) cvt->state_pos = 0; \
    1.42 +				state[cvt->state_pos] = buf[i]; \
    1.43  				buf[i] = 0; \
    1.44  				for(j = 0; j < m;  ++j) { \
    1.45 -					buf[i] += mult(state[j], sinc[j]); \
    1.46 +					buf[i] += mult(state[(cvt->state_pos - j) % m], sinc[j]); \
    1.47  				} \
    1.48  			} \
    1.49  		}
    1.50 @@ -1601,7 +1603,7 @@
    1.51  	}
    1.52  
    1.53  	/* Set the length */
    1.54 -	cvt->len_sinc = m;
    1.55 +	cvt->len_sinc = m + 1;
    1.56  	
    1.57  	/* Allocate the floating point windowed sinc. */
    1.58  	fSinc = (float *)malloc(m * sizeof(float));
    1.59 @@ -1611,6 +1613,7 @@
    1.60  	
    1.61  	/* Set up the filter parameters */
    1.62  	fc = (cvt->len_mult > cvt->len_div) ? 0.5f / (float)cvt->len_mult : 0.5f / (float)cvt->len_div;
    1.63 +	fc = 0.04f;
    1.64  	two_pi_fc = 2.0f * M_PI * fc;
    1.65  	two_pi_over_m = 2.0f * M_PI / (float)m;
    1.66  	four_pi_over_m = 2.0f * two_pi_over_m;
    1.67 @@ -1626,16 +1629,19 @@
    1.68  			fSinc[i] *= 0.42f - 0.5f * cosf(two_pi_over_m * (float)i) + 0.08f * cosf(four_pi_over_m * (float)i);
    1.69  		}
    1.70  		norm_sum += abs(fSinc[i]);
    1.71 +		printf("%f\n", fSinc[i]);
    1.72  	}
    1.73  
    1.74  	/* Now normalize and convert to fixed point. We scale everything to half the precision
    1.75  	   of whatever datatype we're using, for example, 16 bit data means we use 8 bits */
    1.76  	
    1.77  #define convert_fixed(type, fix) { \
    1.78 -		norm_fact = 1.0f / norm_sum; \
    1.79 +		norm_fact = 0.9f / norm_sum; \
    1.80 +		norm_fact = 0.15f; \
    1.81  		type *dst = (type *)cvt->coeff; \
    1.82  		for( i = 0; i <= m; ++i ) { \
    1.83  			dst[i] = fix(fSinc[i] * norm_fact); \
    1.84 +			printf("%f = 0x%x\n", fSinc[i], dst[i]); \
    1.85  		} \
    1.86  	}
    1.87  	
    1.88 @@ -1661,7 +1667,7 @@
    1.89  	}
    1.90  	
    1.91  	/* Initialize the state buffer to all zeroes, and set initial position */
    1.92 -	memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
    1.93 +	//memset(cvt->state_buf, 0, cvt->len_sinc * SDL_AUDIO_BITSIZE(format) / 4);
    1.94  	cvt->state_pos = 0;
    1.95  	
    1.96  	/* Clean up */
    1.97 @@ -1732,7 +1738,7 @@
    1.98  	cvt->len_cvt *= cvt->len_mult;
    1.99  
   1.100  	// Step 2: Use either a windowed sinc FIR filter or IIR lowpass filter to remove all alias frequencies
   1.101 -	SDL_FilterIIR( cvt, format );
   1.102 +	SDL_FilterFIR( cvt, format );
   1.103  	
   1.104  	// Step 3: Discard unnecessary samples
   1.105  #ifdef DEBUG_CONVERT
   1.106 @@ -1855,7 +1861,8 @@
   1.107  	cvt->len_div = src_rate / rate_gcd;
   1.108  	cvt->len_ratio = (double)cvt->len_mult / (double)cvt->len_div;
   1.109  	cvt->filters[cvt->filter_index++] = SDL_Resample;
   1.110 -	SDL_BuildIIRLowpass(cvt, dst_fmt);
   1.111 +	//SDL_BuildIIRLowpass(cvt, dst_fmt);
   1.112 +	SDL_BuildWindowedSinc(cvt, dst_fmt, 12);
   1.113  	
   1.114      /*cvt->rate_incr = 0.0;
   1.115      if ((src_rate / 100) != (dst_rate / 100)) {