Demo program of digital signal processing: Variable LPF/HPF, Vocal canceller, Pitch shifter, Reverbrator. ディジタル信号処理のデモプログラム. 遮断周波数可変 LPF/HPF,ボーカルキャンセラ,ピッチシフタ,残響生成器.

Dependencies:   Array_Matrix F446_AD_DA UIT_AQM1602 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //--------------------------------------------------------
00002 //  STM32F446 と信号処理用ボードによる信号処理のデモプログラム
00003 //
00004 //      SW: 偶数  入力をそのまま出力
00005 //           1: 遮断周波数可変 LPF
00006 //           3: 遮断周波数可変 HPF
00007 //           5: ボーカルキャンセラ
00008 //           7: ピッチシフタ
00009 //           9: 残響生成器
00010 //
00011 //  2017/02/21, Copyright (c) 2017 MIKAMI, Naoki
00012 //--------------------------------------------------------
00013 
00014 #include "F446_ADC_Interrupt.hpp"   // AD, DA
00015 #include "AQM1602.hpp"              // LCD 表示器
00016 #include "MyFunctions.hpp"          // グローバル関数
00017 #include "SignalProcessing.hpp"     // 信号処理の抽象基底クラスなど
00018 #include "VariableLpHp.hpp"         // 遮断周波数可変フィルタ
00019 #include "WeaverModulator.hpp"      // ピッチシフタ
00020 #include "Reverbrator.hpp"          // 残響生成器用
00021 using namespace Mikami;
00022 
00023 const int FS_ = 24000;      // 標本化周波数: 24 kHz
00024 AdcDual_Intr myAdc_(FS_);   // 参照:"F446_ADC_Interrupt.hpp"
00025 DacDual myDac_;             // 参照:"F446_DAC.hpp"
00026 DigitalOut ledG_(D10, 1);   // LED 緑色
00027 BusIn sws_(D6, D7, D8, D9); // ロータリ・ディップ・スイッチ用
00028 Ticker timer_;              // LED 点滅用
00029 
00030 Through through_;               // そのまま出力
00031 VariableLpHp filter_(10, FS_);  // 遮断周波数可変 IIR フィルタ
00032 VocalCanceller vCancel_;        // ボーカルキャンセラ
00033 FrqShifter fShifter_(FS_);      // ピッチシフタ
00034 EchoSystem echo_;               // 残響生成器
00035 
00036 // 割り込みが有効になる前にポインタに割り当てておく必要がある
00037 SignalProcessing *spPtr_ = &through_;
00038 
00039 void TimerIsr()
00040 {
00041     static int count20 = 0;
00042 
00043     int sw = sws_.read();
00044     if ( ((sw & 0x01) == 0x01) && (sw < 10) )
00045     {
00046         if (count20 <= sw) ledG_ = !ledG_;
00047     }
00048     else
00049     {
00050         if (count20 < 10) ledG_ = 1;
00051         else              ledG_ = 0;
00052     }
00053 
00054     if (++count20 > 20)
00055     {
00056         count20 = 0;
00057         ledG_ = 0;
00058     }
00059 }
00060 
00061 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン
00062 void AdcIsr()
00063 {
00064     float xn1, xn2, yn;
00065     myAdc_.Read(xn1, xn2);          // 入力
00066     yn = spPtr_->Execute(xn1, xn2); // sw の値に応じた信号処理の実行
00067     myDac_.Write(yn, yn);           // 出力
00068 }
00069 
00070 int main()
00071 {
00072     printf("\r\nDemonstration for digital signal processing\r\n");
00073 
00074     sws_.mode(PullDown);
00075 
00076     AnalogIn a3In(A3);          // VR からの電圧読み取り用
00077     Aqm1602 lcd;                // LCD 表示器
00078 
00079     // 出力の LPF の遮断周波数を 10 kHz に設定
00080     myDac_.ScfClock(10000*100);
00081 
00082     NVIC_SetPriority(ADC_IRQn, 1);
00083     NVIC_SetPriority(TIM5_IRQn, 2); // Ticker の割り込み優先度を ADC より低くする
00084 
00085 
00086     timer_.attach(&TimerIsr, 0.2f); // タイマ割り込みの設定
00087 
00088     // ADC 変換終了割り込みに対する割り込みサービス・ルーチン割り当て
00089     myAdc_.SetIntrVec(&AdcIsr);
00090 
00091     int kind = -1;  // 処理の種類
00092     float frq;      // VR で設定された周波数
00093 
00094     while (true)
00095     {
00096         int sw;     // 現在の機能切り替えスイッチの状態
00097         do
00098         {
00099             sw = sws_.read();
00100             wait_ms(50);
00101         } while (sw != sws_.read());
00102 
00103         switch (sw)
00104         {
00105             case  1:    // 遮断周波数可変 LPF
00106                 if (FrChange(a3In, 200, 2000, 10, frq) || (sw != kind))
00107                 {
00108                     filter_.Design(frq, BilinearDesign::LPF);
00109                     AssignDisplay(filter_, lcd, "LPF", frq);
00110                 }
00111                 break;
00112             case  3:    // 遮断周波数可変 HPF
00113                 if (FrChange(a3In, 200, 2000, 10, frq) || (sw != kind))
00114                 {
00115                     filter_.Design(frq, BilinearDesign::HPF);
00116                     AssignDisplay(filter_, lcd, "HPF", frq);
00117                 }
00118                 break;
00119             case  5:    // ボーカルキャンセラ
00120                 if (sw != kind)
00121                     AssignDisplay(vCancel_, lcd, "Vocal Calceller");
00122                 break;
00123             case  7:    // ピッチシフタ
00124                 if (FrChange(a3In, 0, 200, 1, frq) || (sw != kind))
00125                 {
00126                     fShifter_.SetFrequensy(frq);
00127                     AssignDisplay(fShifter_, lcd, "Pitch Shifter", frq);
00128                 }
00129                 break;
00130             case  9:    // 残響生成器
00131                 if (sw != kind)
00132                     AssignDisplay(echo_, lcd, "Reverbrator");
00133                 break;                    
00134             default:
00135                 if (sw != kind)
00136                     AssignDisplay(through_, lcd, "Through");
00137                 break;                    
00138         }
00139         kind = sw;
00140         wait(0.2f);
00141     }
00142 }
00143