Synthesizer for Japanese five vowels with keyboard. 鍵盤と一緒になった日本語の5母音の合成器.

Dependencies:   BSP_DISCO_F746NG_patch_fixed BUTTON_GROUP LCD_DISCO_F746NG TS_DISCO_F746NG mbed

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Wed Feb 24 13:00:12 2016 +0000
Commit message:
1

Changed in this revision

BSP_DISCO_F746NG_patch_fixed.lib Show annotated file Show diff for this revision Revisions of this file
BUTTON_GROUP.lib Show annotated file Show diff for this revision Revisions of this file
LCD_DISCO_F746NG.lib Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/BSP_AudioOut_Overwrite.cpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/BSP_AudioOut_Overwrite.hpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Radiator.cpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Radiator.hpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Resonator.cpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Resonator.hpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Rosenberg.cpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/Rosenberg.hpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/sai_io_o.cpp Show annotated file Show diff for this revision Revisions of this file
MyClasses_Functions/sai_io_o.hpp Show annotated file Show diff for this revision Revisions of this file
TS_DISCO_F746NG.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 000000000000 -r a98746e7a170 BSP_DISCO_F746NG_patch_fixed.lib
--- /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
diff -r 000000000000 -r a98746e7a170 BUTTON_GROUP.lib
--- /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
diff -r 000000000000 -r a98746e7a170 LCD_DISCO_F746NG.lib
--- /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
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/BSP_AudioOut_Overwrite.cpp
--- /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);
+}
+
+
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/BSP_AudioOut_Overwrite.hpp
--- /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
+
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Radiator.cpp
--- /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;
+}
+
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Radiator.hpp
--- /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
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Resonator.cpp
--- /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
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Resonator.hpp
--- /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
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Rosenberg.cpp
--- /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;
+    }
+
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/Rosenberg.hpp
--- /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
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/sai_io_o.cpp
--- /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_;
+}
+
diff -r 000000000000 -r a98746e7a170 MyClasses_Functions/sai_io_o.hpp
--- /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
diff -r 000000000000 -r a98746e7a170 TS_DISCO_F746NG.lib
--- /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
diff -r 000000000000 -r a98746e7a170 main.cpp
--- /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;
+        }
+    }
+}
diff -r 000000000000 -r a98746e7a170 mbed.bld
--- /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