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

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed

main.cpp

Committer:
MikamiUitOpen
Date:
2014-12-02
Revision:
2:6a0a8374b4ee
Parent:
1:aab9254a774d
Child:
4:dd2ec72068d0

File content as of revision 2:6a0a8374b4ee:

//------------------------------------------------------------
// Vowel synthesizer using digital resonators
//      sw: 1, 2, 3, 4, 5 => /a/, /i/, /u/, /e/, /o/
//      sw: 0 => Without resonator
// 2014/12/02, Copyright (c) 2014 MIKAMI, Naoki
//------------------------------------------------------------

#include "ADC_Base.hpp"         // for ADC not using interrupt
#include "DAC_MCP4922.hpp"      // for DAC 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;

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

const int N_VWL_ = 5;   // 母音の種類の数
const int N_RSN_ = 3;   // 共振器の数

// フォルマント周波数,帯域幅のデータ:{周波数, 帯域幅}
const Resonator::FrBw c_[N_VWL_][N_RSN_] =
    {{ {654, 50}, {1060, 55}, {2375, 60} },     // ア
     { {302, 40}, {2057, 60}, {3034, 65} },     // イ
     { {375, 45}, {1208, 55}, {2165, 60} },     // ウ
     { {541, 50}, {1784, 60}, {2452, 60} },     // エ
     { {458, 45}, { 807, 50}, {2379, 60} }};    // オ

int main()
{
    // 基本周波数の可変範囲を決める定数(100 ~ 180 Hz の範囲)
    const float F0_COEF = 50.0f/4095.0f;    // 範囲を決める定数
    const float F0_MIN = 100.0f;            // 最低の基本周波数

    Rosenberg g(100, FS_, 3.0f);    // 声帯波発生用オブジェクト初期化
                                    // 基本周波数: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;

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