Vowel synthesizer using digital resonators. This program can run without LCD display. ディジタル共振器を使った合成母音ジェネレータ.LCD表示器なしでも動く.
Dependencies: UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed
main.cpp@4:dd2ec72068d0, 2014-12-17 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Wed Dec 17 08:22:30 2014 +0000
- Revision:
- 4:dd2ec72068d0
- Parent:
- 2:6a0a8374b4ee
- Child:
- 5:0396de26b449
5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:6c67a9387981 | 1 | //------------------------------------------------------------ |
MikamiUitOpen | 0:6c67a9387981 | 2 | // Vowel synthesizer using digital resonators |
MikamiUitOpen | 0:6c67a9387981 | 3 | // sw: 1, 2, 3, 4, 5 => /a/, /i/, /u/, /e/, /o/ |
MikamiUitOpen | 0:6c67a9387981 | 4 | // sw: 0 => Without resonator |
MikamiUitOpen | 4:dd2ec72068d0 | 5 | // 2014/12/17, Copyright (c) 2014 MIKAMI, Naoki |
MikamiUitOpen | 0:6c67a9387981 | 6 | //------------------------------------------------------------ |
MikamiUitOpen | 0:6c67a9387981 | 7 | |
MikamiUitOpen | 0:6c67a9387981 | 8 | #include "ADC_Base.hpp" // for ADC not using interrupt |
MikamiUitOpen | 0:6c67a9387981 | 9 | #include "DAC_MCP4922.hpp" // for DAC MCP4922 |
MikamiUitOpen | 0:6c67a9387981 | 10 | #include "ACM1602NI.hpp" // for LCD display |
MikamiUitOpen | 0:6c67a9387981 | 11 | #include "Rosenberg.hpp" // Glottal source |
MikamiUitOpen | 0:6c67a9387981 | 12 | #include "Resonator.hpp" // Resonator corresponding to vocal tract |
MikamiUitOpen | 0:6c67a9387981 | 13 | #include "Radiator.hpp" // Radiator from mouth |
MikamiUitOpen | 1:aab9254a774d | 14 | #include "ACM1602NI.hpp" // for LCD display |
MikamiUitOpen | 0:6c67a9387981 | 15 | |
MikamiUitOpen | 0:6c67a9387981 | 16 | using namespace Mikami; |
MikamiUitOpen | 0:6c67a9387981 | 17 | |
MikamiUitOpen | 0:6c67a9387981 | 18 | const int FS_ = 8000; // Sampling frequency: 8 kHz |
MikamiUitOpen | 0:6c67a9387981 | 19 | ADC_Base adc_(A2, FS_); // for AD |
MikamiUitOpen | 0:6c67a9387981 | 20 | DAC_MCP4922 myDac_; // for DA |
MikamiUitOpen | 0:6c67a9387981 | 21 | DigitalIn sw1_(D2, PullDown); |
MikamiUitOpen | 0:6c67a9387981 | 22 | DigitalIn sw2_(D3, PullDown); |
MikamiUitOpen | 0:6c67a9387981 | 23 | DigitalIn sw4_(D4, PullDown); |
MikamiUitOpen | 0:6c67a9387981 | 24 | DigitalIn sw8_(D5, PullDown); |
MikamiUitOpen | 0:6c67a9387981 | 25 | |
MikamiUitOpen | 0:6c67a9387981 | 26 | const int N_VWL_ = 5; // 母音の種類の数 |
MikamiUitOpen | 0:6c67a9387981 | 27 | const int N_RSN_ = 3; // 共振器の数 |
MikamiUitOpen | 0:6c67a9387981 | 28 | |
MikamiUitOpen | 0:6c67a9387981 | 29 | // フォルマント周波数,帯域幅のデータ:{周波数, 帯域幅} |
MikamiUitOpen | 0:6c67a9387981 | 30 | const Resonator::FrBw c_[N_VWL_][N_RSN_] = |
MikamiUitOpen | 0:6c67a9387981 | 31 | {{ {654, 50}, {1060, 55}, {2375, 60} }, // ア |
MikamiUitOpen | 0:6c67a9387981 | 32 | { {302, 40}, {2057, 60}, {3034, 65} }, // イ |
MikamiUitOpen | 0:6c67a9387981 | 33 | { {375, 45}, {1208, 55}, {2165, 60} }, // ウ |
MikamiUitOpen | 0:6c67a9387981 | 34 | { {541, 50}, {1784, 60}, {2452, 60} }, // エ |
MikamiUitOpen | 0:6c67a9387981 | 35 | { {458, 45}, { 807, 50}, {2379, 60} }}; // オ |
MikamiUitOpen | 0:6c67a9387981 | 36 | |
MikamiUitOpen | 0:6c67a9387981 | 37 | int main() |
MikamiUitOpen | 0:6c67a9387981 | 38 | { |
MikamiUitOpen | 0:6c67a9387981 | 39 | // 基本周波数の可変範囲を決める定数(100 ~ 180 Hz の範囲) |
MikamiUitOpen | 0:6c67a9387981 | 40 | const float F0_COEF = 50.0f/4095.0f; // 範囲を決める定数 |
MikamiUitOpen | 0:6c67a9387981 | 41 | const float F0_MIN = 100.0f; // 最低の基本周波数 |
MikamiUitOpen | 0:6c67a9387981 | 42 | |
MikamiUitOpen | 0:6c67a9387981 | 43 | Rosenberg g(100, FS_, 3.0f); // 声帯波発生用オブジェクト初期化 |
MikamiUitOpen | 0:6c67a9387981 | 44 | // 基本周波数:100 Hz |
MikamiUitOpen | 0:6c67a9387981 | 45 | Resonator rs[N_RSN_]; // 共振器用オブジェクト配列の宣言 |
MikamiUitOpen | 0:6c67a9387981 | 46 | Radiator rd; // 放射の効果用オブジェクトの初期化 |
MikamiUitOpen | 0:6c67a9387981 | 47 | |
MikamiUitOpen | 0:6c67a9387981 | 48 | myDac_.ScfClockTim3(336000); // cutoff frequency: 3.36 kHz |
MikamiUitOpen | 0:6c67a9387981 | 49 | |
MikamiUitOpen | 1:aab9254a774d | 50 | Acm1602Ni lcd; // objetc for display using LCD |
MikamiUitOpen | 1:aab9254a774d | 51 | lcd.Clear(); |
MikamiUitOpen | 2:6a0a8374b4ee | 52 | lcd.WriteStringXY("Synthetic Vowel", 0, 0); |
MikamiUitOpen | 1:aab9254a774d | 53 | |
MikamiUitOpen | 0:6c67a9387981 | 54 | int sw = (sw8_ << 3) | (sw4_ << 2) | (sw2_ << 1) | sw1_; |
MikamiUitOpen | 0:6c67a9387981 | 55 | if (sw > 5) sw = 5; |
MikamiUitOpen | 1:aab9254a774d | 56 | |
MikamiUitOpen | 1:aab9254a774d | 57 | char str[4] = {'/', 0xB0+sw, '/', NULL}; |
MikamiUitOpen | 1:aab9254a774d | 58 | lcd.WriteStringXY(str, 0, 1); // -アイウエオ |
MikamiUitOpen | 0:6c67a9387981 | 59 | |
MikamiUitOpen | 0:6c67a9387981 | 60 | // 共振器の準備 |
MikamiUitOpen | 0:6c67a9387981 | 61 | if (sw > 0) |
MikamiUitOpen | 0:6c67a9387981 | 62 | for (int k=0; k<N_RSN_; k++) |
MikamiUitOpen | 0:6c67a9387981 | 63 | rs[k] = Resonator(c_[sw-1][k], FS_); |
MikamiUitOpen | 0:6c67a9387981 | 64 | |
MikamiUitOpen | 0:6c67a9387981 | 65 | int counter = 4000; // Length of output |
MikamiUitOpen | 0:6c67a9387981 | 66 | |
MikamiUitOpen | 0:6c67a9387981 | 67 | while (true) |
MikamiUitOpen | 0:6c67a9387981 | 68 | { |
MikamiUitOpen | 0:6c67a9387981 | 69 | if (counter > 0) |
MikamiUitOpen | 0:6c67a9387981 | 70 | { |
MikamiUitOpen | 0:6c67a9387981 | 71 | uint16_t adVal = adc_.Read_u16(); // Read from A2 |
MikamiUitOpen | 0:6c67a9387981 | 72 | float f0 = adVal*F0_COEF + F0_MIN; |
MikamiUitOpen | 0:6c67a9387981 | 73 | g.SetPeriod(f0); // 基本周波数を設定 |
MikamiUitOpen | 0:6c67a9387981 | 74 | |
MikamiUitOpen | 0:6c67a9387981 | 75 | //----------------------------------------------- |
MikamiUitOpen | 0:6c67a9387981 | 76 | |
MikamiUitOpen | 0:6c67a9387981 | 77 | float vn = g.Execute(); // 合成声帯波発生 |
MikamiUitOpen | 0:6c67a9387981 | 78 | if (sw != 0) |
MikamiUitOpen | 0:6c67a9387981 | 79 | for (int k=0; k<N_RSN_; k++) |
MikamiUitOpen | 0:6c67a9387981 | 80 | vn = rs[k].Execute(vn); // 声道の効果 |
MikamiUitOpen | 0:6c67a9387981 | 81 | float yn = rd.Execute(vn); // 放射の効果 |
MikamiUitOpen | 0:6c67a9387981 | 82 | |
MikamiUitOpen | 0:6c67a9387981 | 83 | //----------------------------------------------- |
MikamiUitOpen | 2:6a0a8374b4ee | 84 | myDac_.Write(yn); // Write to DAC |
MikamiUitOpen | 0:6c67a9387981 | 85 | |
MikamiUitOpen | 0:6c67a9387981 | 86 | counter--; |
MikamiUitOpen | 0:6c67a9387981 | 87 | } |
MikamiUitOpen | 0:6c67a9387981 | 88 | } |
MikamiUitOpen | 0:6c67a9387981 | 89 | } |
MikamiUitOpen | 0:6c67a9387981 | 90 |