CQエレクトロニクス・セミナで使用するグラフィック・イコライザ のプログラム
Dependencies: mbed SerialTxRxIntr DSP_MultirateLinearphase
Diff: main.cpp
- Revision:
- 0:b3c94b253ae5
- Child:
- 1:c30bdcb9ba69
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Feb 25 02:18:16 2022 +0000 @@ -0,0 +1,79 @@ +//---------------------------------------------------------------------- +// グラフィック・イコライザ,DA 出力はアップサンプリング使用 +// フィルタの係数の計算をマイコン側でも行うタイプ +// +// PC 側のプログラム: F446_GraphicEqualizerB +// +// 2022/02/19, Copyright (c) 2022 MIKAMI, Naoki +//---------------------------------------------------------------------- + +#include "MultirateLiPh.hpp" // DA でアップサンプリング +#include "SerialRxTxIntr.hpp" +#include "GraphicEqualizer.hpp" +#include <cctype> // isalpha(), isdigit() で使用 +using namespace Mikami; + +const float FS_ = 44.1f; // 入力の標本化周波数: 44.1 kHz +MultirateLiPh myAdDa_(FS_); // 出力標本化周波数を4倍にするオブジェクト + +const int BANDS_ = 9; // グラフィック・イコライザのバンド数 +GrEqualizer grEq_(BANDS_, FS_*1000); // グラフィック・イコライザ用オブジェクト + +void Select(string str); // 有効,無効,平坦化,出力 On/Off に対応する処理の選択 +void NumericCtrl(string str); // 帯域ごとの利得調整 + +// グラフィック・イコライザの信号処理 +void AdcIsr() +{ + float xn = myAdDa_.Input()*0.25f; // 入力 + float yn = grEq_.Execute(xn); // グラフィック・イコライザの処理 + myAdDa_.Output(yn); // 出力 +} + +int main() +{ + SerialRxTxIntr rx(72); // PC との通信用,9600 baud,バッファサイズ:72 + + NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高 + NVIC_SetPriority(USART2_IRQn, 1); + + myAdDa_.Start(&AdcIsr); // 標本化を開始する + while (true) + { + if (rx.IsEol()) // PC からの指令に対応する処理 + { + string str = rx.GetBuffer(); + if (str == "GrEqB") rx.TxString("ACK\n"); // "ACK" を送り返す + else + { + if (isalpha(str[0])) Select(str); + if (isdigit(str[0])) NumericCtrl(str); + // 第1文字がアルファベットでも数字でもない場合は何もしない + } + } + } +} + +// 有効,無効,平坦化,出力 On/Off に対応する処理の選択 +void Select(string str) +{ + if (str == "ACTIVE") grEq_.Validate(); // フィルタ処理有効 + if (str == "THROUGH") grEq_.Invalidate(); // フィルタ処理無効 + if (str == "ON") grEq_.SetOn(); // 出力を On + if (str == "OFF") grEq_.SetOff(); // 出力を Off +} + +// 帯域ごとの利得調整 +void NumericCtrl(string str) +{ + // 最初の2文字はフィルタの番号 + int band = atoi(str.substr(0, 2).c_str()); // フィルタの番号 + // 次の文字からは係数の値 + const int N = 5; // 係数の個数 + const int L0 = 13; // 一つの係数に対する文字数 + float c[N]; + for (int n=0; n<N; n++) + c[n] = atof(str.substr(n*L0+2, L0).c_str()); + grEq_.SetCoefficients(band, + (BiquadGrEq::Coefs){c[0], c[1], c[2], c[3], c[4]}); +}