不韋 呂 / F746_SD_VarableFilter

Dependencies:   F746_GUI F746_SAI_IO FrequencyResponseDrawer SD_PlayerSkeleton

Committer:
MikamiUitOpen
Date:
Mon Apr 10 01:44:22 2017 +0000
Revision:
11:399670d24ed9
Parent:
10:3532c05aa1a9
12

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 2:dcaee06f6ccb 1 //------------------------------------------------------------------------
MikamiUitOpen 2:dcaee06f6ccb 2 // Design of Butterworth LPF and HPF using bilinear transform
MikamiUitOpen 2:dcaee06f6ccb 3 //
MikamiUitOpen 10:3532c05aa1a9 4 // 2017/03/25, Copyright (c) 2017 MIKAMI, Naoki
MikamiUitOpen 2:dcaee06f6ccb 5 //------------------------------------------------------------------------
MikamiUitOpen 2:dcaee06f6ccb 6
MikamiUitOpen 2:dcaee06f6ccb 7 #include "BilinearDesignLH.hpp"
MikamiUitOpen 2:dcaee06f6ccb 8
MikamiUitOpen 2:dcaee06f6ccb 9 namespace Mikami
MikamiUitOpen 2:dcaee06f6ccb 10 {
MikamiUitOpen 2:dcaee06f6ccb 11 // Execute design
MikamiUitOpen 2:dcaee06f6ccb 12 // input
MikamiUitOpen 2:dcaee06f6ccb 13 // fc: Cutoff frequency
MikamiUitOpen 2:dcaee06f6ccb 14 // pb: Passband (LPF or HPF)
MikamiUitOpen 2:dcaee06f6ccb 15 // output
MikamiUitOpen 2:dcaee06f6ccb 16 // c : Coefficients for cascade structure
MikamiUitOpen 2:dcaee06f6ccb 17 // g : Gain factor for cascade structure
MikamiUitOpen 2:dcaee06f6ccb 18 void BilinearDesign::Execute(float fc, Type pb, Coefs c[], float& g)
MikamiUitOpen 2:dcaee06f6ccb 19 {
MikamiUitOpen 2:dcaee06f6ccb 20 Butterworth();
MikamiUitOpen 2:dcaee06f6ccb 21 Bilinear(fc);
MikamiUitOpen 2:dcaee06f6ccb 22 ToCascade(pb);
MikamiUitOpen 2:dcaee06f6ccb 23 GetGain(pb);
MikamiUitOpen 2:dcaee06f6ccb 24 GetCoefs(c, g);
MikamiUitOpen 2:dcaee06f6ccb 25 }
MikamiUitOpen 2:dcaee06f6ccb 26
MikamiUitOpen 2:dcaee06f6ccb 27 // Get poles for Butterworth characteristics
MikamiUitOpen 2:dcaee06f6ccb 28 void BilinearDesign::Butterworth()
MikamiUitOpen 2:dcaee06f6ccb 29 {
MikamiUitOpen 2:dcaee06f6ccb 30 float pi_2order = PI_/(2.0f*ORDER_);
MikamiUitOpen 2:dcaee06f6ccb 31 for (int j=0; j<ORDER_/2; j++) // Pole with imaginary part >= 0
MikamiUitOpen 2:dcaee06f6ccb 32 {
MikamiUitOpen 2:dcaee06f6ccb 33 float theta = (2.0f*j + 1.0f)*pi_2order;
MikamiUitOpen 2:dcaee06f6ccb 34 sP_[j] = Complex(-cosf(theta), sinf(theta));
MikamiUitOpen 2:dcaee06f6ccb 35 }
MikamiUitOpen 2:dcaee06f6ccb 36 }
MikamiUitOpen 2:dcaee06f6ccb 37
MikamiUitOpen 2:dcaee06f6ccb 38 // Bilinear transform
MikamiUitOpen 2:dcaee06f6ccb 39 // fc: Cutoff frequency
MikamiUitOpen 2:dcaee06f6ccb 40 void BilinearDesign::Bilinear(float fc)
MikamiUitOpen 2:dcaee06f6ccb 41 {
MikamiUitOpen 2:dcaee06f6ccb 42 float wc = tanf(fc*PI_FS_);
MikamiUitOpen 2:dcaee06f6ccb 43 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 2:dcaee06f6ccb 44 zP_[k] = (1.0f + wc*sP_[k])/(1.0f - wc*sP_[k]);
MikamiUitOpen 2:dcaee06f6ccb 45 }
MikamiUitOpen 2:dcaee06f6ccb 46
MikamiUitOpen 2:dcaee06f6ccb 47 // Convert to coefficients for cascade structure
MikamiUitOpen 2:dcaee06f6ccb 48 void BilinearDesign::ToCascade(Type pb)
MikamiUitOpen 2:dcaee06f6ccb 49 {
MikamiUitOpen 2:dcaee06f6ccb 50 for (int j=0; j<ORDER_/2; j++)
MikamiUitOpen 2:dcaee06f6ccb 51 {
MikamiUitOpen 2:dcaee06f6ccb 52 ck_[j].a1 = 2.0f*real(zP_[j]); // a1m
MikamiUitOpen 2:dcaee06f6ccb 53 ck_[j].a2 = -norm(zP_[j]); // a2m
MikamiUitOpen 2:dcaee06f6ccb 54 ck_[j].b1 = (pb == LPF) ? 2.0f : -2.0f; // b1m
MikamiUitOpen 2:dcaee06f6ccb 55 ck_[j].b2 = 1.0f; // b2m
MikamiUitOpen 2:dcaee06f6ccb 56 }
MikamiUitOpen 2:dcaee06f6ccb 57 }
MikamiUitOpen 2:dcaee06f6ccb 58
MikamiUitOpen 2:dcaee06f6ccb 59 // Calculate gain factor
MikamiUitOpen 2:dcaee06f6ccb 60 void BilinearDesign::GetGain(Type pb)
MikamiUitOpen 2:dcaee06f6ccb 61 {
MikamiUitOpen 10:3532c05aa1a9 62 float u = (pb == LPF) ? 1.0f : -1.0f; // u: inverse of z
MikamiUitOpen 10:3532c05aa1a9 63 gain_ = 1.0f;
MikamiUitOpen 2:dcaee06f6ccb 64 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 10:3532c05aa1a9 65 gain_ = gain_*(1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)/
MikamiUitOpen 10:3532c05aa1a9 66 (1.0f + (ck_[k].b1 + ck_[k].b2*u)*u);
MikamiUitOpen 2:dcaee06f6ccb 67 }
MikamiUitOpen 2:dcaee06f6ccb 68
MikamiUitOpen 2:dcaee06f6ccb 69 // Get coefficients
MikamiUitOpen 2:dcaee06f6ccb 70 void BilinearDesign::GetCoefs(Coefs c[], float& gain)
MikamiUitOpen 2:dcaee06f6ccb 71 {
MikamiUitOpen 2:dcaee06f6ccb 72 for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k];
MikamiUitOpen 2:dcaee06f6ccb 73 gain = gain_;
MikamiUitOpen 2:dcaee06f6ccb 74 }
MikamiUitOpen 2:dcaee06f6ccb 75 }