![](/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
Revision 5:0396de26b449, committed 2015-07-25
- Comitter:
- MikamiUitOpen
- Date:
- Sat Jul 25 07:10:11 2015 +0000
- Parent:
- 4:dd2ec72068d0
- Commit message:
- 6
Changed in this revision
diff -r dd2ec72068d0 -r 0396de26b449 Radiator.hpp --- a/Radiator.hpp Wed Dec 17 08:22:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -//------------------------------------------------------------------------------ -// 口からの放射の効果(ヘッダ) -// 作成者:三上直樹,2013/11/26 作成,(c)三上直樹 2013 -//------------------------------------------------------------------------------ - -#include "mbed.h" - -#ifndef RADIATOR_HPP -#define RADIATOR_HPP - -namespace Mikami -{ - class Radiator - { - private: - const float C1_; - float xnM1_; - - // コピー・コンストラクタの使用禁止 - Radiator(const Radiator& g); - // 代入演算子の使用禁止 - Radiator& operator=(const Radiator& g); - - public: - // デフォルト・コンストラクタ - explicit Radiator(float c1 = 1.0f) : C1_(c1) { Clear(); } - - // 差分に対応する処理の実行 - float Execute(float xin) - { - float yn = xin - C1_*xnM1_; - xnM1_ = xin; // x[n-1] ← x[n] - return yn; - } - - // 内部の遅延器のクリア - void Clear() { xnM1_ = 0; } - }; -} -#endif // RADIATOR_HPP
diff -r dd2ec72068d0 -r 0396de26b449 Resonator.cpp --- a/Resonator.cpp Wed Dec 17 08:22:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -//------------------------------------------------------------------------------ -// 音声合成で使う共振器 -// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013 -//------------------------------------------------------------------------------ - -#include "Resonator.hpp" - -namespace Mikami -{ - // コンストラクタに共通な初期化 - void Resonator::Initialize(float fr, float bw, float fs) - { - if (piT_ == 0) piT_ = 3.14159265f/fs; - Set(fr, bw); - Clear(); - } - - // 共振器のパラメータの設定 - void Resonator::Set(float fr, float bw) - { - a1_ = 2.0f*exp(-piT_*bw)*cos(2.0f*piT_*fr); - a2_ = -exp(-2.0f*piT_*bw); - b0_ = 1.0f - a1_ - a2_; - } - - // 共振器に対応する処理の実行 - float Resonator::Execute(float xin) - { - float ym = a1_*yn1_ + a2_*yn2_ + b0_*xin; - yn2_ = yn1_; // 遅延器のデータの移動 - yn1_ = ym; // 遅延器のデータの移動 - return ym; - } - - // "π/標本化周波数" の値に対応する実体 - float Resonator::piT_ = 0; -} -
diff -r dd2ec72068d0 -r 0396de26b449 Resonator.hpp --- a/Resonator.hpp Wed Dec 17 08:22:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// 音声合成で使う共振器(ヘッダ) -// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013 -//------------------------------------------------------------------------------ - -#include "mbed.h" - -#ifndef RESONATOR_HPP -#define RESONATOR_HPP - -namespace Mikami -{ - class Resonator - { - private: - static float piT_; - float a1_, a2_, b0_; - float yn1_, yn2_; - - // コンストラクタに共通な初期化 - void Initialize(float fr, float bw, float fs); - - public: - // 共振周波数と帯域幅に対応する構造体 - struct FrBw { float fr, bw; }; - - // デフォルト・コンストラクタ - Resonator() {} - - // 初期化を行うコンストラクタ - Resonator(float fr, float bw, float fs) - { Initialize(fr, bw, fs); } - - // 初期化を行うコンストラクタ(構造体使用) - Resonator(FrBw fb, float fs) - { Initialize(fb.fr, fb.bw, fs); } - - // 共振器のパラメータの設定 - void Set(float fr, float bw); - - // 共振器のパラメータの設定(構造体使用) - void Set(FrBw fb) { Set(fb.fr, fb.bw); } - - // 内部の遅延器をクリア - void Clear() { yn1_ = 0; yn2_ = 0; } - - // 共振器に対応する処理の実行 - float Execute(float xin); - }; -} -#endif // RESONATOR_HPP -
diff -r dd2ec72068d0 -r 0396de26b449 Rosenberg.hpp --- a/Rosenberg.hpp Wed Dec 17 08:22:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// 声帯波の合成 ― Rosenberg 波(ヘッダ) -// 作成者:三上直樹,2013/10/27 作成,(c)三上直樹 2013 -//------------------------------------------------------------------------------ - -#include "mbed.h" - -#ifndef ROSENBERG_HPP -#define ROSENBERGL_HPP - -namespace Mikami -{ - class Rosenberg - { - private: - const float DT_; - - float period_, t1_, t2_, t_, amp_; - - // コピー・コンストラクタの使用禁止 - Rosenberg(const Rosenberg& g); - // 代入演算子の使用禁止 - Rosenberg& operator=(const Rosenberg& g); - - public: - // 初期化を行うコンストラクタ - // f0: 基本周波数 - // fs: 標本化周波数 - // amp: 振幅 - Rosenberg(float f0, float fs, float amp) - : DT_(1.0f/fs), t_(0), amp_(amp) - { SetPeriod(f0); } - - // 基本周期の再設定 - void SetPeriod(float f0) - { - period_ = 1.0f/f0; - t1_ = 0.4f/f0; - t2_ = 0.16f/f0; - } - - // 振幅の再設定 - void SetAmplitude(float amp) { amp_ = amp; } - - // t_ = 0 に設定 - void Reset() { t_ = 0; } - - // Rosengerg 波の計算 - // amp: 振幅 - float Execute() - { - float g = 0; - - if (t_ < t1_) - { - float x = t_/t1_; - g = amp_*(3.0f - 2.0f*x)*x*x; - } - if ((t_ >= t1_) && (t_ < t1_+t2_)) - { - float x = (t_ - t1_)/t2_; - g = amp_*(1.0f - x*x); - } - - if ((t_+=DT_) > period_) t_ -= period_; - - return g; - } - }; -} -#endif // ROSENBERG_HPP
diff -r dd2ec72068d0 -r 0396de26b449 Synthesizer/Radiator.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synthesizer/Radiator.hpp Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,40 @@ +//------------------------------------------------------------------------------ +// 口からの放射の効果(ヘッダ) +// 作成者:三上直樹,2013/11/26 作成,(c)三上直樹 2013 +//------------------------------------------------------------------------------ + +#include "mbed.h" + +#ifndef RADIATOR_HPP +#define RADIATOR_HPP + +namespace Mikami +{ + class Radiator + { + private: + const float C1_; + float xnM1_; + + // コピー・コンストラクタの使用禁止 + Radiator(const Radiator& g); + // 代入演算子の使用禁止 + Radiator& operator=(const Radiator& g); + + public: + // デフォルト・コンストラクタ + explicit Radiator(float c1 = 1.0f) : C1_(c1) { Clear(); } + + // 差分に対応する処理の実行 + float Execute(float xin) + { + float yn = xin - C1_*xnM1_; + xnM1_ = xin; // x[n-1] ← x[n] + return yn; + } + + // 内部の遅延器のクリア + void Clear() { xnM1_ = 0; } + }; +} +#endif // RADIATOR_HPP
diff -r dd2ec72068d0 -r 0396de26b449 Synthesizer/Resonator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synthesizer/Resonator.cpp Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// 音声合成で使う共振器 +// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013 +//------------------------------------------------------------------------------ + +#include "Resonator.hpp" + +namespace Mikami +{ + // コンストラクタに共通な初期化 + void Resonator::Initialize(float fr, float bw, float fs) + { + if (piT_ == 0) piT_ = 3.14159265f/fs; + Set(fr, bw); + Clear(); + } + + // 共振器のパラメータの設定 + void Resonator::Set(float fr, float bw) + { + a1_ = 2.0f*exp(-piT_*bw)*cos(2.0f*piT_*fr); + a2_ = -exp(-2.0f*piT_*bw); + b0_ = 1.0f - a1_ - a2_; + } + + // 共振器に対応する処理の実行 + float Resonator::Execute(float xin) + { + float ym = a1_*yn1_ + a2_*yn2_ + b0_*xin; + yn2_ = yn1_; // 遅延器のデータの移動 + yn1_ = ym; // 遅延器のデータの移動 + return ym; + } + + // "π/標本化周波数" の値に対応する実体 + float Resonator::piT_ = 0; +} +
diff -r dd2ec72068d0 -r 0396de26b449 Synthesizer/Resonator.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synthesizer/Resonator.hpp Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +// 音声合成で使う共振器(ヘッダ) +// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013 +//------------------------------------------------------------------------------ + +#include "mbed.h" + +#ifndef RESONATOR_HPP +#define RESONATOR_HPP + +namespace Mikami +{ + class Resonator + { + private: + static float piT_; + float a1_, a2_, b0_; + float yn1_, yn2_; + + // コンストラクタに共通な初期化 + void Initialize(float fr, float bw, float fs); + + public: + // 共振周波数と帯域幅に対応する構造体 + struct FrBw { float fr, bw; }; + + // デフォルト・コンストラクタ + Resonator() {} + + // 初期化を行うコンストラクタ + Resonator(float fr, float bw, float fs) + { Initialize(fr, bw, fs); } + + // 初期化を行うコンストラクタ(構造体使用) + Resonator(FrBw fb, float fs) + { Initialize(fb.fr, fb.bw, fs); } + + // 共振器のパラメータの設定 + void Set(float fr, float bw); + + // 共振器のパラメータの設定(構造体使用) + void Set(FrBw fb) { Set(fb.fr, fb.bw); } + + // 内部の遅延器をクリア + void Clear() { yn1_ = 0; yn2_ = 0; } + + // 共振器に対応する処理の実行 + float Execute(float xin); + }; +} +#endif // RESONATOR_HPP +
diff -r dd2ec72068d0 -r 0396de26b449 Synthesizer/Rosenberg.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synthesizer/Rosenberg.hpp Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// 声帯波の合成 ― Rosenberg 波(ヘッダ) +// 作成者:三上直樹,2013/10/27 作成,(c)三上直樹 2013 +//------------------------------------------------------------------------------ + +#include "mbed.h" + +#ifndef ROSENBERG_HPP +#define ROSENBERGL_HPP + +namespace Mikami +{ + class Rosenberg + { + private: + const float DT_; + + float period_, t1_, t2_, t_, amp_; + + // コピー・コンストラクタの使用禁止 + Rosenberg(const Rosenberg& g); + // 代入演算子の使用禁止 + Rosenberg& operator=(const Rosenberg& g); + + public: + // 初期化を行うコンストラクタ + // f0: 基本周波数 + // fs: 標本化周波数 + // amp: 振幅 + Rosenberg(float f0, float fs, float amp) + : DT_(1.0f/fs), t_(0), amp_(amp) + { SetPeriod(f0); } + + // 基本周期の再設定 + void SetPeriod(float f0) + { + period_ = 1.0f/f0; + t1_ = 0.4f/f0; + t2_ = 0.16f/f0; + } + + // 振幅の再設定 + void SetAmplitude(float amp) { amp_ = amp; } + + // t_ = 0 に設定 + void Reset() { t_ = 0; } + + // Rosengerg 波の計算 + // amp: 振幅 + float Execute() + { + float g = 0; + + if (t_ < t1_) + { + float x = t_/t1_; + g = amp_*(3.0f - 2.0f*x)*x*x; + } + if ((t_ >= t1_) && (t_ < t1_+t2_)) + { + float x = (t_ - t1_)/t2_; + g = amp_*(1.0f - x*x); + } + + if ((t_+=DT_) > period_) t_ -= period_; + + return g; + } + }; +} +#endif // ROSENBERG_HPP
diff -r dd2ec72068d0 -r 0396de26b449 UITDSP_ADDA.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UITDSP_ADDA.lib Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UITDSP_ADDA/#543daa087bd5
diff -r dd2ec72068d0 -r 0396de26b449 UIT_ACM1602NI.lib --- a/UIT_ACM1602NI.lib Wed Dec 17 08:22:30 2014 +0000 +++ b/UIT_ACM1602NI.lib Sat Jul 25 07:10:11 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/MikamiUitOpen/code/UIT_ACM1602NI/#b911485a6f4d +http://mbed.org/users/MikamiUitOpen/code/UIT_ACM1602NI/#b7c761c179c9
diff -r dd2ec72068d0 -r 0396de26b449 UIT_ADDA.lib --- a/UIT_ADDA.lib Wed Dec 17 08:22:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/MikamiUitOpen/code/UIT_ADDA/#479d18a09e87
diff -r dd2ec72068d0 -r 0396de26b449 UIT_AQM1602.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UIT_AQM1602.lib Sat Jul 25 07:10:11 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UIT_AQM1602/#c943f05b7843
diff -r dd2ec72068d0 -r 0396de26b449 main.cpp --- 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); + } } -
diff -r dd2ec72068d0 -r 0396de26b449 mbed.bld --- a/mbed.bld Wed Dec 17 08:22:30 2014 +0000 +++ b/mbed.bld Sat Jul 25 07:10:11 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/bad568076d81 \ No newline at end of file