Frequency shifter for DISCO-F746. Input: MEMS mic, Output: CN10 OUT. DISCO-F746 による周波数シフタ.入力:MEMS マイク,出力:CN10 OUT

Dependencies:   F746_GUI F746_SAI_IO mbed

main.cpp

Committer:
MikamiUitOpen
Date:
2018-03-19
Revision:
1:af3546588b73
Parent:
0:67554e1407a7

File content as of revision 1:af3546588b73:

//--------------------------------------------------------------
//  MEMS マイクの入力に対して周波数シフトを行う
//      Hilbert 変換フィルタを利用する方法
//
//  使用しているライブラリのリビジョン:
//          F746_GUI            Rev.33
//          F746_SAI_IO         Rev.12
//          mbed                Rev.161
//
//  2018/03/19, Copyright (c) 2018 MIKAMI, Naoki
//--------------------------------------------------------------

#include "InitializeGUI.hpp"
#include "SAI_InOut.hpp"
#include "FrequencyShifter.hpp"
#include "GuiChanger.hpp"
using namespace Mikami;

int main()
{
    const int FS = AUDIO_FREQUENCY_16K;    // 標本化周波数: 16 kHz
    // 入出力の準備
    SaiIO mySai(SaiIO::BOTH, 256, FS,
                INPUT_DEVICE_DIGITAL_MICROPHONE_2);

    ButtonGroup *onOff; // "ON", "OFF"
    ButtonGroup *menu;  // "THROUGH", "F_SHIFTER"
    SeekBar *barFqCh;   // シフトする周波数を設定するシークバー
    NumericLabel<int> *frqLabel;
    WaveformDisplay *displayIn, *displayOut;

    // GUI 部品の初期化
    InitializeGUI(onOff, menu, barFqCh, frqLabel, displayIn, displayOut);

    // 処理に応じて GUI 部品の状態を変更する関数の割り当て
    void (*fPtr[])(SeekBar*, NumericLabel<int>*)
        = { SetThrough, SetFrqShifter };
    ProcessingBase through;             // 0: 信号処理なしで出力
    FrqShifterHilbert shifter(FS, 100); // 1: 周波数シフト(シフトの初期値:100 Hz)

    ProcessingBase *func[2] = { &through, &shifter };

    Array<int16_t> snIn(mySai.GetLength());     // 入力波形表示で使用
    Array<int16_t> snOut(mySai.GetLength());    // 出力波形表示で使用

    mySai.RecordIn();   // 入力開始
    mySai.PlayOut();    // 出力開始
    mySai.PauseOut();   // 出力一時停止

    int menuNum = 0;
    while (true)
    {
        // On/OFF の設定
        int num;
        if (onOff->GetTouchedNumber(num))
        {
            if (num == 0) mySai.ResumeOut();    // 出力再開
            else          mySai.PauseOut();
        }

        // メニューにより GUI の状態を設定しなおす
        if (menu->GetTouchedNumber(menuNum))
            fPtr[menuNum](barFqCh, frqLabel);

        // 周波数シフトの値の設定
        if ( (menuNum == 1) && (barFqCh->Slide()) )
        {
            frqLabel->Draw(barFqCh->GetIntValue());
            shifter.SetFrequency(barFqCh->GetIntValue());
        }

        //---------------------------------------------
        // 1フレーム分の信号処理を行い,その結果を出力する
        if (mySai.IsCompleted())
        {
            for (int n=0; n<mySai.GetLength(); n++)
            {
                int16_t xL, xR;
                mySai.Input(xL, xR);
                int16_t xn = xL + xR;
                snIn[n] = xn;   // 表示用

                //-------------------------------------------------------
                int16_t yn = func[menuNum]->Execute(xn);    // 信号処理実行
                //-------------------------------------------------------

                mySai.Output(yn, yn);   // 左右チャンネルに同じ信号を出力
                snOut[n] = yn;  // 表示用
            }

            displayIn->Execute(snIn);   // 入力波形の表示
            displayOut->Execute(snOut); // 出力波形の表示
        }
        // 1フレーム分の信号処理はここまで
        //---------------------------------------------
    }
}