![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Cutoff frequency variable LPF, HPF, BPF, and BRF by FIR 160th-order filter.
Dependencies: UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602
Diff: WindowingDesign/WindowingDesign.cpp
- Revision:
- 0:ca94cfc90365
- Child:
- 3:24b6aa1a19ba
diff -r 000000000000 -r ca94cfc90365 WindowingDesign/WindowingDesign.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WindowingDesign/WindowingDesign.cpp Mon Dec 08 08:14:48 2014 +0000 @@ -0,0 +1,91 @@ +//------------------------------------------------------------------------------ +// Design of FIR filter of 4 type passbands using window method +// +// 2014/12/07, Copyright (c) 2014 MIKAMI, Naoki +//------------------------------------------------------------------------------ + +#include "WindowingDesign.hpp" + +namespace Mikami +{ + WindowingDesign::WindowingDesign(int order, float fs) + : FS_(fs), PI_FS_(3.1415926536f/fs) + { + order_ = order; + if ((order % 2) != 0) + { + fprintf(stderr, "order must be even."); + return; + } + hm_ = new float[order/2+1]; + wn_ = new float[order/2+1]; + + HammWindow(); + } + + void WindowingDesign::Design(int order, Type pb, + float fc1, float fc2, + float hk[]) + { + if (pb == LPF) fC_ = fc1; + if (pb == HPF) fC_ = 0.5f*FS_ - fc1; + + float w0 = PI_FS_*(fc1 + fc2); + if ((pb == BPF) || (pb == BPF)) + fC_ = 0.5f*fabs(fc2 - fc1); + + if (order != order_) + { + order_ = order_; + if (hm_ != NULL) delete[] hm_; + hm_ = new float[order/2+1]; + if (wn_ != NULL) delete[] wn_; + wn_ = new float[order/2+1]; + HammWindow(); + } + + // Calculate coefficients for LPF + LpfCoefficients(); + // If not LPF, transform coefficients + if (pb != LPF) Transform(pb, w0); + + for (int k=0; k<=order/2; k++) + hk[k] = hm_[order/2-k]; + } + + // Calculation of coefficients for LPF + void WindowingDesign::LpfCoefficients() + { + float w = 2.0f*PI_FS_*fC_; + hm_[0] = 2.0f*fC_/FS_; + for (int k=1; k<=order_/2; k++) + hm_[k] = (sinf(k*w)/(PI_*k))*wn_[k]; + } + + // Transform LPF to HPF, BPF, or BRF + void WindowingDesign::Transform(Type pb, float w0) + { + if (pb == HPF) // To HPF + for (int k=1; k<=order_/2; k+=2) + hm_[k] = -hm_[k]; + + if (pb == BPF) // To BPF + for (int k=0; k<=order_/2; k++) + hm_[k] = 2.0f*cosf(w0*k)*hm_[k]; + + if (pb == BRF) // To BRF + { + hm_[0] = 1.0f - 2.0f*hm_[0]; + for (int k=1; k<=order_/2; k++) + hm_[k] = -2.0*cosf(w0*k)*hm_[k]; + } + } + + // Hamming window + void WindowingDesign::HammWindow() + { + float pi2OvM = 2.0f*PI_/(float)(order_ + 1); + for (int n=0; n<=order_/2; n++) + wn_[n] = 0.54f + 0.46f*cosf(pi2OvM*n); + } +}