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

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed

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);
+    }   
 }
-