void firdes_lowpass_f(float *output, int length, float cutoff_rate, window_t window) { //Generates symmetric windowed sinc FIR filter real taps // length should be odd // cutoff_rate is (cutoff frequency/sampling frequency) //Explanation at Chapter 16 of dspguide.com int middle=length/2; float temp; float (*window_function)(float) = firdes_get_window_kernel(window); output[middle]=2*PI*cutoff_rate*window_function(0); for(int i=1; i<=middle; i++) //@@firdes_lowpass_f: calculate taps { output[middle-i]=output[middle+i]=(sin(2*PI*cutoff_rate*i)/i)*window_function((float)i/middle); //printf("%g %d %d %d %d | %g\n",output[middle-i],i,middle,middle+i,middle-i,sin(2*PI*cutoff_rate*i)); } //Normalize filter kernel float sum=0; for(int i=0;i<length;i++) //@firdes_lowpass_f: normalize pass 1 { sum+=output[i]; } for(int i=0;i<length;i++) //@firdes_lowpass_f: normalize pass 2 { output[i]/=sum; } }
static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff, float *phase_table, int phases, int taps, bool calculate_delta) { int i, j; double window_mod = window_function(0.0); /* Need to normalize w(0) to 1.0. */ int stride = calculate_delta ? 2 : 1; double sidelobes = taps / 2.0; for (i = 0; i < phases; i++) { for (j = 0; j < taps; j++) { double sinc_phase; float val; int n = j * phases + i; double window_phase = (double)n / (phases * taps); /* [0, 1). */ window_phase = 2.0 * window_phase - 1.0; /* [-1, 1) */ sinc_phase = sidelobes * window_phase; val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; phase_table[i * stride * taps + j] = val; } } if (calculate_delta) { int phase; int p; for (p = 0; p < phases - 1; p++) { for (j = 0; j < taps; j++) { float delta = phase_table[(p + 1) * stride * taps + j] - phase_table[p * stride * taps + j]; phase_table[(p * stride + 1) * taps + j] = delta; } } phase = phases - 1; for (j = 0; j < taps; j++) { float val, delta; double sinc_phase; int n = j * phases + (phase + 1); double window_phase = (double)n / (phases * taps); /* (0, 1]. */ window_phase = 2.0 * window_phase - 1.0; /* (-1, 1] */ sinc_phase = sidelobes * window_phase; val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; delta = (val - phase_table[phase * stride * taps + j]); phase_table[(phase * stride + 1) * taps + j] = delta; } } }
void apply_window_c(complexf* input, complexf* output, int size, window_t window) { float (*window_function)(float)=firdes_get_window_kernel(window); for(int i=0;i<size;i++) //@apply_window_c { float rate=(float)i/(size-1); iof(output,i)=iof(input,i)*window_function(2.0*rate+1.0); qof(output,i)=qof(input,i)*window_function(2.0*rate+1.0); } }
void apply_window_f(float* input, float* output, int size, window_t window) { float (*window_function)(float)=firdes_get_window_kernel(window); for(int i=0;i<size;i++) //@apply_window_f { float rate=(float)i/(size-1); output[i]=input[i]*window_function(2.0*rate+1.0); } }