Cutoff frequency variable LPF, HPF, BPF, and BRF by FIR 160th-order filter.

Dependencies:   UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

Committer:
MikamiUitOpen
Date:
Sat Jul 25 06:36:06 2015 +0000
Revision:
3:24b6aa1a19ba
Parent:
0:ca94cfc90365
4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:ca94cfc90365 1 //------------------------------------------------------------------------------
MikamiUitOpen 0:ca94cfc90365 2 // Design of FIR filter of 4 type passbands using window method
MikamiUitOpen 0:ca94cfc90365 3 //
MikamiUitOpen 0:ca94cfc90365 4 // 2014/12/07, Copyright (c) 2014 MIKAMI, Naoki
MikamiUitOpen 0:ca94cfc90365 5 //------------------------------------------------------------------------------
MikamiUitOpen 0:ca94cfc90365 6
MikamiUitOpen 0:ca94cfc90365 7 #include "WindowingDesign.hpp"
MikamiUitOpen 0:ca94cfc90365 8
MikamiUitOpen 0:ca94cfc90365 9 namespace Mikami
MikamiUitOpen 0:ca94cfc90365 10 {
MikamiUitOpen 0:ca94cfc90365 11 WindowingDesign::WindowingDesign(int order, float fs)
MikamiUitOpen 0:ca94cfc90365 12 : FS_(fs), PI_FS_(3.1415926536f/fs)
MikamiUitOpen 0:ca94cfc90365 13 {
MikamiUitOpen 0:ca94cfc90365 14 order_ = order;
MikamiUitOpen 0:ca94cfc90365 15 if ((order % 2) != 0)
MikamiUitOpen 0:ca94cfc90365 16 {
MikamiUitOpen 0:ca94cfc90365 17 fprintf(stderr, "order must be even.");
MikamiUitOpen 0:ca94cfc90365 18 return;
MikamiUitOpen 0:ca94cfc90365 19 }
MikamiUitOpen 0:ca94cfc90365 20 hm_ = new float[order/2+1];
MikamiUitOpen 0:ca94cfc90365 21 wn_ = new float[order/2+1];
MikamiUitOpen 0:ca94cfc90365 22
MikamiUitOpen 0:ca94cfc90365 23 HammWindow();
MikamiUitOpen 0:ca94cfc90365 24 }
MikamiUitOpen 0:ca94cfc90365 25
MikamiUitOpen 0:ca94cfc90365 26 void WindowingDesign::Design(int order, Type pb,
MikamiUitOpen 0:ca94cfc90365 27 float fc1, float fc2,
MikamiUitOpen 0:ca94cfc90365 28 float hk[])
MikamiUitOpen 0:ca94cfc90365 29 {
MikamiUitOpen 0:ca94cfc90365 30 if (pb == LPF) fC_ = fc1;
MikamiUitOpen 0:ca94cfc90365 31 if (pb == HPF) fC_ = 0.5f*FS_ - fc1;
MikamiUitOpen 0:ca94cfc90365 32
MikamiUitOpen 0:ca94cfc90365 33 float w0 = PI_FS_*(fc1 + fc2);
MikamiUitOpen 3:24b6aa1a19ba 34 if ((pb == BPF) || (pb == BRF))
MikamiUitOpen 0:ca94cfc90365 35 fC_ = 0.5f*fabs(fc2 - fc1);
MikamiUitOpen 0:ca94cfc90365 36
MikamiUitOpen 0:ca94cfc90365 37 if (order != order_)
MikamiUitOpen 0:ca94cfc90365 38 {
MikamiUitOpen 0:ca94cfc90365 39 order_ = order_;
MikamiUitOpen 0:ca94cfc90365 40 if (hm_ != NULL) delete[] hm_;
MikamiUitOpen 0:ca94cfc90365 41 hm_ = new float[order/2+1];
MikamiUitOpen 0:ca94cfc90365 42 if (wn_ != NULL) delete[] wn_;
MikamiUitOpen 0:ca94cfc90365 43 wn_ = new float[order/2+1];
MikamiUitOpen 0:ca94cfc90365 44 HammWindow();
MikamiUitOpen 0:ca94cfc90365 45 }
MikamiUitOpen 0:ca94cfc90365 46
MikamiUitOpen 0:ca94cfc90365 47 // Calculate coefficients for LPF
MikamiUitOpen 0:ca94cfc90365 48 LpfCoefficients();
MikamiUitOpen 0:ca94cfc90365 49 // If not LPF, transform coefficients
MikamiUitOpen 0:ca94cfc90365 50 if (pb != LPF) Transform(pb, w0);
MikamiUitOpen 0:ca94cfc90365 51
MikamiUitOpen 0:ca94cfc90365 52 for (int k=0; k<=order/2; k++)
MikamiUitOpen 0:ca94cfc90365 53 hk[k] = hm_[order/2-k];
MikamiUitOpen 0:ca94cfc90365 54 }
MikamiUitOpen 0:ca94cfc90365 55
MikamiUitOpen 0:ca94cfc90365 56 // Calculation of coefficients for LPF
MikamiUitOpen 0:ca94cfc90365 57 void WindowingDesign::LpfCoefficients()
MikamiUitOpen 0:ca94cfc90365 58 {
MikamiUitOpen 0:ca94cfc90365 59 float w = 2.0f*PI_FS_*fC_;
MikamiUitOpen 0:ca94cfc90365 60 hm_[0] = 2.0f*fC_/FS_;
MikamiUitOpen 0:ca94cfc90365 61 for (int k=1; k<=order_/2; k++)
MikamiUitOpen 0:ca94cfc90365 62 hm_[k] = (sinf(k*w)/(PI_*k))*wn_[k];
MikamiUitOpen 0:ca94cfc90365 63 }
MikamiUitOpen 0:ca94cfc90365 64
MikamiUitOpen 0:ca94cfc90365 65 // Transform LPF to HPF, BPF, or BRF
MikamiUitOpen 0:ca94cfc90365 66 void WindowingDesign::Transform(Type pb, float w0)
MikamiUitOpen 0:ca94cfc90365 67 {
MikamiUitOpen 0:ca94cfc90365 68 if (pb == HPF) // To HPF
MikamiUitOpen 0:ca94cfc90365 69 for (int k=1; k<=order_/2; k+=2)
MikamiUitOpen 0:ca94cfc90365 70 hm_[k] = -hm_[k];
MikamiUitOpen 0:ca94cfc90365 71
MikamiUitOpen 0:ca94cfc90365 72 if (pb == BPF) // To BPF
MikamiUitOpen 0:ca94cfc90365 73 for (int k=0; k<=order_/2; k++)
MikamiUitOpen 0:ca94cfc90365 74 hm_[k] = 2.0f*cosf(w0*k)*hm_[k];
MikamiUitOpen 0:ca94cfc90365 75
MikamiUitOpen 0:ca94cfc90365 76 if (pb == BRF) // To BRF
MikamiUitOpen 0:ca94cfc90365 77 {
MikamiUitOpen 0:ca94cfc90365 78 hm_[0] = 1.0f - 2.0f*hm_[0];
MikamiUitOpen 0:ca94cfc90365 79 for (int k=1; k<=order_/2; k++)
MikamiUitOpen 0:ca94cfc90365 80 hm_[k] = -2.0*cosf(w0*k)*hm_[k];
MikamiUitOpen 0:ca94cfc90365 81 }
MikamiUitOpen 0:ca94cfc90365 82 }
MikamiUitOpen 0:ca94cfc90365 83
MikamiUitOpen 0:ca94cfc90365 84 // Hamming window
MikamiUitOpen 0:ca94cfc90365 85 void WindowingDesign::HammWindow()
MikamiUitOpen 0:ca94cfc90365 86 {
MikamiUitOpen 0:ca94cfc90365 87 float pi2OvM = 2.0f*PI_/(float)(order_ + 1);
MikamiUitOpen 0:ca94cfc90365 88 for (int n=0; n<=order_/2; n++)
MikamiUitOpen 0:ca94cfc90365 89 wn_[n] = 0.54f + 0.46f*cosf(pi2OvM*n);
MikamiUitOpen 0:ca94cfc90365 90 }
MikamiUitOpen 0:ca94cfc90365 91 }