Vowel synthesizer using digital resonators. This program can run without LCD display. ディジタル共振器を使った合成母音ジェネレータ.LCD表示器なしでも動く.

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed

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?

UserRevisionLine numberNew 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