Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BSP_DISCO_F746NG_patch_fixed BUTTON_GROUP LCD_DISCO_F746NG TS_DISCO_F746NG mbed
Revision 0:a98746e7a170, committed 2016-02-24
- Comitter:
- MikamiUitOpen
- Date:
- Wed Feb 24 13:00:12 2016 +0000
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_DISCO_F746NG_patch_fixed.lib Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/the_sz/code/BSP_DISCO_F746NG_patch_fixed/#0094f74cb733
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BUTTON_GROUP.lib Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/BUTTON_GROUP/#af578b53ff0e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LCD_DISCO_F746NG.lib Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/LCD_DISCO_F746NG/#d44525b1de98
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/BSP_AudioOut_Overwrite.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,112 @@
+//--------------------------------------------------------------
+// Overwrite functuions and define calback functions
+// for functions in stm32746g_discovery_audio.cpp
+//--------------------------------------------------------------
+#include "BSP_AudioOut_Overwrite.hpp"
+
+// These three callback functions are modyfied by Mikami
+void BSP_AUDIO_OUT_HalfTransfer_CallBack()
+{
+ Mikami::SaiIO_O::FillBuffer1st();
+}
+
+void BSP_AUDIO_OUT_TransferComplete_CallBack()
+{
+ Mikami::SaiIO_O::FillBuffer2nd();
+}
+
+void BSP_AUDIO_OUT_Error_CallBack()
+{
+ Mikami::SaiIO_O::ErrorTrap();
+}
+
+//--------------------------------------------------------------
+// Followings are original by Nanase
+//--------------------------------------------------------------
+
+DMA_HandleTypeDef hdma_sai_tx;
+
+void AUDIO_OUT_SAIx_DMAx_IRQHandler()
+{
+ HAL_DMA_IRQHandler(&hdma_sai_tx);
+}
+
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+ //static DMA_HandleTypeDef hdma_sai_tx;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Enable SAI clock */
+ AUDIO_OUT_SAIx_CLK_ENABLE();
+
+ /* Enable GPIO clock */
+ AUDIO_OUT_SAIx_MCLK_ENABLE();
+ AUDIO_OUT_SAIx_SCK_SD_ENABLE();
+ AUDIO_OUT_SAIx_FS_ENABLE();
+
+ /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_FS_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ gpio_init_structure.Alternate = AUDIO_OUT_SAIx_SCK_AF;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable the DMA clock */
+ AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
+
+ if(hsai->Instance == AUDIO_OUT_SAIx)
+ {
+ /* Configure the hdma_saiTx handle parameters */
+ hdma_sai_tx.Init.Channel = AUDIO_OUT_SAIx_DMAx_CHANNEL;
+ hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
+ hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
+ hdma_sai_tx.Init.Mode = DMA_CIRCULAR;
+ hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
+
+ /* Deinitialize the Stream for new transfer */
+ HAL_DMA_DeInit(&hdma_sai_tx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_sai_tx);
+ }
+
+ /* SAI DMA IRQ Channel configuration */
+ HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyClasses_Functions/BSP_AudioOut_Overwrite.hpp Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,15 @@ +//-------------------------------------------------------------- +// Overwrite functuions and define calback function (Header) +// for functions in stm32746g_discovery_audio.cpp +//-------------------------------------------------------------- + +#ifndef F746_AUDIO_OUT_OVERWRITE_HPP +#define F746_AUDIO_OUT_OVERWRITE_HPP + +#include "stm32746g_discovery_audio.h" +#include "sai_io_o.hpp" + +void AUDIO_OUT_SAIx_DMAx_IRQHandler(); + +#endif // F746_AUDIO_OUT_OVERWRITE_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Radiator.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,15 @@
+//------------------------------------------------------------------------------
+// 口からの放射の効果
+// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#include "Radiator.hpp"
+
+// 差分に対応する処理の実行
+float Radiator::Execute(float xin)
+{
+ float yn = xin - c1_*xnM1_;
+ xnM1_ = xin; // x[n-1] ← x[n]
+ return yn;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Radiator.hpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+// 口からの放射の効果(ヘッダ)
+// 作成者:三上直樹,2013/11/26 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#ifndef RADIATOR_HPP
+#define RADIATOR_HPP
+
+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);
+
+ // 内部の遅延器のクリア
+ void Clear() { xnM1_ = 0; }
+};
+
+#endif // RADIATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Resonator.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,34 @@
+//------------------------------------------------------------------------------
+// 音声合成で使う共振器
+// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#include "Resonator.hpp"
+
+// コンストラクタに共通な初期化
+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*expf(-piT_*bw)*cosf(2.0f*piT_*fr);
+ a2_ = -expf(-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;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Resonator.hpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+// 音声合成で使う共振器(ヘッダ)
+// 作成者:三上直樹,2013/11/27 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#include "mbed.h"
+
+#ifndef RESONATOR_HPP
+#define RESONATOR_HPP
+
+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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Rosenberg.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+// 声帯波の合成 ― Rosenberg 波
+// 作成者:三上直樹,2013/10/27 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#include "Rosenberg.hpp"
+
+ // 基本周期の設定
+ void Rosenberg::SetPeriod(float f0)
+ {
+ period_ = 1.0f/f0;
+ t1_ = 0.4f/f0;
+ t2_ = 0.16f/f0;
+ }
+
+ // Rosengerg 波の計算
+ float Rosenberg::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;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/Rosenberg.hpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+// 声帯波の合成 ― Rosenberg 波(ヘッダ)
+// 作成者:三上直樹,2013/10/27 作成,(c)三上直樹 2013
+//------------------------------------------------------------------------------
+
+#ifndef ROSENBERG_HPP
+#define ROSENBERGL_HPP
+
+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); }
+
+ // 基本周期の再設定
+ // f0: 基本周波数
+ void SetPeriod(float f0);
+
+ // 振幅の再設定
+ void SetAmplitude(float amp) { amp_ = amp; }
+
+ // t_ = 0 に設定
+ void Reset() { t_ = 0; }
+
+ // Rosengerg 波の計算
+ float Execute();
+};
+
+#endif // ROSENBERG_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/sai_io_o.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------
+// SiaIO class for output
+// 2016/02/16, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "sai_io_o.hpp"
+
+namespace Mikami
+{
+ SaiIO_O::SaiIO_O(int size, int fs) : FS_(fs), tmpIndex_(0)
+ {
+ nData_ = size;
+ bufferSize_ = (size*2)*2;
+ outBuffer_ = new int16_t[bufferSize_];
+ tmp_ = new int16_t[size*2];
+ ClearOutBuffer();
+ xferred_ = false;
+ }
+
+ void SaiIO_O::InitCodecOut()
+ {
+ if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME_OUT_, FS_) == AUDIO_ERROR)
+ ErrorTrap();
+
+ NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ, (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler);
+ BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
+
+ if (BSP_AUDIO_OUT_Play((uint16_t *)outBuffer_,
+ bufferSize_*AUDIODATA_SIZE) == AUDIO_ERROR)
+ ErrorTrap();
+ }
+
+ bool SaiIO_O::IsXferred()
+ {
+ if (xferred_)
+ {
+ tmpIndex_ = 0;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ void SaiIO_O::Output(int16_t xL, int16_t xR)
+ {
+ tmp_[tmpIndex_++] = xL; // Left
+ tmp_[tmpIndex_++] = xR; // Right
+ }
+
+ void SaiIO_O::ClearOutBuffer()
+ {
+ for (int n=0; n<bufferSize_; n++) outBuffer_[n] = 0;
+ for (int n=0; n<bufferSize_/2; n++) tmp_[n] = 0;
+ }
+
+ void SaiIO_O::StartOutPlay()
+ {
+ if (BSP_AUDIO_OUT_Play((uint16_t *)outBuffer_,
+ bufferSize_*AUDIODATA_SIZE) == AUDIO_ERROR)
+ ErrorTrap();
+ }
+
+ void SaiIO_O::StopOutPlay()
+ {
+ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW))
+ ErrorTrap();
+ }
+
+ void SaiIO_O::ErrorTrap()
+ {
+ DigitalOut led1(LED1);
+ fprintf(stderr, "\r\n### ERROR\r\n");
+ while(true)
+ {
+ led1 = !led1;
+ wait_ms(250);
+ }
+ }
+
+ void SaiIO_O::FillBuffer(uint32_t offset)
+ {
+ int k = offset;
+ for (int n=0; n<nData_*2; n++)
+ outBuffer_[k++] = tmp_[n];
+ xferred_ = true;
+ }
+
+ // Instances for static variables
+ int32_t SaiIO_O::nData_;
+ int32_t SaiIO_O::bufferSize_;
+ int16_t* SaiIO_O::outBuffer_;
+ int16_t* SaiIO_O::tmp_;
+ __IO bool SaiIO_O::xferred_;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/sai_io_o.hpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------
+// SiaIO class for output (Header)
+// 2016/02/16, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_SAI_IO_HPP
+#define F746_SAI_IO_HPP
+
+#include "mbed.h"
+#include "stm32746g_discovery_audio.h"
+#include "BSP_AudioOut_Overwrite.hpp"
+
+namespace Mikami
+{
+ class SaiIO_O
+ {
+ public:
+ SaiIO_O(int size, int fs);
+
+ void InitCodecOut();
+
+ bool IsXferred();
+ void Output(int16_t xL, int16_t xR);
+
+ void ResetXferred() { xferred_ = false; }
+ int32_t GetLength() { return nData_; }
+
+ void ClearOutBuffer();
+ void StartOutPlay();
+ void StopOutPlay();
+ void OutPause() { BSP_AUDIO_OUT_Pause(); }
+ void OutResume() {BSP_AUDIO_OUT_Resume(); }
+
+ // These three member functions are called from
+ // callback functions in "BSP_AudioOut_Overwrite.cpp"
+
+ // Called form BSP_AUDIO_OUT_HalfTransfer_CallBack()
+ static void FillBuffer1st() { FillBuffer(0); }
+ // Called form BSP_AUDIO_OUT_TransferComplete_CallBack()
+ static void FillBuffer2nd() { FillBuffer(bufferSize_/2); }
+ // Also called form BSP_AUDIO_OUT_Error_CallBack()
+ static void ErrorTrap();
+
+ private:
+ const int FS_;
+ static const uint8_t VOLUME_OUT_ = 95;
+
+ static int32_t nData_;
+ static int32_t bufferSize_;
+
+ static int16_t* outBuffer_;
+ static int16_t* tmp_;
+
+ static __IO bool xferred_;
+
+ __IO int32_t tmpIndex_;
+
+ static void FillBuffer(uint32_t offset);
+ };
+}
+#endif // F746_SAI_IO_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TS_DISCO_F746NG.lib Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/ST/code/TS_DISCO_F746NG/#fe0cf5e2960f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Feb 24 13:00:12 2016 +0000
@@ -0,0 +1,171 @@
+//------------------------------------------------------------
+// 合成母音発生器+キーボード
+// Vowel synthesizer with keyboard
+// タッチしている母音に対応する音が出る
+// 黒鍵はサポートしていない
+//
+// 2016/02/24, Copyright (c) 2016 MIKAMI, Naoki
+//------------------------------------------------------------
+
+#include "button_group.hpp"
+#include "sai_io_o.hpp"
+#include "Rosenberg.hpp" // 合成声帯波用
+#include "Resonator.hpp" // 共振器用
+#include "Radiator.hpp" // 放射の効果用
+
+using namespace Mikami;
+
+const uint32_t N_DATA_ = 300;//1400;
+
+SaiIO_O mySai_(N_DATA_, I2S_AUDIOFREQ_16K);
+
+const int N_VWL_ = 5; // 母音の種類の数
+const int N_RSN_ = 3; // 共振器の数
+
+// フォルマント周波数,帯域幅のデータ:{周波数, 帯域幅}
+const Resonator::FrBw FORMANT_[N_VWL_][N_RSN_] =
+ {{ {654, 50}, {1060, 55}, {2375, 60} }, // ア
+ { {302, 40}, {2057, 60}, {3004, 65} }, // イ
+ { {375, 45}, {1208, 55}, {2165, 60} }, // ウ
+ { {541, 50}, {1784, 60}, {2452, 60} }, // エ
+ { {458, 45}, { 807, 50}, {2379, 60} }}; // オ
+
+int main()
+{
+ const float FS = I2S_AUDIOFREQ_16K; // 標本化周波数: 16 kHz
+ const float F0 = 125.0f; // 基本周波数:125 Hz
+ const float A0 = 10000.0f; // 声帯波の振幅
+ const float A0M[N_VWL_] = // 声帯波の倍率
+ { 1.0f, 3.0f, 2.0f, 1.0f, 1.0f };
+
+ Rosenberg gs(F0, FS, A0); // 声帯波発生用オブジェクト初期化
+ Resonator rs[N_RSN_]; // 共振器用オブジェクト配列の宣言
+ Radiator rd(0.8f); // 放射の効果用オブジェクトの初期化
+
+ LCD_DISCO_F746NG lcd; // LCD 用オブジェクト
+ const uint32_t BACK_COLOR = 0xFF006A6C; // Teal green
+ const uint32_t TOUCHED_COLOR = 0xFF7F7FFF;
+ const uint32_t ORIGINAL_COLOR = 0xFF0068B7;
+
+ lcd.Clear(BACK_COLOR);
+ lcd.SetBackColor(BACK_COLOR);
+ lcd.SetTextColor(LCD_COLOR_WHITE);
+ lcd.SetFont(&Font20);
+ lcd.DisplayStringAt(0, 10, (uint8_t *)"Vowel Synthesizer", CENTER_MODE);
+
+ TS_DISCO_F746NG ts; // タッチパネル用オブジェクト
+ const string FIVE_VOEWLS[N_VWL_] = {"a", "i", "u", "e", "o"};
+ ButtonGroup vowel(lcd, ts, 10, 40, 50, 40,
+ ORIGINAL_COLOR, BACK_COLOR,
+ N_VWL_, FIVE_VOEWLS, 0, 5, 1, Font20);
+ vowel.Draw(0, TOUCHED_COLOR);
+
+ // 白鍵用
+ const string NO_CHAR[8] = {"", "", "", "", "", "", "", ""};
+ const int X0S = 90;
+ const int Y0S = 120;
+ const int WIDTH = 43;
+ ButtonGroup scale(lcd, ts, X0S, Y0S, WIDTH, 140,
+ LCD_COLOR_WHITE, BACK_COLOR,
+ 8, NO_CHAR, 5, 0, 8);
+
+ const float F_DO = 110.0f*powf(2, 3.0f/12.0f);
+ const float F_OCTAVE[8] =
+ { F_DO, F_DO*powf(2, 2.0f/12.0f),
+ F_DO*powf(2, 4.0f/12.0f), F_DO*powf(2, 5.0f/12.0f),
+ F_DO*powf(2, 7.0f/12.0f), F_DO*powf(2, 9.0f/12.0f),
+ F_DO*powf(2, 11.0f/12.0f), F_DO*2};
+
+ // 黒鍵用(音は出ない)
+ const int H0 = 70;
+ const int X0B = X0S+WIDTH/2+5;
+ const int WB = WIDTH-5;
+ const int MPOS = WIDTH + 5;
+ lcd.SetTextColor(LCD_COLOR_BLACK);
+ lcd.FillRect(X0B, Y0S, WB, H0);
+ lcd.FillRect(X0B+MPOS, Y0S, WB, H0);
+ lcd.FillRect(X0B+MPOS*3, Y0S, WB, H0);
+ lcd.FillRect(X0B+MPOS*4, Y0S, WB, H0);
+ lcd.FillRect(X0B+MPOS*5, Y0S, WB, H0);
+
+ // 男声,女声
+ const string MF[2] ={"M", "F"};
+ ButtonGroup mf(lcd, ts, X0S, 40, 60, 40,
+ ORIGINAL_COLOR, BACK_COLOR,
+ 2, MF, 5, 0, 2, Font20);
+ mf.Draw(0, TOUCHED_COLOR);
+
+ mySai_.InitCodecOut();
+ mySai_.OutPause();
+
+ float f0 = 1;
+ int mf0 = -1;
+ int sw0 = -1;
+ // 共振器の準備
+ for (int k=0; k<N_RSN_; k++)
+ rs[k] = Resonator(FORMANT_[0][k], FS);
+ // 声帯波の振幅設定
+ gs.SetAmplitude(A0*A0M[0]);
+
+ int dore0 = -1;
+ while (true)
+ {
+ int mfNow;
+ if (mf.GetTouchedNumber(mfNow, TOUCHED_COLOR))
+ {
+ if (mfNow != mf0)
+ {
+ // 男声,女声の切り替え
+ f0 = (mfNow == 0) ? 1.0f : 2.0f;
+ mf0 = mfNow;
+ }
+ }
+
+ int sw;
+ if (vowel.GetTouchedNumber(sw, TOUCHED_COLOR))
+ {
+ if (sw != sw0)
+ {
+ // 共振器の準備
+ for (int k=0; k<N_RSN_; k++)
+ rs[k] = Resonator(FORMANT_[sw][k], FS);
+ // 声帯波の振幅設定
+ gs.SetAmplitude(A0*A0M[sw]);
+
+ sw0 = sw;
+ }
+ }
+ int dore;
+ if (scale.GetTouchedNumber(dore)) // キーがタッチされている場合
+ {
+ if (dore != dore0) // タッチするキーが変わった場合
+ {
+ // 音階に対応する基本周期に設定
+ gs.SetPeriod(F_OCTAVE[dore]*f0);
+ dore0 = dore;
+ mySai_.OutResume();
+ }
+
+ if (mySai_.IsXferred())
+ {
+ for (int n=0; n<mySai_.GetLength(); n++)
+ {
+ float gn = gs.Execute(); // 合成声帯波発生
+ float vn = gn; // 声帯波を声道へ入力
+ for (int k=0; k<N_RSN_; k++)
+ vn = rs[k].Execute(vn); // 声道の効果
+ float yn = rd.Execute(vn); // 放射の効果
+
+ mySai_.Output(yn, gn);
+ }
+ mySai_.ResetXferred();
+ }
+ }
+ else // キーがタッチされていない場合
+ {
+ mySai_.OutPause();
+ mySai_.ClearOutBuffer();
+ dore0 = -1;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Feb 24 13:00:12 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/f141b2784e32 \ No newline at end of file