Output the audio signal (*.bin) with filtering by IIR filter in the SD card using onboard CODEC. For *.wav file, F746_SD_WavPlayer and F746_SD_GraphicEqualiser are published on mbed. SD カードのオーディオ信号 (*.bin) を遮断周波数可変の IIR フィルタを通して,ボードに搭載されているCODEC で出力する.*.wav 形式のファイル用には,F746_SD_WavPlayer と F746_SD_GraphicEqualiser を mbed で公開している.
Dependencies: BSP_DISCO_F746NG_patch_fixed F746_GUI LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed
Revision 3:492cb0f68526, committed 2016-04-16
- Comitter:
- MikamiUitOpen
- Date:
- Sat Apr 16 13:53:26 2016 +0000
- Parent:
- 2:f963cb0d323f
- Child:
- 4:76aa20fb326a
- Commit message:
- 4
Changed in this revision
--- a/MyClasses_Functions/BSP_AudioOut_Overwrite.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -//-------------------------------------------------------------- -// 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); -} -
--- a/MyClasses_Functions/BSP_AudioOut_Overwrite.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -//-------------------------------------------------------------- -// 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
--- a/MyClasses_Functions/BilinearDesignLH.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -//------------------------------------------------------------------------------ -// Design of Butterworth LPF and HPF using bilinear transform -// -// 2016/03/31, Copyright (c) 2016 MIKAMI, Naoki -//------------------------------------------------------------------------------ - -#include "BilinearDesignLH.hpp" - -namespace Mikami -{ - // Execute design - // input - // fc: Cutoff frequency - // pb: Passband (LPF or HPF) - // output - // c : Coefficients for cascade structure - // g : Gain factor for cascade structure - void BilinearDesign::Execute(float fc, Type pb, Coefs c[], float& g) - { - Butterworth(); - Bilinear(fc); - ToCascade(pb); - GetGain(pb); - GetCoefs(c, g); - } - - // Get poles for Butterworth characteristics - void BilinearDesign::Butterworth() - { - float pi_2order = PI_/(2.0f*ORDER_); - for (int j=0; j<ORDER_/2; j++) // Pole with imaginary part >= 0 - { - float theta = (2.0f*j + 1.0f)*pi_2order; - sP_[j] = Complex(-cosf(theta), sinf(theta)); - } - } - - // Bilinear transform - // fc: Cutoff frequency - void BilinearDesign::Bilinear(float fc) - { - float wc = tanf(fc*PI_FS_); - for (int k=0; k<ORDER_/2; k++) - zP_[k] = (1.0f + wc*sP_[k])/(1.0f - wc*sP_[k]); - } - - // Convert to coefficients for cascade structure - void BilinearDesign::ToCascade(Type pb) - { - for (int j=0; j<ORDER_/2; j++) - { - ck_[j].a1 = 2.0f*real(zP_[j]); // a1m - ck_[j].a2 = -norm(zP_[j]); // a2m - ck_[j].b1 = (pb == LPF) ? 2.0f : -2.0f; // b1m - ck_[j].b2 = 1.0f; // b2m - } - } - - // Calculate gain factor - void BilinearDesign::GetGain(Type pb) - { - float u = (pb == LPF) ? 1.0f : -1.0f; - float g0 = 1.0f; - for (int k=0; k<ORDER_/2; k++) - g0 = g0*(1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)/ - (1.0f + (ck_[k].b1 + ck_[k].b2*u)*u); - gain_ = g0; - } - - // Get coefficients - void BilinearDesign::GetCoefs(Coefs c[], float& gain) - { - for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k]; - gain = gain_; - } -}
--- a/MyClasses_Functions/BilinearDesignLH.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -//------------------------------------------------------------------------------ -// Design of Butterworth LPF and HPF using bilinear transform -- Header -// -// 2016/03/31, Copyright (c) 2016 MIKAMI, Naoki -//------------------------------------------------------------------------------ - -#ifndef BILINEAR_BUTTERWORTH_HPP -#define BILINEAR_BUTTERWORTH_HPP - -#include "mbed.h" -#include <complex> // requisite - -namespace Mikami -{ - typedef complex<float> Complex; // define "Complex" - - class BilinearDesign - { - public: - struct Coefs { float a1, a2, b1, b2; }; - enum Type { LPF, HPF }; - - // Constructor - BilinearDesign(int order, float fs) - : PI_FS_(PI_/fs), ORDER_(order) - { - sP_ = new Complex[order/2]; - zP_ = new Complex[order/2]; - ck_ = new Coefs[order/2]; - } - - // Destractor - ~BilinearDesign() - { - delete[] sP_; - delete[] zP_; - delete[] ck_; - } - - // Execution of design - void Execute(float fc, Type pb, Coefs c[], float& g); - - private: - static const float PI_ = 3.1415926536f; - const float PI_FS_; - const int ORDER_; - - Complex* sP_; // Poles on s-plane - Complex* zP_; // Poles on z-plane - Coefs* ck_; // Coefficients of transfer function for cascade form - float gain_; // Gain factor for cascade form - - void Butterworth(); - void Bilinear(float fc); - void ToCascade(Type pb); - void GetGain(Type pb); - void GetCoefs(Coefs c[], float& gain); - }; -} -#endif // BILINEAR_BUTTERWORTH_HPP
--- a/MyClasses_Functions/Biquad.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -//-------------------------------------------------------------- -// 縦続形 IIR フィルタで使う 1D タイプの 2 次のフィルタ -// Biquad filter of 1D type for IIR filter of cascade structure -// このクラスでは,係数は実行中に書き換えられることを想定している -// -// u[n] = x[n] + a1*u[n-1] + a2*u[n-2] -// y[n] = u[n] + b1*u[n-1] + b2*u[n-2] -// x[n] : input signal -// y[n] : output signal -// b0 = 1 -// -// 2016/03/25, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#ifndef IIR_BIQUAD_HPP -#define IIR_BIQUAD_HPP - -#include "mbed.h" - -// 2nd order IIR filter -namespace Mikami -{ - class Biquad - { - public: - struct Coefs { float a1, a2, b1, b2; }; - - Biquad() {} // Default constructore - - Biquad(const Coefs ck) - { - SetCoefficients(ck); - Clear(); - } - - void SetCoefficients(const Coefs ck) - { - a1_ = ck.a1; - a2_ = ck.a2; - b1_ = ck.b1; - b2_ = ck.b2; - } - - float Execute(float xn) - { - float un = xn + a1_*un1_ + a2_*un2_; - float yn = un + b1_*un1_ + b2_*un2_; - - un2_ = un1_; - un1_ = un; - - return yn; - } - - void Clear() { un1_ = un2_ = 0; } - - private: - float a1_, a2_, b1_, b2_; - float un1_, un2_; - - // disallow copy constructor - Biquad(const Biquad&); - }; -} -#endif // IIR_BIQUAD_HPP
--- a/MyClasses_Functions/BiquadFrqRespDrawer.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -//-------------------------------------------------------------- -// BiquadFrqRespDrawer class (Derived class of FrqRespDrawer) -// 縦続形 IIR フィルタの周波数特性を描画するためのクラス -// このクラスは,FrqRespDrawer の派生クラス -// -// 2016/03/31, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#ifndef F746_BILINEAR_FRQ_RESP_DRAWER_HPP -#define F746_BILINEAR_FRQ_RESP_DRAWER_HPP - -#include "Biquad.hpp" -#include "FrquencyResponseDrawer.hpp" - -namespace Mikami -{ - class BiquadFrqRespDrawer : public FrqRespDrawer - { - public: - BiquadFrqRespDrawer(FrqRespDrawer::Params p) - : FrqRespDrawer(p) {} - - // 次数とフィルタの係数設定 - void SetParams(int order, float g0, Biquad::Coefs ck[]) - { - order_ = order; - g0_ = g0; - ck_ = ck; - } - - // 周波数応答の絶対値を返す関数, 引数: z^(-1) - virtual float AbsH_z(Complex u) - { - Complex h = g0_; - for (int k=0; k<order_/2; k++) - h = h*(1.0f + (ck_[k].b1 + ck_[k].b2*u)*u) - /((1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)); - return abs(h); - } - - private: - int order_; - float g0_; - Biquad::Coefs *ck_; - }; -} -#endif // F746_BILINEAR_FRQ_RESP_DRAWER_HPP
--- a/MyClasses_Functions/DesignerDrawer.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -//------------------------------------------------------------------------------ -// IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス -// -// 2016/04/08, Copyright (c) 2016 MIKAMI, Naoki -//------------------------------------------------------------------------------ - -#include "DesignerDrawer.hpp" - -namespace Mikami -{ - // Constructor - DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0, - uint16_t db10, int fs, int order, - float fc, uint16_t fL, uint16_t fH, - BilinearDesign::Type lpHp) - : lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()), - X0_(x0), Y0_(y0), DB10_(db10), ORDER_(order), - CURSOR_Y0_(y0+1-db10*6), CURSOR_LENGTH_(db10*6-1), - LOWER_F_(fL), HIGHER_F_(fH), - CURSOR_COLOR_(0xFFE000D0), CURSOR_TOUCHED_COLOR_(0xFFFF80FF) - { - drawerObj_ = new BiquadFrqRespDrawer( - FrqRespDrawer::Params(x0, 100.0f, 8000.0f, 150, - y0, -60, 0, db10, fs)); - - // 双一次 z 変換による IIR フィルタの設計 - designObj_ = new BilinearDesign(order, fs); - coefs_ = new BilinearDesign::Coefs[ORDER_/2]; - ck_ = (Biquad::Coefs *)coefs_; - - fC_ = fc; // 最初に与える遮断周波数 - designObj_->Execute(fC_, lpHp, coefs_, g0_); - drawerObj_->SetParams(ORDER_, g0_, ck_); - lblFrq_ = new NumericLabel<int>(110, 30); - - // 周波数特性の描画 - DrawResponse(); - - tp_ = new TouchPanelDetectorX( - drawerObj_->X(LOWER_F_), drawerObj_->X(HIGHER_F_), - CURSOR_Y0_, y0); - lp_ = lpHp; - cursorRedraw_ = false; - } - - DesignerDrawer::~DesignerDrawer() - { - delete tp_; - delete lblFrq_; - delete coefs_; - delete designObj_; - delete drawerObj_; - } - - // フィルタの再設計と周波数特性の再描画 - bool DesignerDrawer::ReDesignAndDraw(Biquad::Coefs *ck, float &g0, - BilinearDesign::Type lpHp) - { - bool changed = (lpHp != lp_) ? true : false; - bool tch = tp_->IsTouched(cursorX_, cursorX_); - if (tch || changed) - { - int newFc = Frq10(drawerObj_->PosToFrq(cursorX_)); - newFc = (newFc > HIGHER_F_) ? HIGHER_F_ : newFc; - if ((abs(newFc - fC_) >= 10) || changed) - { - fC_ = newFc; - lblFrq_->Draw("Cutoff frequency = %4d Hz", newFc); - designObj_->Execute(newFc, lpHp, coefs_, g0_); - GetCoefficients(ck, g0); - - drawerObj_->SetParams(ORDER_, g0_, ck_); - drawerObj_->Erase(); - drawerObj_->DrawAxis(); // 目盛線の描画 - drawerObj_->DrawGraph(); // 周波数特性のグラフのカーブを描画する - - if (tch) // カーソルの移動 - { - lcd_->SetTextColor(CURSOR_TOUCHED_COLOR_); - lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_); - } - cursorRedraw_ = true; - oldCursorX_ = cursorX_; - lp_ = lpHp; - return true; - } - } - - if (!tch && cursorRedraw_) // カーソルを元の色に戻す - { - lcd_->SetTextColor(CURSOR_COLOR_); - lcd_->DrawVLine(oldCursorX_, CURSOR_Y0_, CURSOR_LENGTH_); - cursorRedraw_ = false; - } - return false; - } - - // 周波数特性の描画 - void DesignerDrawer::DrawResponse() - { - lblFrq_->Draw("Cutoff frequency = %4d Hz", fC_); - DrawAxisNum(); // 目盛値の描画 - drawerObj_->DrawAxis(); // 目盛線の描画 - drawerObj_->DrawGraph(); // 周波数特性のカーブの描画 - - cursorX_ = drawerObj_->X(fC_); - lcd_->SetTextColor(CURSOR_COLOR_); - lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_); - } - - // フィルタ係数の取得 - void DesignerDrawer::GetCoefficients(Biquad::Coefs *c, float &g0) - { - for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k]; - g0 = g0_; - } - - // 周波数を 10, 20, 50, 100 Hz の倍数にする - int DesignerDrawer::Frq10(float f) - { - if (f < 1000) - return ((int)(f/10.0f + 0.5f))*10; - if (f < 2000) - return ((int)(f/20.0f + 0.5f))*20; - if (f < 3000) - return ((int)(f/50.0f + 0.5f))*50; - else - return ((int)(f/100.0f + 0.5f))*100; - } - - // 周波数特性の目盛線の描画 - void DesignerDrawer::DrawAxisNum() - { - const int16_t OFS = 6; - drawerObj_->DrawCharX(100, OFS, "0.1"); - drawerObj_->DrawCharX(300, OFS, "0.3"); - drawerObj_->DrawCharX(1000, OFS, "1.0"); - drawerObj_->DrawCharX(3000, OFS, "3.0"); - drawerObj_->DrawCharX(8000, OFS, "8.0"); - - Label l_frq(drawerObj_->X(900), Y0_+20, "Frequency [kHz]", - Label::CENTER); - drawerObj_->DrawNumericY(-24, -6, 4, 20, "%3d"); // 縦軸の目盛は 20 dB 間隔 - Label l_dB(X0_-24, Y0_-DB10_*6-20, "[dB]"); - } -}
--- a/MyClasses_Functions/DesignerDrawer.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -//------------------------------------------------------------------------------ -// IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス -- Header -// -// 2016/04/06, Copyright (c) 2016 MIKAMI, Naoki -//------------------------------------------------------------------------------ - -#ifndef F746_DISIGNER_AND_DRAWER_HPP -#define F746_DISIGNER_AND_DRAWER_HPP - -#include "NumericLabel.hpp" -#include "TouchPanelDetectorX.hpp" -#include "BiquadFrqRespDrawer.hpp" -#include "BilinearDesignLH.hpp" - -namespace Mikami -{ - class DesignerDrawer - { - public: - // Constructor - DesignerDrawer(uint16_t x0, uint16_t y0, - uint16_t db10, int fs, int order, - float fc, uint16_t fL, uint16_t fH, - BilinearDesign::Type lpHp); - - ~DesignerDrawer(); - - // フィルタの再設計と周波数特性の再描画 - bool ReDesignAndDraw(Biquad::Coefs *ck, float &g0, - BilinearDesign::Type lpHp); - - // 周波数特性の描画 - void DrawResponse(); - - void GetCoefficients(Biquad::Coefs *ck, float &g0); - - uint16_t GetOrder() { return ORDER_; } - - private: - LCD_DISCO_F746NG *lcd_; - TS_DISCO_F746NG *ts_; - - const uint16_t X0_, Y0_; - const uint16_t DB10_; - const uint16_t ORDER_; - const uint16_t CURSOR_Y0_, CURSOR_LENGTH_; - const uint16_t LOWER_F_, HIGHER_F_; - const uint32_t CURSOR_COLOR_, CURSOR_TOUCHED_COLOR_; - - BilinearDesign::Coefs *coefs_; // 設計された係数 - Biquad::Coefs *ck_; - float g0_; // 設計された係数(利得定数) - - int fC_; // 遮断周波数 - - uint16_t cursorX_, oldCursorX_; - bool cursorRedraw_; - BilinearDesign::Type lp_; - - BiquadFrqRespDrawer *drawerObj_; - BilinearDesign *designObj_; - TouchPanelDetectorX *tp_; - NumericLabel<int> *lblFrq_; - - // 周波数を 10, 20, 50, 100 Hz の倍数にする - int Frq10(float f); - - // 周波数特性の目盛線と目盛値の描画 - void DrawAxisNum(); - }; -} -#endif // F746_DISIGNER_AND_DRAWER_HPP
--- a/MyClasses_Functions/FileSelector.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -//-------------------------------------------------------------- -// FileSelector class -// SD カード内のファイル名の一覧を表示し,ファイルを選択する -// -// 2016/04/10, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#ifndef FILE_SELECTOR_HPP -#define FILE_SELECTOR_HPP - -#include "mbed.h" -#include "Label.hpp" -#include "ButtonGroup.hpp" -#include "SD_BinaryReader.hpp" -#include "SDFileSystem.h" -#include <algorithm> // sort() で使用 -#include <string> - -namespace Mikami -{ - class FileSelector - { - public: - FileSelector(uint8_t x0, uint8_t y0, int maxFiles, - int maxNameLength, SD_BinaryReader &reader) - : X_(x0), Y_(y0), W_H_(24), V_L_(36), - MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength), - BASE_COLOR_(0xFF80FFA0), TOUCHED_COLOR_(0xFF80FFFF), - fileNames_(new string[maxFiles]), - sortedFileNames_(new string[maxFiles]), - lcd_(GuiBase::GetLcdPtr()), - sdReader_(reader), prev_(-1) {} - - bool CreateTable() - { - DIR* dp = opendir("/sd"); - fileCount_ = 0; - if (dp != NULL) - { - dirent* entry; - for (int n=0; n<256; n++) - { - entry = readdir(dp); - if (entry == NULL) break; - - string strName = entry->d_name; - if ( (strName.find(".bin") != string::npos) || - (strName.find(".BIN") != string::npos) ) - { - sdReader_.Open(strName); // ファイルオープン - // 小さすぎるファイルは除外 - if ((sdReader_.ReadSize()) > 4096) - { - fileNames_[fileCount_] = strName; - fileCount_++; - } - sdReader_.Close(); - } - if (fileCount_ >= MAX_FILES_) break; - } - closedir(dp); - } - else - return false; - - if (fileCount_ == 0) return false; - - nonString_ = new string[fileCount_]; - for (int n=0; n<fileCount_; n++) nonString_[n] = ""; - rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, fileCount_, - nonString_, 0, V_L_-W_H_, 1, - -1, Font12, 0, GuiBase::ENUM_BACK, - BASE_COLOR_, TOUCHED_COLOR_); - for (int n=0; n<fileCount_; n++) rect_->Erase(n); - CreateLabels(); - - return true; - } - - // ファイルを選択する - bool Select(string &fileName) - { - int n; - if (rect_->GetTouchedNumber(n)) - { - fileNameLabels_[n]->Draw(GetFileNameNoExt(n), TOUCHED_COLOR_); - if ((prev_ >= 0) && (prev_ != n)) - fileNameLabels_[prev_]->Draw(GetFileNameNoExt(prev_)); - prev_ = n; - fileName = sortedFileNames_[n]; - return true; - } - else - return false; - } - - // ファイルの一覧の表示 - void DisplayFileList(bool sort = true) - { - for (int n=0; n<fileCount_; n++) - sortedFileNames_[n] = fileNames_[n]; - if (sort) - std::sort(sortedFileNames_, sortedFileNames_+fileCount_); - - Erase(MAX_NAME_LENGTH_*((sFONT *)(&Font16))->Width, 270-Y_); - rect_->DrawAll(); - for (int n=0; n<fileCount_; n++) - fileNameLabels_[n]->Draw(GetFileNameNoExt(n)); - } - - void Erase(uint16_t width, uint16_t height, - uint32_t color = GuiBase::ENUM_BACK) - { - lcd_->SetTextColor(color); - lcd_->FillRect(X_, Y_, width, height); - } - - private: - const uint8_t X_, Y_, W_H_, V_L_; - const int MAX_FILES_; - const int MAX_NAME_LENGTH_; - const uint32_t BASE_COLOR_; - const uint32_t TOUCHED_COLOR_; - - string *fileNames_; - string *sortedFileNames_; - string *nonString_; - ButtonGroup *rect_; - Label **fileNameLabels_; - LCD_DISCO_F746NG *lcd_; - SD_BinaryReader &sdReader_; - int fileCount_; - int prev_; - - // Label を生成 - void CreateLabels() - { - fileNameLabels_ = new Label *[fileCount_+1]; - for (int n=0; n<fileCount_; n++) - fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "", - Label::LEFT, Font16, - BASE_COLOR_); - } - - // 拡張子を削除した文字列を取得 - string GetFileNameNoExt(int n) - { - string name = sortedFileNames_[n]; - name.erase(name.find(".")); - return name.substr(0, MAX_NAME_LENGTH_); - } - - // disallow copy constructor and assignment operator - FileSelector(const FileSelector&); - FileSelector& operator=(const FileSelector&); - }; -} -#endif // FILE_SELECTOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyClasses_Functions/FrequancyResponseBase.hpp Sat Apr 16 13:53:26 2016 +0000 @@ -0,0 +1,21 @@ + +#ifndef FREQUENCY_RESPONSE_BASE_HPP +#define FREQUENCY_RESPONSE_BASE_HPP + +#include <complex> // requisite for complex + +namespace Mikami +{ + typedef complex<float> Complex; // define "Complex" + + class FrequencyResponse + { + public: + // 周波数応答の絶対値を返す関数, 引数: z^(-1) + virtual float AbsH_z(Complex u) = 0; + + protected: + FrequencyResponse() {} + }; +} +#endif // F746_FREQUENCY_RESPONSE_BASE_HPP
--- a/MyClasses_Functions/FrquencyResponseDrawer.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -//----------------------------------------------------------- -// FrqRespDrawer class (Abstract base class) -// -// 2016/03/31, Copyright (c) 2016 MIKAMI, Naoki -//----------------------------------------------------------- - -#include "FrquencyResponseDrawer.hpp" -#include "NumericLabel.hpp" - -namespace Mikami -{ - // 目盛線の描画 - void FrqRespDrawer::DrawAxis() - { - uint16_t height = DB1_*(P_.MAX_DB - P_.MIN_DB); - int logMin = (int)floorf(log10f(P_.MIN)); - int loop = (int)floorf(log10f(P_.MAX)) - logMin; - - lcd_->SetTextColor(P_.AXIS_COLOR); - uint16_t y0 = P_.ORGY- height; - lcd_->DrawVLine(X(P_.MIN), y0, height); // 最小値に対応する線 - - float du = powf(10.0, logMin); // 座標値の増分 - float u1 = (floorf(P_.MIN/du) + 1.0f)*du; // 最小値に対応する線の次の座標値 - - for (int n=0; n<=loop; n++) - { - float uMax = (10.0f*du < P_.MAX) ? 10.0f*du : P_.MAX; - for (float u=u1; u<uMax*0.99f; u+=du) - lcd_->DrawVLine(X(u), y0, height); - - du = uMax; // 値の増分を 10 倍する - u1 = du; // 次の for ループ の最初の値 - } - - lcd_->DrawVLine(X(P_.MAX), y0, height); // 最大値に対応する線 - - uint16_t width = X(P_.MAX) - X(P_.MIN); - for (int n=0; n<= (P_.MAX_DB - P_.MIN_DB)/10; n++) - lcd_->DrawHLine(X(P_.MIN), P_.ORGY-P_.DB10*n, width); - } - - // 縦軸の数値の表示 - void FrqRespDrawer::DrawNumericY(int offsetX, int offsetY, int count, - uint16_t d_dB, const char fmt[], sFONT &fonts, - uint32_t textColor) - { - uint16_t x0 = P_.ORG + offsetX; - uint16_t y0 = P_.ORGY + offsetY; - for (int n=0; n<count; n++) - new NumericLabel<int>(x0, y0-n*d_dB*DB1_, - fmt, (int)(P_.MIN_DB+d_dB*n)); - } - - // 周波数特性のグラフの描画 - void FrqRespDrawer::DrawGraph() - { - lcd_->SetTextColor(P_.LINE_COLOR); - uint16_t width = X(P_.MAX) - X(P_.MIN); - uint16_t x1 = 0; - uint16_t y1 = 0; - float pi2FsM = -6.283185f/P_.FS; // -2*PI*Ts - for (int n=0; n<=width; n++) - { - float frq = PosToFrq(n+P_.ORG); - uint16_t x2 = X(frq); - - float absHz = AbsH_z(exp(Complex(0, pi2FsM*frq))); - float dB = (absHz > 0.001f) ? 20.0f*log10f(absHz) : P_.MIN_DB; - uint16_t y2 = P_.ORGY - Round((dB - P_.MIN_DB)*DB1_); - if (y2 > P_.ORGY) y2 = P_.ORGY; - - if (n != 0) lcd_->DrawLine(x1, y1, x2, y2); - - x1 = x2; - y1 = y2; - } - lcd_->SetTextColor(P_.AXIS_COLOR); - lcd_->DrawHLine(X(P_.MIN), P_.ORGY, width); - } - - // 消去 - void FrqRespDrawer::Erase() - { - lcd_->SetTextColor(P_.BACK_COLOR); - uint16_t height = DB1_*(P_.MAX_DB - P_.MIN_DB); - lcd_->FillRect(P_.ORG, P_.ORGY- height, X(P_.MAX)-X(P_.MIN)+1, height+1); - } -}
--- a/MyClasses_Functions/FrquencyResponseDrawer.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -//----------------------------------------------------------- -// FrqRespDrawer class (Abstract base class) -- Header -// -// 2016/03/30, Copyright (c) 2016 MIKAMI, Naoki -//----------------------------------------------------------- - -#ifndef F746_FRQ_RESP_DRAWER_HPP -#define F746_FRQ_RESP_DRAWER_HPP - -#include <complex> // requisite for complex -#include "Label.hpp" - -namespace Mikami -{ - typedef complex<float> Complex; // define "Complex" - - class FrqRespDrawer - { - public: - struct Params - { - const uint16_t ORG; // 横軸の目盛の最小値に対応する位置 - const float MIN; // 横軸の目盛の最小値 - const float MAX; // 横軸の目盛の最大値 - const uint16_t DEC; // 周波数の 10 倍に対応する長さ (pixels) - const uint16_t ORGY; // 縦軸の目盛の最小値に対応する位置 - const float MIN_DB; // 縦軸の目盛の最小値 [dB] - const float MAX_DB; // 縦軸の目盛の最大値 [dB] - const uint16_t DB10; // 10 dB 対応する長さ (pixels) - const float FS; // 標本化周波数 - const uint32_t LINE_COLOR; - const uint32_t AXIS_COLOR; - const uint32_t BACK_COLOR; - - Params(uint16_t org, float min, float max, uint16_t dec, - uint16_t orgY, float minDb, float maxDb, uint16_t db10, - float fs, - uint32_t lineColor = 0xFF00B0FF, - uint32_t axisColor = LCD_COLOR_LIGHTGRAY, - uint32_t backColor = GuiBase::ENUM_BACK) - : ORG(org), MIN(min), MAX(max), DEC(dec), - ORGY(orgY), MIN_DB(minDb), MAX_DB(maxDb), DB10(db10), - FS(fs), - LINE_COLOR(lineColor), - AXIS_COLOR(axisColor), - BACK_COLOR(backColor) {} - }; - - // Constructor - FrqRespDrawer(Params p) - : lcd_(GuiBase::GetLcdPtr()), P_(p), DB1_(p.DB10*0.1f) {} - - // 周波数に対応する x 座標値の取得 - int X(float frq) - { return Round(P_.ORG + P_.DEC*log10f(frq/P_.MIN)); } - - // x 座標値を周波数に変換 - float PosToFrq(uint16_t x) - { return P_.MIN*powf(10.0f, (x - P_.ORG)/(float)P_.DEC); } - - // 目盛線の描画 - void DrawAxis(); - - // 横軸の目盛値の表示用 - void DrawCharX(uint32_t frq, int offsetY, - const char str[], sFONT &fonts = Font12, - uint32_t textColor = LCD_COLOR_WHITE) - { Label frequency(X(frq), P_.ORGY+offsetY, str, Label::CENTER); } - - // 縦軸の目盛値の表示 - void DrawNumericY(int offsetX, int offsetY, int count, - uint16_t d_dB, const char fmt[], sFONT &fonts = Font12, - uint32_t textColor = LCD_COLOR_WHITE); - - // 周波数特性のグラフの描画 - void DrawGraph(); - - // 周波数応答の絶対値を返す関数, 引数: z^(-1) - virtual float AbsH_z(Complex u) = 0; - - // 消去 - void Erase(); - - private: - LCD_DISCO_F746NG *lcd_; - const Params P_; - const float DB1_; - - // 丸め - int Round(float x) { return x + 0.5f - (x < 0); } - - // 10 のべき乗かどうかの検査 - bool PowersOf10(float x) - { return fabsf(log10f(x) - Round(log10f(x))) < 0.01f; } - - // disallow copy constructor and assignment operator - FrqRespDrawer(const FrqRespDrawer&); - FrqRespDrawer& operator=(const FrqRespDrawer&); - }; -} -#endif // F746_FRQ_RESP_DRAWER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyClasses_Functions/IIR_CascadeFrqResp.hpp Sat Apr 16 13:53:26 2016 +0000 @@ -0,0 +1,48 @@ +//----------------------------------------------------------- +// Frequency response for IIR filter of cascade form +// +// 2016/04/16, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef IIR_CASCADE_FREQUENCY_RESPONSE_HPP +#define IIR_CASCADE_FREQUENCY_RESPONSE_HPP + +#include "FrequancyResponseBase.hpp" +#include "Biquad.hpp" + +namespace Mikami +{ + class IIR_CascadeFrqResp : public FrequencyResponse + { + public: + IIR_CascadeFrqResp() {} + + // 次数とフィルタの係数設定 + void SetParams(int order, float g0, Biquad::Coefs ck[]) + { + order_ = order; + g0_ = g0; + ck_ = ck; + } + + // 周波数応答の絶対値を返す関数, 引数: z^(-1) + virtual float AbsH_z(Complex u) + { + Complex h = g0_; + for (int k=0; k<order_/2; k++) + h = h*(1.0f + (ck_[k].b1 + ck_[k].b2*u)*u) + /((1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)); + return abs(h); + } + + private: + int order_; + float g0_; + Biquad::Coefs *ck_; + + // disallow copy constructor and assignment operator + IIR_CascadeFrqResp(const IIR_CascadeFrqResp&); + IIR_CascadeFrqResp& operator=(const IIR_CascadeFrqResp&); + }; +} +#endif // IIR_CASCADE_FREQUENCY_RESPONSE_HPP \ No newline at end of file
--- a/MyClasses_Functions/MyFunctions.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -//-------------------------------------------------------------- -// フィルタ処理付き SD オーディオプレーヤーで使う大域関数(ヘッダ) -// -// 2016/04/07, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#include "MyFunctions.hpp" - -// 1フレーム分の信号処理 (IIR フィルタ) の実行 -void ProcessSignal(SD_BinaryReader &sdReader, SaiIO_O &mySai, - int16_t sn[], float g0, Biquad hn[], - int order, bool filterOn) -{ - sdReader.Read(sn, mySai.GetLength()); // 1フレーム分のデータを SD から読み込む - - while (!mySai.IsXferred()) {} // データの転送が終わるまで待つ - //-------------------------------------------------------------- - // 1フレーム分の信号処理を行い,その結果を出力する - for (int n=0; n<mySai.GetLength(); n++) - { - int16_t value; - if (filterOn) // フィルタ処理実行 - { - // 縦続形の IIR フィルタ - float yn = g0*sn[n]; - for (int k=0; k<order/2; k++) yn = hn[k].Execute(yn); - value = (int16_t)yn; - } - else - value = sn[n]; // フィルタ処理なし - mySai.Output(value, value); // 音響信号の出力 - } - //-------------------------------------------------------------- - mySai.ResetXferred(); // 次のデータ転送に備える -} - -// SD カードのファイルのオープン -int32_t SD_Open(SD_BinaryReader &sdReader, - string fileName, int32_t frameSize) -{ - sdReader.Open(fileName); - return sdReader.ReadSize()/frameSize; -} - -// ファイルの選択 -// selectedName: 選択されたファイル名 -void SelectFile(ButtonGroup &menu, FileSelector &selector, - Label &msg, string &selectedName) -{ - msg.Draw("Select file"); - selector.DisplayFileList(); - do - { - if (selector.Select(selectedName)) - menu.Activate(1); // PLAY 有効 - wait_ms(200); - } while (!menu.Touched(1)); // PLAY がタッチされるまで繰り返す -} - -// フィルタの変更 -void ModifyFilter(DesignerDrawer &drawerObj, - ButtonGroup &lpHp, ButtonGroup &onOff, - Biquad hn[], Biquad::Coefs ck[], - float &g0, bool &filterOn) -{ - // フィルタ処理の有効/無効切り替え - int sw = 0; - if (onOff.GetTouchedNumber(sw)) - filterOn = (sw == 0) ? true : false; - - // フィルタの周波数特性の変更 - static int num = 0; - lpHp.GetTouchedNumber(num); - BilinearDesign::Type typeLH = (BilinearDesign::Type)num; - if (drawerObj.ReDesignAndDraw(ck, g0, typeLH)) - for (int k=0; k<drawerObj.GetOrder()/2; k++) - { - hn[k].SetCoefficients(ck[k]); - hn[k].Clear(); - } -}
--- a/MyClasses_Functions/MyFunctions.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -//-------------------------------------------------------------- -// フィルタ処理付き SD オーディオプレーヤーで使う大域関数(ヘッダ) -// -// 2016/04/07, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#ifndef F746_MY_FUNCTIONS_HPP -#define F746_MY_FUNCTIONS_HPP - -#include "sai_io_o.hpp" -#include "ButtonGroup.hpp" -#include "FileSelector.hpp" -#include "DesignerDrawer.hpp" -#include "SD_BinaryReader.hpp" - -using namespace Mikami; - -// 1フレーム分の信号処理 (IIR フィルタ) の実行 -void ProcessSignal(SD_BinaryReader &sdReader, SaiIO_O &mySai, - int16_t sn[], float g0, Biquad hn[], - int order, bool filterOn); - -// SD カードのファイルのオープン -int32_t SD_Open(SD_BinaryReader &sdReader, - string fileName, int32_t frameSize); - -// ファイルの選択 -void SelectFile(ButtonGroup &menu, FileSelector &selector, - Label &msg, string &selectedName); - -// フィルタの変更 -void ModifyFilter(DesignerDrawer &drawerObj, - ButtonGroup &lpHp, ButtonGroup &onOff, - Biquad hn[], Biquad::Coefs ck[], - float &g0, bool &filterOn); - -#endif // F746_MY_FUNCTIONS_HPP
--- a/MyClasses_Functions/SD_BinaryReader.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -//-------------------------------------------------------------- -// SD_BinaryReader class -// SD カードの内容を読み出す -// 最初の4バイト:データサイズ -// それ以降: int16_t のデータ -// -// 2016/04/07, Copyright (c) 2016 MIKAMI, Naoki -//-------------------------------------------------------------- - -#ifndef SD_BINARY_READER_HPP -#define SD_BINARY_READER_HPP - -#include "SDFileSystem.h" -#include "BlinkLabel.hpp" -#include <string> - -namespace Mikami -{ - class SD_BinaryReader - { - public: - SD_BinaryReader() : STR_("sd"), ok_(false) - { - sd_ = new SDFileSystem(STR_.c_str()); - sd_->mount(); - } - - ~SD_BinaryReader() - { - sd_->unmount(); - delete sd_; - } - - void Open(const string fileName) - { - string name = (string)"/" + STR_ + "/" + fileName; - fp_ = fopen(name.c_str(), "rb"); - if (fp_ == NULL) ErrorMsg("open error!!"); - } - - void Close() { fclose(fp_); } - - // ファイルからデータサイズの読み出し - // 戻り値: int16_t 型のデータサイズ - int32_t ReadSize() - { - fread(&size_, sizeof(int), 1, fp_); - ok_ = true; - return size_; - } - - // ファイルからデータの取得 - void Read(int16_t data[], uint32_t size) - { - if (!ok_) ErrorMsg("Get data FAILED"); - fread(data, sizeof(int16_t), size, fp_); - } - - // データサイズの取得 - // 戻り値: int16_t 型のデータサイズ - int32_t GetSize() - { - if (!ok_) ErrorMsg("Get data size FAILED"); - return size_; - } - - private: - const string STR_; - - SDFileSystem *sd_; - FILE *fp_; - - bool ok_; - int32_t size_; // word count, word = int16_t - - void ErrorMsg(char msg[]) - { - BlinkLabel errLabel(240, 100, msg, Label::CENTER); - } - - // disallow copy constructor and assignment operator - SD_BinaryReader(const SD_BinaryReader&); - SD_BinaryReader& operator=(const SD_BinaryReader&); - }; -} -#endif // SD_BINARY_READER_HPP
--- a/MyClasses_Functions/TouchPanelDetectorX.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -//------------------------------------------------------ -// Touch panel detector for x axis class -// -// 2016/03/31, Copyright (c) 2016 MIKAMI, Naoki -//------------------------------------------------------ - -#ifndef F746_TOUCH_PANELDETECTORX_HPP -#define F746_TOUCH_PANELDETECTORX_HPP - -#include "GuiBase.hpp" - -namespace Mikami -{ - class TouchPanelDetectorX : public GuiBase - { - public: - // Constructor - TouchPanelDetectorX(uint16_t x1, uint16_t x2, - uint16_t y1, uint16_t y2) - : X1_(x1), X2_(x2), Y1_(y1), Y2_(y2) {} - - bool IsTouched(uint16_t xIn, uint16_t &xOut) - { - GetTsState(); - - if (!state_.touchDetected) return false; - - uint16_t x = state_.touchX[0]; - uint16_t y = state_.touchY[0]; - - if ( (x < X1_) || (x > X2_) || (y < Y1_) || (y > Y2_) ) - return false; - - const int WD = 8; - if ( (x < xIn-WD) || (x > xIn+WD) ) return false; - - xOut = (x >= X1_) ? x : X1_; - xOut = (x <= X2_) ? x : X2_; - return true; - } - - private: - const uint16_t X1_, X2_, Y1_, Y2_; - }; -} -#endif // F746_TOUCH_PANELDETECTORX_HPP
--- a/MyClasses_Functions/sai_io_o.cpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -//----------------------------------------------------------- -// 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[(size*2)*2]; - tmp_ = new int16_t[size*2]; - xferred_ = false; - } - - void SaiIO_O::InitCodecOut() - { - if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME_OUT_, FS_) == AUDIO_ERROR) - ErrorTrap(); - for (int n=0; n<bufferSize_; n++) outBuffer_[n] = 0; - for (int n=0; n<nData_*2; n++) tmp_[n] = 0; - - 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::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_; -} -
--- a/MyClasses_Functions/sai_io_o.hpp Sat Apr 16 03:57:18 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -//----------------------------------------------------------- -// 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 Stop() { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); } - void Pause() { BSP_AUDIO_OUT_Pause(); } - void Resume() { 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_ = 90; - - 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
--- a/mbed.bld Sat Apr 16 03:57:18 2016 +0000 +++ b/mbed.bld Sat Apr 16 13:53:26 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/99a22ba036c9 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/082adc85693f \ No newline at end of file