![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Vowel synthesizer using digital resonators. This program can run without LCD display. ディジタル共振器を使った合成母音ジェネレータ.LCD表示器なしでも動く.
Dependencies: UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed
Diff: main.cpp
- Revision:
- 5:0396de26b449
- Parent:
- 4:dd2ec72068d0
--- a/main.cpp Wed Dec 17 08:22:30 2014 +0000 +++ b/main.cpp Sat Jul 25 07:10:11 2015 +0000 @@ -1,27 +1,40 @@ //------------------------------------------------------------ -// Vowel synthesizer using digital resonators +// ディジタル共振器を使った母音発生器 // sw: 1, 2, 3, 4, 5 => /a/, /i/, /u/, /e/, /o/ // sw: 0 => Without resonator -// 2014/12/17, Copyright (c) 2014 MIKAMI, Naoki +// スイッチを切り替えてから Nucleo ボードのユーザボタン(青色)を +// 押すと違う合成母音が発生する. +// 母音の基本周波数は VR で変えられる(合成母音の音が出ている最中 +// でも変えられる) +// +// 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki //------------------------------------------------------------ -#include "ADC_Base.hpp" // for ADC not using interrupt -#include "DAC_MCP4922.hpp" // for DAC MCP4922 +#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 -#include "ACM1602NI.hpp" // for LCD display +using namespace Mikami; + +// ACM1602Ni を使う場合は次の define 文をコメントにすること +#define AQM1602 -using namespace Mikami; +#ifdef AQM1602 +#include "AQM1602.hpp" +Aqm1602 Lcd_; +#else +#include "ACM1602NI.hpp" +Acm1602Ni Lcd_; +#endif const int FS_ = 8000; // Sampling frequency: 8 kHz -ADC_Base adc_(A2, FS_); // for AD -DAC_MCP4922 myDac_; // for DA -DigitalIn sw1_(D2, PullDown); -DigitalIn sw2_(D3, PullDown); -DigitalIn sw4_(D4, PullDown); -DigitalIn sw8_(D5, PullDown); +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; // 共振器の数 @@ -40,51 +53,50 @@ const float F0_COEF = 50.0f/4095.0f; // 範囲を決める定数 const float F0_MIN = 100.0f; // 最低の基本周波数 - Rosenberg g(100, FS_, 3.0f); // 声帯波発生用オブジェクト初期化 + Rosenberg g(100, FS_, 2.5f); // 声帯波発生用オブジェクト初期化 // 基本周波数:100 Hz Resonator rs[N_RSN_]; // 共振器用オブジェクト配列の宣言 Radiator rd; // 放射の効果用オブジェクトの初期化 myDac_.ScfClockTim3(336000); // cutoff frequency: 3.36 kHz - Acm1602Ni lcd; // objetc for display using LCD - lcd.Clear(); - lcd.WriteStringXY("Synthetic Vowel", 0, 0); - - int sw = (sw8_ << 3) | (sw4_ << 2) | (sw2_ << 1) | sw1_; - if (sw > 5) sw = 5; + busSw_.mode(PullDown); + Lcd_.Clear(); + Lcd_.WriteStringXY("Synthetic Vowel", 0, 0); - 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_); - - int counter = 4000; // Length of output - while (true) { - if (counter > 0) + 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 - - counter--; } - } + + // ユーザボタンが押されるまで待つ + while (uButton_ == 1) {} + Lcd_.ClearLine(1); + } } -