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

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Sat Jul 25 07:10:11 2015 +0000
Parent:
4:dd2ec72068d0
Commit message:
6

Changed in this revision

Radiator.hpp Show diff for this revision Revisions of this file
Resonator.cpp Show diff for this revision Revisions of this file
Resonator.hpp Show diff for this revision Revisions of this file
Rosenberg.hpp Show diff for this revision Revisions of this file
Synthesizer/Radiator.hpp Show annotated file Show diff for this revision Revisions of this file
Synthesizer/Resonator.cpp Show annotated file Show diff for this revision Revisions of this file
Synthesizer/Resonator.hpp Show annotated file Show diff for this revision Revisions of this file
Synthesizer/Rosenberg.hpp Show annotated file Show diff for this revision Revisions of this file
UITDSP_ADDA.lib Show annotated file Show diff for this revision Revisions of this file
UIT_ACM1602NI.lib Show annotated file Show diff for this revision Revisions of this file
UIT_ADDA.lib Show diff for this revision Revisions of this file
UIT_AQM1602.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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