Vowel synthesizer using digital resonators. This program can run without LCD display. ディジタル共振器を使った合成母音ジェネレータ.LCD表示器なしでも動く.
Dependencies: UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed
main.cpp@5:0396de26b449, 2015-07-25 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sat Jul 25 07:10:11 2015 +0000
- Revision:
- 5:0396de26b449
- Parent:
- 4:dd2ec72068d0
6
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:6c67a9387981 | 1 | //------------------------------------------------------------ |
MikamiUitOpen | 5:0396de26b449 | 2 | // ディジタル共振器を使った母音発生器 |
MikamiUitOpen | 0:6c67a9387981 | 3 | // sw: 1, 2, 3, 4, 5 => /a/, /i/, /u/, /e/, /o/ |
MikamiUitOpen | 0:6c67a9387981 | 4 | // sw: 0 => Without resonator |
MikamiUitOpen | 5:0396de26b449 | 5 | // スイッチを切り替えてから Nucleo ボードのユーザボタン(青色)を |
MikamiUitOpen | 5:0396de26b449 | 6 | // 押すと違う合成母音が発生する. |
MikamiUitOpen | 5:0396de26b449 | 7 | // 母音の基本周波数は VR で変えられる(合成母音の音が出ている最中 |
MikamiUitOpen | 5:0396de26b449 | 8 | // でも変えられる) |
MikamiUitOpen | 5:0396de26b449 | 9 | // |
MikamiUitOpen | 5:0396de26b449 | 10 | // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki |
MikamiUitOpen | 0:6c67a9387981 | 11 | //------------------------------------------------------------ |
MikamiUitOpen | 0:6c67a9387981 | 12 | |
MikamiUitOpen | 5:0396de26b449 | 13 | #include "ADC_BuiltIn.hpp" // for ADC not using interrupt |
MikamiUitOpen | 5:0396de26b449 | 14 | #include "DAC_MCP4921.hpp" // for DAC MCP4921, MCP4922 |
MikamiUitOpen | 0:6c67a9387981 | 15 | #include "ACM1602NI.hpp" // for LCD display |
MikamiUitOpen | 0:6c67a9387981 | 16 | #include "Rosenberg.hpp" // Glottal source |
MikamiUitOpen | 0:6c67a9387981 | 17 | #include "Resonator.hpp" // Resonator corresponding to vocal tract |
MikamiUitOpen | 0:6c67a9387981 | 18 | #include "Radiator.hpp" // Radiator from mouth |
MikamiUitOpen | 5:0396de26b449 | 19 | using namespace Mikami; |
MikamiUitOpen | 5:0396de26b449 | 20 | |
MikamiUitOpen | 5:0396de26b449 | 21 | // ACM1602Ni を使う場合は次の define 文をコメントにすること |
MikamiUitOpen | 5:0396de26b449 | 22 | #define AQM1602 |
MikamiUitOpen | 0:6c67a9387981 | 23 | |
MikamiUitOpen | 5:0396de26b449 | 24 | #ifdef AQM1602 |
MikamiUitOpen | 5:0396de26b449 | 25 | #include "AQM1602.hpp" |
MikamiUitOpen | 5:0396de26b449 | 26 | Aqm1602 Lcd_; |
MikamiUitOpen | 5:0396de26b449 | 27 | #else |
MikamiUitOpen | 5:0396de26b449 | 28 | #include "ACM1602NI.hpp" |
MikamiUitOpen | 5:0396de26b449 | 29 | Acm1602Ni Lcd_; |
MikamiUitOpen | 5:0396de26b449 | 30 | #endif |
MikamiUitOpen | 0:6c67a9387981 | 31 | |
MikamiUitOpen | 0:6c67a9387981 | 32 | const int FS_ = 8000; // Sampling frequency: 8 kHz |
MikamiUitOpen | 5:0396de26b449 | 33 | ADC_BuiltIn adc_(A2, FS_); // for AD |
MikamiUitOpen | 5:0396de26b449 | 34 | DAC_MCP4921 myDac_; // for DA |
MikamiUitOpen | 5:0396de26b449 | 35 | |
MikamiUitOpen | 5:0396de26b449 | 36 | DigitalIn uButton_(USER_BUTTON); |
MikamiUitOpen | 5:0396de26b449 | 37 | BusIn busSw_(D2, D3, D4, D5); |
MikamiUitOpen | 0:6c67a9387981 | 38 | |
MikamiUitOpen | 0:6c67a9387981 | 39 | const int N_VWL_ = 5; // 母音の種類の数 |
MikamiUitOpen | 0:6c67a9387981 | 40 | const int N_RSN_ = 3; // 共振器の数 |
MikamiUitOpen | 0:6c67a9387981 | 41 | |
MikamiUitOpen | 0:6c67a9387981 | 42 | // フォルマント周波数,帯域幅のデータ:{周波数, 帯域幅} |
MikamiUitOpen | 0:6c67a9387981 | 43 | const Resonator::FrBw c_[N_VWL_][N_RSN_] = |
MikamiUitOpen | 0:6c67a9387981 | 44 | {{ {654, 50}, {1060, 55}, {2375, 60} }, // ア |
MikamiUitOpen | 0:6c67a9387981 | 45 | { {302, 40}, {2057, 60}, {3034, 65} }, // イ |
MikamiUitOpen | 0:6c67a9387981 | 46 | { {375, 45}, {1208, 55}, {2165, 60} }, // ウ |
MikamiUitOpen | 0:6c67a9387981 | 47 | { {541, 50}, {1784, 60}, {2452, 60} }, // エ |
MikamiUitOpen | 0:6c67a9387981 | 48 | { {458, 45}, { 807, 50}, {2379, 60} }}; // オ |
MikamiUitOpen | 0:6c67a9387981 | 49 | |
MikamiUitOpen | 0:6c67a9387981 | 50 | int main() |
MikamiUitOpen | 0:6c67a9387981 | 51 | { |
MikamiUitOpen | 0:6c67a9387981 | 52 | // 基本周波数の可変範囲を決める定数(100 ~ 180 Hz の範囲) |
MikamiUitOpen | 0:6c67a9387981 | 53 | const float F0_COEF = 50.0f/4095.0f; // 範囲を決める定数 |
MikamiUitOpen | 0:6c67a9387981 | 54 | const float F0_MIN = 100.0f; // 最低の基本周波数 |
MikamiUitOpen | 0:6c67a9387981 | 55 | |
MikamiUitOpen | 5:0396de26b449 | 56 | Rosenberg g(100, FS_, 2.5f); // 声帯波発生用オブジェクト初期化 |
MikamiUitOpen | 0:6c67a9387981 | 57 | // 基本周波数:100 Hz |
MikamiUitOpen | 0:6c67a9387981 | 58 | Resonator rs[N_RSN_]; // 共振器用オブジェクト配列の宣言 |
MikamiUitOpen | 0:6c67a9387981 | 59 | Radiator rd; // 放射の効果用オブジェクトの初期化 |
MikamiUitOpen | 0:6c67a9387981 | 60 | |
MikamiUitOpen | 0:6c67a9387981 | 61 | myDac_.ScfClockTim3(336000); // cutoff frequency: 3.36 kHz |
MikamiUitOpen | 0:6c67a9387981 | 62 | |
MikamiUitOpen | 5:0396de26b449 | 63 | busSw_.mode(PullDown); |
MikamiUitOpen | 5:0396de26b449 | 64 | Lcd_.Clear(); |
MikamiUitOpen | 5:0396de26b449 | 65 | Lcd_.WriteStringXY("Synthetic Vowel", 0, 0); |
MikamiUitOpen | 1:aab9254a774d | 66 | |
MikamiUitOpen | 0:6c67a9387981 | 67 | while (true) |
MikamiUitOpen | 0:6c67a9387981 | 68 | { |
MikamiUitOpen | 5:0396de26b449 | 69 | int sw = busSw_.read(); |
MikamiUitOpen | 5:0396de26b449 | 70 | if (sw > 5) sw = 5; |
MikamiUitOpen | 5:0396de26b449 | 71 | |
MikamiUitOpen | 5:0396de26b449 | 72 | char str[4] = {'/', 0xB0+sw, '/', NULL}; |
MikamiUitOpen | 5:0396de26b449 | 73 | Lcd_.WriteStringXY(str, 0, 1); // -アイウエオ |
MikamiUitOpen | 5:0396de26b449 | 74 | |
MikamiUitOpen | 5:0396de26b449 | 75 | // 共振器の準備 |
MikamiUitOpen | 5:0396de26b449 | 76 | if (sw > 0) |
MikamiUitOpen | 5:0396de26b449 | 77 | for (int k=0; k<N_RSN_; k++) |
MikamiUitOpen | 5:0396de26b449 | 78 | rs[k] = Resonator(c_[sw-1][k], FS_); |
MikamiUitOpen | 5:0396de26b449 | 79 | |
MikamiUitOpen | 5:0396de26b449 | 80 | for (int n=0; n<4000; n++) |
MikamiUitOpen | 0:6c67a9387981 | 81 | { |
MikamiUitOpen | 0:6c67a9387981 | 82 | uint16_t adVal = adc_.Read_u16(); // Read from A2 |
MikamiUitOpen | 0:6c67a9387981 | 83 | float f0 = adVal*F0_COEF + F0_MIN; |
MikamiUitOpen | 0:6c67a9387981 | 84 | g.SetPeriod(f0); // 基本周波数を設定 |
MikamiUitOpen | 0:6c67a9387981 | 85 | |
MikamiUitOpen | 0:6c67a9387981 | 86 | //----------------------------------------------- |
MikamiUitOpen | 5:0396de26b449 | 87 | // ここで合成母音を発生している |
MikamiUitOpen | 0:6c67a9387981 | 88 | float vn = g.Execute(); // 合成声帯波発生 |
MikamiUitOpen | 0:6c67a9387981 | 89 | if (sw != 0) |
MikamiUitOpen | 0:6c67a9387981 | 90 | for (int k=0; k<N_RSN_; k++) |
MikamiUitOpen | 0:6c67a9387981 | 91 | vn = rs[k].Execute(vn); // 声道の効果 |
MikamiUitOpen | 0:6c67a9387981 | 92 | float yn = rd.Execute(vn); // 放射の効果 |
MikamiUitOpen | 0:6c67a9387981 | 93 | //----------------------------------------------- |
MikamiUitOpen | 5:0396de26b449 | 94 | |
MikamiUitOpen | 2:6a0a8374b4ee | 95 | myDac_.Write(yn); // Write to DAC |
MikamiUitOpen | 0:6c67a9387981 | 96 | } |
MikamiUitOpen | 5:0396de26b449 | 97 | |
MikamiUitOpen | 5:0396de26b449 | 98 | // ユーザボタンが押されるまで待つ |
MikamiUitOpen | 5:0396de26b449 | 99 | while (uButton_ == 1) {} |
MikamiUitOpen | 5:0396de26b449 | 100 | Lcd_.ClearLine(1); |
MikamiUitOpen | 5:0396de26b449 | 101 | } |
MikamiUitOpen | 0:6c67a9387981 | 102 | } |