Beispiel #1
0
//! fcd = cut-off (1=sampling rate)
//! ord = Filter order
//! ripple = passband ripple in dB
void chebyshev_iir(iir_coeff& filt, float_type fcd, bool lpf, float_type ripple = 3.0) {
  const float_type ten = 10.0;
  long order = filt.order;
  float_type epi = pow(ten, (ripple / ten)) - 1.0;
  epi = pow(epi, (float_type)(1. / (1.0 * order)));
  float_type wca = tan(0.5 * PI * fcd);
  //! wca - pre-warped angular frequency
  long n2 = (order + 1) / 2;
  chebyshev_s(filt.poles, filt.zeros, lpf, wca, epi, order, n2);
  filt.bilinear();
  filt.convert_to_ab();
}
Beispiel #2
0
//! fcd = cut-off (1=sampling rate)
//! ord = Filter order
//! ripple = passband ripple in dB
void chebyshev2_iir(iir_coeff& filt, float_type fcd, float_type stopband = 40.0) {
  const float_type ten = 10.0;
  auto order = filt.getOrder();
  float_type delta = pow(ten, -stopband/20.0);
  float_type epi   = delta/sqrt(1 - delta*delta);
  float_type wca = (filt.get_type()==filter_type::high) ? tan(M_PI * (0.5-fcd)) : tan(M_PI*fcd);
  chebyshev2_s(filt, wca, epi, order);
	filt.bilinear();
	if (filt.get_type()==filter_type::bandpass || filt.get_type()==filter_type::bandstop) {
		filt.make_band(filt.get_center());
	} else {
		filt.convert_to_ab();
	}
	if (filt.get_type()==filter_type::bandpass) filt.set_bandpass_gain();
}
Beispiel #3
0
 // Get frequency response for IIR   
 void iir_freq(iir_coeff& MF, int pts, double* w, double inc) {
 double w_inc = inc*M_PI/(float)pts;
 for (int i=0;i<pts;i++) {
   double t = MF.freqz_mag(w_inc*i);
   if (t==0) t = 0.00001;
   w[i] = 20.0*log(t)/log(10.0);
 }
 }
Beispiel #4
0
//! Calculate poles (chebyshev)
void chebyshev2_s(iir_coeff& filt, float_type wp, float_type epi, size_t order) {
  auto l = 1;
  size_t n2 = (order + 1) / 2;
  float_type x = 1 / epi;
  float_type lambda = pow(x*(1.0 + sqrt(1.0 + epi*epi)),1.0/order);
  float_type sm = 0.5*((1.0/lambda) - lambda);
  float_type cm = 0.5*((1.0/lambda) + lambda);
  for (size_t j = 0; j < n2; j++) {
    float_type arg  = M_PI * (2*l-1) / ((float_type)(2*order));
		std::complex<float_type> p = std::complex<float_type>(sm * sin(arg), cm * cos(arg));
    if (filt.get_type()==filter_type::low) {
			// Get regular chebyshev pole first
			// then transform for inverse chebyshev
			filt.set_pole((-wp*p/norm(p)), n2-1-j);
			// inverse chebyshev zero
			filt.set_zero(std::complex<float_type>(0,wp/cos(arg)),n2-1-j);
    } else {
			filt.set_pole(-p/wp, n2-1-j);
			filt.set_zero(std::complex<float_type>(0,cos(arg)/wp),n2-1-j);
    }
    l++;
  }
}