Vowel synthesizer using digital resonators. This program can run without LCD display. ディジタル共振器を使った合成母音ジェネレータ.LCD表示器なしでも動く.
Dependencies: UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed
main.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2015-07-25
- Revision:
- 5:0396de26b449
- Parent:
- 4:dd2ec72068d0
File content as of revision 5:0396de26b449:
//------------------------------------------------------------ // ディジタル共振器を使った母音発生器 // sw: 1, 2, 3, 4, 5 => /a/, /i/, /u/, /e/, /o/ // sw: 0 => Without resonator // スイッチを切り替えてから Nucleo ボードのユーザボタン(青色)を // 押すと違う合成母音が発生する. // 母音の基本周波数は VR で変えられる(合成母音の音が出ている最中 // でも変えられる) // // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki //------------------------------------------------------------ #include "ADC_BuiltIn.hpp" // for ADC not using interrupt #include "DAC_MCP4921.hpp" // for DAC MCP4921, MCP4922 #include "ACM1602NI.hpp" // for LCD display #include "Rosenberg.hpp" // Glottal source #include "Resonator.hpp" // Resonator corresponding to vocal tract #include "Radiator.hpp" // Radiator from mouth using namespace Mikami; // ACM1602Ni を使う場合は次の define 文をコメントにすること #define AQM1602 #ifdef AQM1602 #include "AQM1602.hpp" Aqm1602 Lcd_; #else #include "ACM1602NI.hpp" Acm1602Ni Lcd_; #endif const int FS_ = 8000; // Sampling frequency: 8 kHz ADC_BuiltIn adc_(A2, FS_); // for AD DAC_MCP4921 myDac_; // for DA DigitalIn uButton_(USER_BUTTON); BusIn busSw_(D2, D3, D4, D5); const int N_VWL_ = 5; // 母音の種類の数 const int N_RSN_ = 3; // 共振器の数 // フォルマント周波数,帯域幅のデータ:{周波数, 帯域幅} const Resonator::FrBw c_[N_VWL_][N_RSN_] = {{ {654, 50}, {1060, 55}, {2375, 60} }, // ア { {302, 40}, {2057, 60}, {3034, 65} }, // イ { {375, 45}, {1208, 55}, {2165, 60} }, // ウ { {541, 50}, {1784, 60}, {2452, 60} }, // エ { {458, 45}, { 807, 50}, {2379, 60} }}; // オ int main() { // 基本周波数の可変範囲を決める定数(100 ~ 180 Hz の範囲) const float F0_COEF = 50.0f/4095.0f; // 範囲を決める定数 const float F0_MIN = 100.0f; // 最低の基本周波数 Rosenberg g(100, FS_, 2.5f); // 声帯波発生用オブジェクト初期化 // 基本周波数:100 Hz Resonator rs[N_RSN_]; // 共振器用オブジェクト配列の宣言 Radiator rd; // 放射の効果用オブジェクトの初期化 myDac_.ScfClockTim3(336000); // cutoff frequency: 3.36 kHz busSw_.mode(PullDown); Lcd_.Clear(); Lcd_.WriteStringXY("Synthetic Vowel", 0, 0); while (true) { int sw = busSw_.read(); if (sw > 5) sw = 5; char str[4] = {'/', 0xB0+sw, '/', NULL}; Lcd_.WriteStringXY(str, 0, 1); // -アイウエオ // 共振器の準備 if (sw > 0) for (int k=0; k<N_RSN_; k++) rs[k] = Resonator(c_[sw-1][k], FS_); for (int n=0; n<4000; n++) { uint16_t adVal = adc_.Read_u16(); // Read from A2 float f0 = adVal*F0_COEF + F0_MIN; g.SetPeriod(f0); // 基本周波数を設定 //----------------------------------------------- // ここで合成母音を発生している float vn = g.Execute(); // 合成声帯波発生 if (sw != 0) for (int k=0; k<N_RSN_; k++) vn = rs[k].Execute(vn); // 声道の効果 float yn = rd.Execute(vn); // 放射の効果 //----------------------------------------------- myDac_.Write(yn); // Write to DAC } // ユーザボタンが押されるまで待つ while (uButton_ == 1) {} Lcd_.ClearLine(1); } }