Cutoff frequency variable LPF and HPF by 160th-order FIR filter designed by window method usin Hamming window for ST Nucleo F401RE.

Dependencies:   UIT_ACM1602NI UIT_ADDA mbed

Committer:
MikamiUitOpen
Date:
Mon Nov 10 03:03:18 2014 +0000
Revision:
0:ea9a0c65a7dd
1

Who changed what in which revision?

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