44 if ( !(winlength % 2 == 0) )
56 for(i=0; i<winlength; i++)
57 x[i] *= 0.54f - 0.46f * (cosf(2.0f*
SAF_PI*(
float)i/(
float)N));
63 for(i=0; i<winlength; i++)
64 x[i] *= 0.5f - 0.5f * (cosf(2.0f*
SAF_PI*(
float)i/(
float)N));
68 for(i=0; i<winlength; i++)
69 x[i] *= 1.0f - 2.0f * fabsf((
float)i-((
float)N/2.0f))/(float)N;
73 for(i=0; i<winlength; i++){
75 0.49656f *cosf(2.0f*
SAF_PI*(
float)i/(
float)N) +
76 0.076849f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N);
81 for(i=0; i<winlength; i++){
83 0.487396f*cosf(2.0f*
SAF_PI*(
float)i/(
float)N) +
84 0.144232f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N) -
85 0.012604f*cosf(6.0f*
SAF_PI*(
float)i/(
float)N);
90 for(i=0; i<winlength; i++){
92 0.4891775f*cosf(2.0f*
SAF_PI*(
float)i/(
float)N) +
93 0.1365995f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N) +
94 0.0106411f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N);
99 for(i=0; i<winlength; i++){
101 0.48829f*cosf(2.0f*
SAF_PI*(
float)i/(
float)N) +
102 0.14128f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N) +
103 0.01168f*cosf(4.0f*
SAF_PI*(
float)i/(
float)N);
125 for (n=0; n<nSamples; n++){
127 wn = in_signal[n] - (a[1] * wz[0]);
130 out_signal[n] = b[0] * wn + b[1] * wz[0];
153 for (n=0; n<nSamples; n++){
155 wn = in_signal[n] - a[1] * wz[0] - a[2] * wz[1];
158 out_signal[n] = b[0] * wn + b[1] * wz[0] + b[2] * wz[1];
182 for (n=0; n<nSamples; n++){
184 wn = in_signal[n] - a[1] * wz[0] - a[2] * wz[1] - a[3] * wz[2];
187 out_signal[n] = b[0] * wn + b[1] * wz[0] + b[2] * wz[1] + b[3] * wz[2];
209 for(i=0; i<winlength; i++)
222 for(i=0; i<nCentreFreqs-1; i++)
223 cutoffFreqs[i] = 2.0f*centreFreqs[i]/sqrtf(2.0f);
233 float_complex* ctd_tmp, *tdi_f, *tdi_f_labs, *dt_min_f;
237 ctd_tmp =
malloc1d(len*
sizeof(float_complex));
238 tdi_f =
malloc1d(len*
sizeof(float_complex));
239 tdi_f_labs =
malloc1d(len*
sizeof(float_complex));
240 dt_min_f =
malloc1d(len*
sizeof(float_complex));
245 ctd_tmp[i] = cmplxf(x[i], 0.0f);
250 tdi_f_labs[i] = cmplxf(logf(cabsf(tdi_f[i])), 0.0f);
253 hilbert(tdi_f_labs, len, dt_min_f);
257 dt_min_f[i] = ccdivf(tdi_f[i], cexpf(conjf(dt_min_f[i])));
264 x[i] = crealf(ctd_tmp[i]);
279 float_complex* filters_in,
280 float_complex* filters_out
283 int i, j, nBins_in, nBins_out;
284 float* M_ifft, *M_ifft_fl;
286 void* hFFT_in, *hFFT_out;
288 nBins_in = inFFTsize/2 + 1;
289 nBins_out = outFFTsize/2 + 1;
296 for(i=0; i<nFilters; i++){
297 for(j=0; j<nBins_in; j++)
298 tmp[j] = filters_in[j*nFilters+i];
302 for(j=0; j<outFFTsize/2; j++){
303 M_ifft_fl[j] = M_ifft[inFFTsize/2+j];
304 M_ifft_fl[inFFTsize/2+j] = M_ifft[j];
307 for(j=0; j<nBins_out; j++)
308 filters_out[j*nFilters+i] = tmp[j];
323 return sqrtf(powf(2.0f, BW))/(powf(2.0f, BW)-1.0f);
331 return logf( (2.0f*Q*Q+1.0f)/(2.0f*Q*Q) + sqrtf( powf((2.0f*Q*Q+1.0f)/(Q*Q+2.23e-13f), 2.0f)/4.0f - 1.0f )) /logf(2.0f);
350 float K, KK, D, V0, A, w0, alpha, a0;
362 b[1] = (2.0f * KK * Q)/D;
364 a[1] = (2.0f * Q * (KK - 1.0f))/D;
365 a[2] = (KK * Q - K + Q)/D;
371 alpha = sinf(w0)/(2.0f*Q);
372 b[0] = (1.0f - cosf(w0))/2.0f;
373 b[1] = 1.0f - cosf(w0);
376 a[1] = -2.0f*cosf(w0);
393 b[1] = -(2.0f * Q)/D;
395 a[1] = (2.0f * Q * (KK - 1.0f))/D;
396 a[2] = (KK * Q - K + Q)/D;
402 alpha = sinf(w0)/(2.0f*Q);
403 b[0] = (1.0f + cosf(w0))/2.0f;
404 b[1] = -(1.0f + cosf(w0));
407 a[1] = -2.0f*cosf(w0);
421 V0 = powf(10.0f, (gain_dB/20.0f));
426 D = 1.0f + sqrtf(2.0f) * K + KK;
427 b[0] = (1.0f + sqrtf(2.0f * V0) * K + V0 * KK)/D;
428 b[1] = (2.0f*(V0*KK - 1.0f))/D;
429 b[2] = (1.0f - sqrtf(2.0f * V0) * K + V0 * KK)/D;
430 a[1] = (2.0f * (KK - 1.0f))/D;
431 a[2] = (1.0f - sqrtf(2.0f) * K + KK)/D;
434 D = V0 + sqrtf(2.0f*V0)*K + KK;
435 b[0] = (V0*(1.0f + sqrtf(2.0f)*K + KK))/D;
436 b[1] = (2.0f*V0*(KK - 1.0f))/D;
437 b[2] = (V0*(1.0f - sqrtf(2.0f)*K + KK))/D;
438 a[1] = (2.0f * (KK - V0))/D;
439 a[2] = (V0 - sqrtf(2.0f*V0)*K + KK)/D;
445 A = powf(10.0f, gain_dB/40.0f);
447 alpha = sinf(w0)/(2.0f*Q);
448 b[0] = A*( (A+1.0f) - (A-1.0f) * cosf(w0) + 2.0f*sqrtf(A)*alpha );
449 b[1] = 2.0f*A*( (A-1.0f) - (A+1.0f) * cosf(w0) );
450 b[2] = A*( (A+1.0f) - (A-1.0f) * cosf(w0) - 2.0f*sqrtf(A)*alpha );
451 a0 = (A+1.0f) + (A-1.0f) * cosf(w0) + 2.0f*sqrtf(A)*alpha;
452 a[1] = -2.0f*( (A-1.0f) + (A+1.0f) * cosf(w0) );
453 a[2] = (A+1.0f) + (A-1.0f) * cosf(w0) - 2.0f*sqrtf(A)*alpha;
466 V0 = powf(10.0f, (gain_dB/20.0f));
471 D = 1.0f + sqrtf(2.0f) * K + KK;
472 b[0] = (V0 + sqrtf(2.0f * V0) * K + KK)/D;
473 b[1] = (2.0f*(KK - V0))/D;
474 b[2] = (V0 - sqrtf(2.0f * V0) * K + KK)/D;
475 a[1] = (2.0f*(KK - 1.0f))/D;
476 a[2] = (1.0f - sqrtf(2.0f) * K + KK)/D;
479 D = 1.0f + sqrtf(2.0f*V0) * K + V0*KK;
480 b[0] = (V0*(1.0f + sqrtf(2.0f)*K + KK))/D;
481 b[1] = (2.0f*V0*(KK - 1.0f))/D;
482 b[2] = (V0*(1.0f - sqrtf(2.0f)*K + KK))/D;
483 a[1] = (2.0f * (V0*KK - 1.0f))/D;
484 a[2] = (1.0f - sqrtf(2.0f*V0)*K + V0*KK)/D;
490 A = powf(10.0f, gain_dB/40.0f);
492 alpha = sinf(w0)/(2.0f*Q);
493 b[0] = A*( (A+1.0f) + (A-1.0f) * cosf(w0) + 2.0f*sqrtf(A)*alpha );
494 b[1] = -2.0f*A*( (A-1.0f) + (A+1.0f) * cosf(w0) );
495 b[2] = A*( (A+1.0f) + (A-1.0f) * cosf(w0) - 2.0f*sqrtf(A)*alpha );
496 a0 = (A+1.0f) - (A-1.0f) * cosf(w0) + 2.0f*sqrtf(A)*alpha;
497 a[1] = 2.0f*( (A-1.0f) - (A+1.0f) * cosf(w0) );
498 a[2] = (A+1.0f) - (A-1.0f) * cosf(w0) - 2.0f*sqrtf(A)*alpha;
511 V0 = powf(10.0f, (gain_dB/20.0f));
514 D = 1.0f + (K/Q) + KK;
515 b[0] = (1.0f + (V0/Q) * K + KK)/D;
516 b[1] = (2.0f*(KK - 1.0f))/D;
517 b[2] = (1.0f - (V0/Q) * K + KK)/D;
519 a[2] = (1.0f - (K/Q) + KK)/D;
522 D = 1.0f + (K/(V0*Q)) + KK;
523 b[0] = (1.0f + (K/Q) + KK)/D;
524 b[1] = (2.0f*(KK - 1.0f))/D;
525 b[2] = (1.0f - (K/Q) + KK)/D;
527 a[2] = (1.0f - (K/(V0*Q)) + KK)/D;
533 A = powf(10.0f, gain_dB/40.0f);
535 alpha = sinf(w0)/(2.0f*Q);
536 b[0] = 1.0f + alpha*A;
537 b[1] = -2.0f*cosf(w0);
538 b[2] = 1.0f - alpha*A;
541 a[2] = 1.0f - alpha/A;
566 for(n=0; n<nSamples; n++){
567 wn = signal[n] - a[1] * w_z_12[0] - a[2] * w_z_12[1];
568 signal[n] = b[0] * wn + b[1] * w_z_12[0] + b[2] * w_z_12[1];
570 w_z_12[1] = w_z_12[0];
588 float w, denom_real, denom_imag, num_real, num_imag;
590 for(ff=0; ff<nFreqs; ff++){
591 w = tanf(
SAF_PI * freqs[ff]/fs);
594 denom_real = 1.0f + a[1]*cosf(w) + a[2]*cosf(2.0f*w);
595 denom_imag = a[1]*sinf(w) + a[2]*sinf(2.0f*w);
596 num_real = b[0] + b[1]*cosf(w) + b[2]*cosf(2.0f*w);
597 num_imag = b[1]*sinf(w) + b[2]*sinf(2.0f*w);
600 magnitude[ff] = sqrtf( (powf(num_real, 2.0f) + powf(num_imag, 2.0f)) / (powf(denom_real, 2.0f) + powf(denom_imag, 2.0f) + 2.23e-7f) );
602 magnitude[ff] = 20.0f*log10f(magnitude[ff]);
605 phase_rad[ff] = atan2f(num_imag,num_real) - atan2f(denom_imag, denom_real);
623 float w, x, a, b, c, d, h_re, h_im, cosx, sinx;
624 float norm_frq = -2.f *
SAF_PI / fs;
634 for(ff = 0; ff < nFreqs; ff++){
635 w = freqs[ff] * norm_frq;
644 for(
int n = 1; n < nCoeffs; n++){
648 a += b_coeff[n] * cosx;
649 b += b_coeff[n] * sinx;
650 c += a_coeff[n] * cosx;
651 d += a_coeff[n] * sinx;
655 double dvsr = 1.0 / (powf(c, 2.f) + powf(d, 2.f) + 2.23e-7f);
659 magnitude[ff] = (float)sqrt( (powf(a, 2.0f) + powf(b, 2.0f)) * dvsr );
661 magnitude[ff] = 20.0f*log10f(magnitude[ff]);
664 if(phase_rad!=NULL) {
666 h_re = (a*c + b*d) * (
float)dvsr;
667 h_im = (b*c - a*d) * (
float)dvsr;
668 phase_rad[ff] = (float)atan2(h_im, h_re);
688 double x, a, b, c, d, h_re, h_im, cosx, sinx;
689 float norm_frq = -2.f *
SAF_PI / fs;
699 for(ff = 0; ff < nFreqs; ff++){
700 w = freqs[ff] * norm_frq;
709 for(
int n = 1; n < nCoeffs; n++){
711 cosx = 1 - 2.f * pow(sin(x/2.f), 2.f);
713 a += b_coeff[n] * cosx;
714 b += b_coeff[n] * sinx;
715 c += a_coeff[n] * cosx;
716 d += a_coeff[n] * sinx;
720 double dvsr = 1.0 / (pow(c, 2.f) + pow(d, 2.f) + 2.23e-17f);
724 magnitude[ff] = (float)sqrt( (pow(a, 2.0f) + pow(b, 2.0f)) * dvsr );
726 magnitude[ff] = 20.0f*log10f(magnitude[ff]);
729 if(phase_rad!=NULL) {
731 h_re = (a*c + b*d) * dvsr;
732 h_im = (b*c - a*d) * dvsr;
733 phase_rad[ff] = (float)atan2(h_im, h_re);
753#if defined(SAF_USE_INTEL_IPP) && 0
756 IppsIIRState_32f* pIppIIR;
758 ba =
malloc1d(nCoeffs*2*
sizeof(Ipp32f));
759 for(i=0; i<nCoeffs; i++){
761 ba[i+nCoeffs] = a[i];
763 ippsIIRGetStateSize_32f( nCoeffs-1, &pBufSize );
764 m_pBuf = ippsMalloc_8u(pBufSize);
767 IppStatus error = ippsIIRInit_32f(&pIppIIR, ba, nCoeffs-1, NULL, m_pBuf);
768 error = ippsIIR_32f( in_signal, out_signal, nSamples, pIppIIR );
779 case 2:
applyIIR_1(in_signal, nSamples, b, a, wz, out_signal);
return;
780 case 3:
applyIIR_2(in_signal, nSamples, b, a, wz, out_signal);
return;
781 case 4:
applyIIR_3(in_signal, nSamples, b, a, wz, out_signal);
return;
785 for (n=0; n<nSamples; n++){
788 for (i=1; i<nCoeffs;i++)
789 wn = wn - (a[i] * wz[i-1]);
792 out_signal[n] = b[0] * wn;
793 for (i=1; i<nCoeffs; i++)
794 out_signal[n] = out_signal[n] + (b[i] * wz[i-1]);
798 case 10: wz[9] = wz[8];
799 case 9: wz[8] = wz[7];
800 case 8: wz[7] = wz[6];
801 case 7: wz[6] = wz[5];
802 case 6: wz[5] = wz[4];
803 case 5: wz[4] = wz[3];
804 case 4: wz[3] = wz[2];
805 case 3: wz[2] = wz[1];
806 case 2: wz[1] = wz[0];
807 case 1: wz[0] = wn;
break;
808 default:
saf_print_error(
"Unsupported number of IIR filter coefficients.");
824 int i, j, k, np, tmp_len, numStates, oddPolesFLAG, nCoeffs;
825 double wlow, whi, w0, wl, w1, BW, Wn1, q;
827 double* c_state, *r, *b_coeffs_real;
828 double** a_state, **bf_ss, **tmp1, **tmp2, **a_bili;
829 double_complex kaT, kbT;
830 double_complex den_cmplx[3];
831 double_complex* proto, *proto_tmp, *a_coeffs_cmplx, *kern, *rcmplx, *b_coeffs_cmplx;
833 wlow = (double)cutoff1/((
double)sampleRate/2.0);
834 whi = (double)cutoff2/((
double)sampleRate/2.0);
835 w0 = 4.0 * tan(
SAF_PI*wlow/2.0);
840 tmp_len = (int)((
float)order/2.0f);
842 proto =
malloc1d(np*
sizeof(double_complex));
843 proto[np-1] = cmplx(-1.0,0.0);
848 proto =
malloc1d(np*
sizeof(double_complex));
850 proto_tmp =
malloc1d(np*
sizeof(double_complex));
851 for(i=1, j=0; i<=order-1; i+=2, j++)
852 proto_tmp[j] = cexp(cmplx(0.0,
SAF_PI*(
double)i/(2.0*(
double)order) +
SAF_PI/2.0) );
853 for (i=0; i<tmp_len; i++){
854 proto[2*i] = proto_tmp[i];
855 proto[2*i+1] = conj(proto_tmp[i]);
861 memcpy(proto, proto_tmp, np*
sizeof(double_complex));
863 a_state = (
double**)
calloc2d(numStates,numStates,
sizeof(
double));
864 c_state =
malloc1d(numStates*
sizeof(
double));
866 a_state[0][0] = creal(proto[np-1]);
875 for(i=1; i<np; i+=2){
876 polyz_v(&proto[i-1], den_cmplx, 2);
878 den[j] = creal(den_cmplx[j]);
879 j = oddPolesFLAG ? i-1 : i-2;
882 a_state[0][0] = -den[1];
883 a_state[0][1] = -den[2];
891 a_state[j+1][k] = c_state[k];
892 a_state[j+1][j+1] = -den[1];
893 a_state[j+1][j+2] = -den[2];
894 a_state[j+2][j+1] = 1.0;
895 a_state[j+2][j+2] = 0.0;
911 bf_ss = (
double**)
malloc2d(numStates,numStates,
sizeof(
double));
912 for(i=0; i<numStates; i++)
913 for(j=0; j<numStates; j++)
914 bf_ss[i][j] = w0*(a_state[i][j]);
920 numStates = numStates*2;
921 w1 = 4.0*tan(
SAF_PI*whi/2.0);
925 bf_ss = (
double**)
calloc2d(numStates,numStates,
sizeof(
double));
926 for(i=0; i<numStates/2; i++)
927 for(j=0; j<numStates/2; j++)
928 bf_ss[i][j] = Wn1 * (a_state[i][j]) /q;
929 for(i=numStates/2; i<numStates; i++)
930 for(j=0; j<numStates/2; j++)
931 bf_ss[i][j] = (i-numStates/2) == j ? -Wn1 : 0.0;
932 for(i=0; i<numStates/2; i++)
933 for(j=numStates/2; j<numStates; j++)
934 bf_ss[i][j] = i == (j-numStates/2) ? Wn1 : 0.0;
937 nCoeffs = numStates+1;
940 tmp1 = (
double**)
malloc2d(numStates,numStates,
sizeof(
double));
941 tmp2 = (
double**)
malloc2d(numStates,numStates,
sizeof(
double));
942 a_bili = (
double**)
malloc2d(numStates,numStates,
sizeof(
double));
943 for(i=0; i<numStates; i++){
944 for(j=0; j<numStates; j++){
945 tmp1[i][j] = (i==j ? 1.0f : 0.0f) + bf_ss[i][j]*0.25;
946 tmp2[i][j] = (i==j ? 1.0f : 0.0f) - bf_ss[i][j]*0.25;
952 a_coeffs_cmplx =
malloc1d(nCoeffs*
sizeof(double_complex));
960 r =
malloc1d(numStates*
sizeof(
double));
961 for(i=0; i<numStates; i++)
966 r =
malloc1d(numStates*
sizeof(
double));
967 for(i=0; i<numStates; i++)
972 r =
malloc1d(numStates*
sizeof(
double));
973 wl = 2.0*atan2(Wn1, 4.0);
974 for(i=0; i<order;i++)
980 rcmplx =
malloc1d(numStates*
sizeof(double_complex));
981 Wn1 = 2.0*atan2(Wn1,4.0);
983 for(i=0; i<numStates;i++)
984 rcmplx[i] = cexp(cmplx(0.0, Wn1*pow(-1.0,(
double)i)));
987 b_coeffs_real =
malloc1d(nCoeffs*
sizeof(
double));
989 b_coeffs_cmplx =
malloc1d(nCoeffs*
sizeof(double_complex));
990 polyz_v(rcmplx, b_coeffs_cmplx, numStates);
991 for(i=0; i<nCoeffs; i++)
992 b_coeffs_real[i] = creal(b_coeffs_cmplx[i]);
993 free(b_coeffs_cmplx);
996 polyd_v(r, b_coeffs_real, numStates);
997 kern =
calloc1d(nCoeffs,
sizeof(double_complex));
998 kaT = cmplx(0.0,0.0);
999 kbT = cmplx(0.0,0.0);
1000 for(i=0; i<nCoeffs; i++){
1001 kern[i] = cexp(cmplx(0.0,-wl*(
double)i));
1002 kaT = ccadd(kaT, crmul(kern[i],creal(a_coeffs_cmplx[i])));
1003 kbT = ccadd(kbT, crmul(kern[i],b_coeffs_real[i]));
1007 for(i=0; i<nCoeffs; i++){
1008 b_coeffs[i] = creal(crmul(ccdiv(kaT,kbT), b_coeffs_real[i]));
1009 a_coeffs[i] = creal(a_coeffs_cmplx[i]);
1020 free(a_coeffs_cmplx);
1021 free(b_coeffs_real);
1026typedef struct _faf_IIRFB_data{
1058 double b_lpf[4], a_lpf[4], b_hpf[4], a_hpf[4], r[7], revb[4], reva[4], q[4];
1059 double tmp[7], tmp2[7];
1060 double_complex d1[3], d2[3], d1_num[3], d2_num[3];
1061 double_complex z[3], A[3][3], ztmp[7], ztmp2[7];
1062 int i, j, f, filtLen, d1_len, d2_len;
1064 saf_assert( (order==1) || (order==3),
"Only odd number orders are supported, and 5th order+ is numerically unstable");
1065 saf_assert(nCutoffFreq>1,
"Number of filterbank cut-off frequencies must be more than 1");
1066 filtLen = order + 1;
1073 fb->
nBands = nCutoffFreq + 1;
1076 fb->
b_hpf = (
float**)
malloc2d(nCutoffFreq, filtLen,
sizeof(
float));
1077 fb->
a_hpf = (
float**)
malloc2d(nCutoffFreq, filtLen,
sizeof(
float));
1078 fb->
b_lpf = (
float**)
malloc2d(nCutoffFreq, filtLen,
sizeof(
float));
1079 fb->
a_lpf = (
float**)
malloc2d(nCutoffFreq, filtLen,
sizeof(
float));
1090 for(f=0; f<nCutoffFreq; f++){
1095 for(i=0; i<filtLen; i++){
1096 reva[i] = a_lpf[filtLen-i-1];
1097 revb[i] = b_lpf[filtLen-i-1];
1099 convd(revb, b_lpf, filtLen, filtLen, tmp);
1100 convd(a_lpf, reva, filtLen, filtLen, tmp2);
1101 for(i=0; i<2*filtLen-1; i++)
1102 r[i] = tmp[i] - tmp2[i];
1103 q[0] = sqrt(-r[0]/-1.0);
1104 q[1] = -r[1]/(2.0*-1.0*q[0]);
1111 for(i=0; i<filtLen; i++)
1112 q[i] = b_lpf[i] - q[i];
1116 z[0] = cmplx(-q[1]/q[0], 0.0);
1118 memset(A, 0, 9*
sizeof(double_complex));
1119 A[0][0] = cmplx(-q[1]/q[0], 0.0);
1120 A[0][1] = cmplx(-q[2]/q[0], 0.0);
1121 A[0][2] = cmplx(-q[3]/q[0], 0.0);
1122 A[1][0] = cmplx(1.0, 0.0);
1123 A[2][1] = cmplx(1.0, 0.0);
1124 utility_zeig(NULL, (double_complex*)A, 3, NULL, NULL, NULL, (double_complex*)z);
1129 d1[0] = cmplx(1.0, 0.0);
1130 d2[0] = cmplx(1.0, 0.0);
1131 d1_len = d2_len = 1;
1132 for(i=0; i<order; i++){
1133 if (cabs(z[i]) < 1.0){
1134 ztmp[0] = cmplx(1.0, 0.0);
1135 ztmp[1] = crmul(z[i], -1.0);
1136 convz(d2,ztmp,d2_len,2,ztmp2);
1138 for(j=0; j<d2_len; j++)
1142 ztmp[0] = cmplx(1.0, 0.0);
1143 ztmp[1] = ccdiv(cmplx(-1.0, 0.0), conj(z[i]));
1144 convz(d1,ztmp,d1_len,2,ztmp2);
1146 for(j=0; j<d1_len; j++)
1154 for(i=0; i<d1_len; i++)
1155 d1_num[i] = conj(d1[d1_len-i-1]);
1156 for(i=0; i<d2_len; i++)
1157 d2_num[i] = conj(d2[d2_len-i-1]);
1158 convz(d1_num, d2, d1_len, d2_len, ztmp);
1159 convz(d2_num, d1, d2_len, d1_len, ztmp2);
1160 for(i=0; i<filtLen; i++){
1161 b_hpf[i] = -0.5 * creal(ccsub(ztmp[filtLen-i-1], ztmp2[filtLen-i-1]));
1162 a_hpf[i] = a_lpf[i];
1166 for(i=0; i<filtLen; i++){
1167 fb->
b_hpf[f][i] = (float)b_hpf[i];
1168 fb->
a_hpf[f][i] = (float)a_hpf[i];
1169 fb->
b_lpf[f][i] = (float)b_lpf[i];
1170 fb->
a_lpf[f][i] = (float)a_lpf[i];
1186 saf_assert(nSamples <= fb->maxNSamplesToExpect,
"Number of samples exceeds the maximum number informed when calling faf_IIRFilterbank_create()");
1189 for(band=0; band<fb->
nBands; band++)
1190 memcpy(outBands[band], inSig, nSamples*
sizeof(
float));
1202 for (band = 2; band < fb->
nBands; band++){
1203 for (j=0; j<=band-2; j++){
1211 for(band = 2; band< fb->
nBands-1; band++){
1216 for(j=band; j<fb->
nBands-1; j++)
1281 float ft1, ft2, h_sum, f0;
1282 float_complex h_z_sum;
1292 for(i=0; i<h_len; i++)
1293 h_filt[i] = i==order/2 ? 2.0f*ft1 : sinf(2.0f*
SAF_PI*ft1*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2));
1297 for(i=0; i<h_len; i++)
1298 h_filt[i] = i==order/2 ? 1.0f - 2.0f*ft1 : -sinf(2.0f*ft1*
SAF_PI*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2));
1303 for(i=0; i<h_len; i++){
1304 h_filt[i] = i==order/2 ? 2.0f*(ft2-ft1) :
1305 sinf(2.0f*
SAF_PI*ft2*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2)) - sinf(2.0f*
SAF_PI*ft1*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2));
1311 for(i=0; i<h_len; i++){
1312 h_filt[i] = i==order/2 ? 1.0f - 2.0f*(ft2-ft1) :
1313 sinf(2.0f*
SAF_PI*ft1*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2)) - sinf(2.0f*
SAF_PI*ft2*(
float)(i-order/2)) / (
SAF_PI*(float)(i-order/2));
1319 saf_print_error(
"Please specify an even value for the filter 'order' argument");
1333 for(i=0; i<h_len; i++)
1335 for(i=0; i<h_len; i++)
1341 h_z_sum = cmplxf(0.0f, 0.0f);
1342 for(i=0; i<h_len; i++)
1343 h_z_sum = ccaddf(h_z_sum, crmulf(cexpf(cmplxf(0.0f, -2.0f*
SAF_PI*(
float)i*f0/2.0f)), h_filt[i]));
1344 h_sum = cabsf(h_z_sum);
1345 for(i=0; i<h_len; i++)
1350 f0 = fc1/fs + fc2/fs;
1351 h_z_sum = cmplxf(0.0f, 0.0f);
1352 for(i=0; i<h_len; i++)
1353 h_z_sum = ccaddf(h_z_sum, crmulf(cexpf(cmplxf(0.0f, -2.0f*
SAF_PI*(
float)i*f0/2.0f)), h_filt[i]));
1354 h_sum = cabsf(h_z_sum);
1355 for(i=0; i<h_len; i++)
1376 nFilt = nCutoffFreq + 1;
1381 FIRCoeffs(
FIR_FILTER_HPF, order, fc[nCutoffFreq-1], 0.0f, sampleRate, windowType, scalingFLAG, &filterbank[(nFilt-1)*(order+1)]);
1385 for(k=1; k<nFilt-1; k++)
1386 FIRCoeffs(
FIR_FILTER_BPF, order, fc[k-1], fc[k], sampleRate, windowType, scalingFLAG, &filterbank[k*(order+1)]);
#define saf_print_error(message)
Macro to print a error message along with the filename and line number.
void faf_IIRFilterbank_destroy(void **phFaF)
Destroys an instance of the Favrot & Faller filterbank.
void utility_dinv(void *const hWork, double *A, double *B, const int N)
Matrix inversion: double precision, i.e.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
#define SAF_PI
pi constant (single precision)
WINDOWING_FUNCTION_TYPES
Windowing function types.
BUTTER_FILTER_TYPES
Butterworth Infinite Impulse Response (IIR) filter design options.
FIR_FILTER_TYPES
Finite Impulse Response (FIR) filter design options.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void utility_dglslv(void *const hWork, const double *A, const int dim, double *B, int nCol, double *X)
General linear solver: double precision, i.e.
void saf_fft_backward(void *const hFFT, float_complex *inputFD, float_complex *outputTD)
Performs the backward-FFT operation; use for complex to complex transformations.
BIQUAD_FILTER_TYPES
Bi-quadratic (second-order) IIR filter design options.
void FIRFilterbank(int order, float *fc, int nCutoffFreq, float sampleRate, WINDOWING_FUNCTION_TYPES windowType, int scalingFLAG, float *filterbank)
Computes a bank of FIR filter coefficients required to divide a signal into frequency bands.
void cmplxPairUp(double_complex *in_vec, double_complex *out_vec, int len)
Pairs up complex numbers and sorts them in ascending order based on their real parts first,...
void saf_fft_create(void **const phFFT, int N)
Creates an instance of saf_fft; complex<->complex FFT.
void hilbert(float_complex *x, int x_len, float_complex *y)
Computes the discrete-time analytic signal via the Hilbert transform [1].
void faf_IIRFilterbank_create(void **phFaF, int order, float *fc, int nCutoffFreq, float sampleRate, int maxNumSamples)
Computes a bank of IIR filter coefficients required to divide a signal into frequency bands,...
void applyIIR(float *in_signal, int nSamples, int nCoeffs, float *b, float *a, float *wz, float *out_signal)
Applies an IIR filter to a time-domain signal (using the direct form II difference equation)
void saf_rfft_create(void **const phFFT, int N)
Creates an instance of saf_rfft; real<->half-complex (conjugate-symmetric) FFT.
void getWindowingFunction(WINDOWING_FUNCTION_TYPES type, int winlength, float *win)
Computes the weights of a specific windowing function.
void flattenMinphase(float *x, int len)
Equalises input sequence by its minimum phase form, in order to bring its magnitude response to unity...
void saf_fft_forward(void *const hFFT, float_complex *inputTD, float_complex *outputFD)
Performs the forward-FFT operation; use for complex to complex transformations.
void evalIIRTransferFunctionf(float *b_coeff, float *a_coeff, int nCoeffs, float *freqs, int nFreqs, float fs, int mag2dB, float *magnitude, float *phase_rad)
Computes magnitude and phase response of an IIR filter from its coefficients (floats) at user-specifi...
void polyd_m(double *X, double_complex *poly, int size_x)
Convert roots of a matrix to polynomial (real double precision)
float convertQ2BW(float Q)
Converts filter Q-factor to octave band-width.
void utility_zeig(void *const hWork, const double_complex *A, const int dim, double_complex *VL, double_complex *VR, double_complex *D, double_complex *eig)
Eigenvalue decomposition of a NON-SYMMETRIC matrix: double precision complex, i.e.
void saf_rfft_forward(void *const hFFT, float *inputTD, float_complex *outputFD)
Performs the forward-FFT operation; use for real to complex (conjugate symmetric) transformations.
void applyBiQuadFilter(float b[3], float a[3], float w_z_12[2], float *signal, int nSamples)
Applies biQuad filter to an input signal using the direct form II difference equation: https://en....
void biQuadCoeffs(BIQUAD_FILTER_TYPES filterType, float fc, float fs, float Q, float gain_dB, float b[3], float a[3])
Calculates 2nd order IIR filter coefficients [1].
void saf_rfft_backward(void *const hFFT, float_complex *inputFD, float *outputTD)
Performs the backward-FFT operation; use for complex (conjugate symmetric) to real transformations.
void saf_rfft_destroy(void **const phFFT)
Destroys an instance of saf_rfft.
void FIRCoeffs(FIR_FILTER_TYPES filterType, int order, float fc1, float fc2, float fs, WINDOWING_FUNCTION_TYPES windowType, int scalingFLAG, float *h_filt)
Computes FIR filter coefficients by windowing.
void butterCoeffs(BUTTER_FILTER_TYPES filterType, int order, float cutoff1, float cutoff2, float sampleRate, double *b_coeffs, double *a_coeffs)
Computes Butterworth IIR filter coefficients [1].
void evalBiQuadTransferFunction(float b[3], float a[3], float *freqs, int nFreqs, float fs, int mag2dB, float *magnitude, float *phase_rad)
Evaluates the 2nd order IIR transfer function at one or more frequencies, returning its magnitude and...
void convd(double *x, double *h, int len_x, int len_h, double *y)
Basic 1-D direct convolution in the time-domain (real double precision)
void utility_svvadd(const float *a, const float *b, const int len, float *c)
Single-precision, vector-vector addition, i.e.
void polyd_v(double *x, double *poly, int len_x)
Convert roots of a vector to polynomial (real double precision)
void polyz_v(double_complex *x, double_complex *poly, int len_x)
Convert roots of a vector to polynomial (complex double precision)
void faf_IIRFilterbank_flushBuffers(void *hFaF)
Zeros the delay lines used during faf_IIRFilterbank_apply()
float convertBW2Q(float BW)
Converts filter octave band-width to Q-factor.
void evalIIRTransferFunction(double *b_coeff, double *a_coeff, int nCoeffs, float *freqs, int nFreqs, float fs, int mag2dB, float *magnitude, float *phase_rad)
Computes magnitude and phase response of an IIR filter from its coefficients at user-specified freque...
void interpolateFiltersH(int inFFTsize, int outFFTsize, int nFilters, float_complex *filters_in, float_complex *filters_out)
Interpolate filters (w.r.t.
void saf_fft_destroy(void **const phFFT)
Destroys an instance of saf_fft.
void convz(double_complex *x, double_complex *h, int len_x, int len_h, double_complex *y)
Basic 1-D direct convolution in the time-domain (complex double precision)
void getOctaveBandCutoffFreqs(float *centreFreqs, int nCentreFreqs, float *cutoffFreqs)
Converts octave band CENTRE frequencies into CUTOFF frequencies.
void faf_IIRFilterbank_apply(void *hFaF, float *inSig, float **outBands, int nSamples)
Applies the Favrot & Faller filterbank.
@ WINDOWING_FUNCTION_RECTANGULAR
Rectangular.
@ WINDOWING_FUNCTION_BLACKMAN_NUTTALL
Blackman-Nuttall.
@ WINDOWING_FUNCTION_BLACKMAN
Blackman.
@ WINDOWING_FUNCTION_BARTLETT
Bartlett.
@ WINDOWING_FUNCTION_HANN
Hann.
@ WINDOWING_FUNCTION_HAMMING
Hamming.
@ WINDOWING_FUNCTION_NUTTALL
Nuttall.
@ WINDOWING_FUNCTION_BLACKMAN_HARRIS
Blackman-Harris.
@ BUTTER_FILTER_BSF
band-stop filter
@ BUTTER_FILTER_LPF
low-pass filter
@ BUTTER_FILTER_HPF
high-pass filter
@ BUTTER_FILTER_BPF
band-pass filter
@ FIR_FILTER_BSF
band-stop filter
@ FIR_FILTER_LPF
low-pass filter
@ FIR_FILTER_HPF
high-pass filter
@ FIR_FILTER_BPF
band-pass filter
@ BIQUAD_FILTER_LPF
low-pass filter (DAFx-Zolzer)
@ BIQUAD_FILTER_LOW_SHELF_EQCB
low-shelving filter (EQ-cookbook)
@ BIQUAD_FILTER_PEAK
peaking filter (DAFx-Zolzer)
@ BIQUAD_FILTER_HPF_EQCB
high-pass filter (EQ-cookbook)
@ BIQUAD_FILTER_PEAK_EQCB
peaking filter (EQ-cookbook)
@ BIQUAD_FILTER_LOW_SHELF
low-shelving filter (DAFx-Zolzer)
@ BIQUAD_FILTER_LPF_EQCB
low-pass filter (EQ-cookbook)
@ BIQUAD_FILTER_HI_SHELF_EQCB
high-shelving filter (EQ-cookbook)
@ BIQUAD_FILTER_HI_SHELF
high-shelving filter (DAFx-Zolzer)
@ BIQUAD_FILTER_HPF
high-pass filter (DAFx-Zolzer)
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
void *** calloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D calloc (contiguously allocated, so use free() as usual to deallocate)
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
Include header for SAF externals.
Main header for the utilities module (SAF_UTILITIES_MODULE)
static void applyIIR_1(float *in_signal, int nSamples, float *b, float *a, float *wz, float *out_signal)
Applies IIR filter of order 1.
static void applyWindowingFunction(WINDOWING_FUNCTION_TYPES type, int winlength, float *x)
Applies a windowing function (see WINDOWING_FUNCTION_TYPES enum) of length 'winlength',...
static void applyIIR_2(float *in_signal, int nSamples, float *b, float *a, float *wz, float *out_signal)
Applies IIR filter of order 2.
static void applyIIR_3(float *in_signal, int nSamples, float *b, float *a, float *wz, float *out_signal)
Applies IIR filter of order 3.
Main structure for the Favrot&Faller filterbank.
float *** wz_hpf
Delay buffers for high-pass filters.
int filtOrder
Filter order (must be 1 or 3)
float ** a_hpf
Denominator filter coeffs for high-pass filters.
int nBands
Number of bands in the filterbank.
float * tmp2
Temporary buffer; maxNSamplesToExpect x 1.
int maxNSamplesToExpect
Maximum number of samples to expect to process at a time.
int filtLen
Filter length.
float * tmp
Temporary buffer; maxNSamplesToExpect x 1.
float *** wz_apf1
Delay buffers for all-pass filter part 1.
float *** wz_lpf
Delay buffers for low-pass filters.
float ** a_lpf
Denominator filter coeffs for low-pass filters.
float *** wz_apf2
Delay buffers for all-pass filter part 2.
int nFilters
Number of filters used by the filterbank.
float ** b_lpf
Numerator filter coeffs for low-pass filters.
float ** b_hpf
Numerator filter coeffs for high-pass filters.