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 F746_GUI F746_SAI_IO FrequencyResponseDrawer LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed
Fork of F746_SD_GraphicEqualizer by
Revision 8:12aa05f3cc24, committed 2016-05-09
- Comitter:
- MikamiUitOpen
- Date:
- Mon May 09 08:54:09 2016 +0000
- Parent:
- 7:be29ba9c83b2
- Child:
- 9:0d5bd1539291
- Commit message:
- 8
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/BiquadGrEq.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,66 @@
+//--------------------------------------------------------------
+// グラフィックイコライザで使う 1D タイプの 2 次のフィルタ
+// Biquad filter of 1D type for graphic equalizer
+// このクラスでは,係数は実行中に書き換えられることを想定している
+//
+// u[n] = x[n] + a1*u[n-1] + a2*u[n-2]
+// y[n] = b0*u[n] + b1*u[n-1] + b2*u[n-2]
+// x[n] : input signal
+// y[n] : output signal
+//
+// 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 BiquadGrEq
+ {
+ public:
+ struct Coefs { float a1, a2, b0, b1, b2; };
+
+ BiquadGrEq() {} // Default constructore
+
+ BiquadGrEq(const Coefs ck)
+ {
+ SetCoefficients(ck);
+ Clear();
+ }
+
+ void SetCoefficients(const Coefs ck)
+ {
+ a1_ = ck.a1;
+ a2_ = ck.a2;
+ b0_ = ck.b0;
+ b1_ = ck.b1;
+ b2_ = ck.b2;
+ }
+
+ float Execute(float xn)
+ {
+ float un = xn + a1_*un1_ + a2_*un2_;
+ float yn = b0_*un + b1_*un1_ + b2_*un2_;
+
+ un2_ = un1_;
+ un1_ = un;
+
+ return yn;
+ }
+
+ void Clear() { un1_ = un2_ = 0; }
+
+ private:
+ float a1_, a2_, b0_, b1_, b2_;
+ float un1_, un2_;
+
+ // disallow copy constructor
+ BiquadGrEq(const BiquadGrEq&);
+ };
+}
+#endif // IIR_BIQUAD_HPP
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/DesignerDrawer.cpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,76 @@
+//------------------------------------------------------------------------------
+// イコライザ用フィルタのパラメータを設定し,その周波数特性を描画するためのクラス
+//
+// 2016/05/09, Copyright (c) 2016 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#include "DesignerDrawer.hpp"
+
+namespace Mikami
+{
+ // Constructor
+ DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0,
+ int bands, float f0, int fs, float db1)
+ : lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()),
+ X0_(x0), Y0_(y0), BANDS_(bands), Q_VAL_(1.0f/sqrtf(2.0f))
+ {
+ drawerObj_ = new FrqRespDrawer(x0, 50.0f, 20000.0f, 142,
+ y0, -18, 18, db1, 6, fs);
+
+ calculator_ = new GrEqParams(bands, fs);
+ f0_ = new float[bands];
+ for (int n=0; n<bands; n++)
+ f0_[n] = f0*powf(2, n);
+
+ ck_ = new BiquadGrEq::Coefs[bands];
+ for (int n=0; n<bands; n++)
+ ck_[n] = calculator_->Execute(n, f0_[n], 0, Q_VAL_);
+ frqResp_ = new GrEqualizerFrqResp(bands);
+ frqResp_->SetParams(ck_);
+
+ // 周波数特性の描画
+ DrawResponse();
+ }
+
+ DesignerDrawer::~DesignerDrawer()
+ {
+ delete[] frqResp_;
+ delete[] ck_;
+ delete[] f0_;
+ delete calculator_;
+ delete drawerObj_;
+ }
+
+ // 周波数特性の描画
+ void DesignerDrawer::DrawResponse()
+ {
+ drawerObj_->DrawAxis(); // 目盛線の描画
+ FrqRespDrawer::AxisX_Char numX[] = // 横軸の目盛値を描画する際に使う構造体の配列
+ {{ 50, "50"}, { 100, "100"}, { 200, "200"}, { 500, "500"}, { 1000, "1k"},
+ { 2000, "2k"}, { 5000, "5k"}, {10000, "10k"}, {20000, "20k"}};
+ drawerObj_->DrawNumericX(numX, 9, 6, "Frequency [Hz]"); // 横軸の目盛
+ drawerObj_->DrawNumericY(-24, -6, 6, "%3d"); // 縦軸の目盛値は 6 dB 間隔
+ drawerObj_->DrawGraph(frqResp_); // 周波数特性のカーブの描画
+ }
+
+ // 周波数特性の平坦化と描画
+ void DesignerDrawer::DrawFlat()
+ {
+ for (int n=0; n<BANDS_; n++)
+ ck_[n] = calculator_->Execute(n, f0_[n], 0, Q_VAL_);
+ frqResp_->SetParams(ck_);
+ drawerObj_->Erase();
+ drawerObj_->DrawAxis(); // 目盛線の描画
+ drawerObj_->DrawGraph(frqResp_); // 周波数特性のグラフのカーブを描画する
+ }
+
+ // 特定のバンドのイコライザ用フィルタのパラメータの設定と周波数特性の再描画
+ void DesignerDrawer::DesignAndRedraw(float gainDb, int n)
+ {
+ ck_[n] = calculator_->Execute(n, f0_[n], gainDb, Q_VAL_);
+ frqResp_->SetParam(ck_[n], n);
+ drawerObj_->Erase();
+ drawerObj_->DrawAxis(); // 目盛線の描画
+ drawerObj_->DrawGraph(frqResp_); // 周波数特性のグラフのカーブを描画する
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/DesignerDrawer.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,64 @@
+//------------------------------------------------------------------------------
+// イコライザ用フィルタのパラメータを設定し,その周波数特性を描画するためのクラス -- Header
+//
+// 2016/05/09, Copyright (c) 2016 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#ifndef F746_DISIGNER_AND_DRAWER_HPP
+#define F746_DISIGNER_AND_DRAWER_HPP
+
+#include "NumericLabel.hpp"
+#include "FrquencyResponseDrawer.hpp"
+#include "GrEqParamsCalculator.hpp"
+#include "GrEqualizerFrqResp.hpp"
+
+namespace Mikami
+{
+ class DesignerDrawer
+ {
+ public:
+ // Constructor
+ DesignerDrawer(uint16_t x0, uint16_t y0,
+ int stages, float f0, int fs, float db1);
+
+ ~DesignerDrawer();
+
+ // 周波数特性の描画
+ void DrawResponse();
+
+ // 周波数特性の平坦化と描画
+ void DrawFlat();
+
+ // 特定のバンドのイコライザ用フィルタのパラメータの設定と周波数特性の再描画
+ void DesignAndRedraw(float gainDb, int n);
+
+ void GetCoefficients(BiquadGrEq::Coefs ck[])
+ { for (int n=0; n<BANDS_; n++) ck[n] = ck_[n]; }
+
+ BiquadGrEq::Coefs GetCoefficient(int n) { return ck_[n]; }
+
+ uint16_t GetX0()
+ { return drawerObj_->X(f0_[0]); }
+
+ uint16_t GetSpaceX()
+ { return (uint16_t)(drawerObj_->X(f0_[1])
+ - drawerObj_->X(f0_[0])); }
+
+ int GetStages() { return BANDS_; }
+
+ private:
+ LCD_DISCO_F746NG *lcd_;
+ TS_DISCO_F746NG *ts_;
+
+ const uint16_t X0_, Y0_;
+ const int BANDS_;
+ const float Q_VAL_;
+
+ float *f0_; // 中心周波数を格納する配列のポインタ
+ GrEqParams *calculator_;
+ GrEqualizerFrqResp *frqResp_; // フィルタの周波数応答に対応するオブジェクト
+ BiquadGrEq::Coefs *ck_; // フィルタの係数
+ FrqRespDrawer *drawerObj_;
+ };
+}
+#endif // F746_DISIGNER_AND_DRAWER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/FileSelectorWav.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,182 @@
+//--------------------------------------------------------------
+// FileSelector class
+// SD カード内のファイル名の一覧を表示し,ファイルを選択する
+//
+// 2016/04/18, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef FILE_SELECTOR_HPP
+#define FILE_SELECTOR_HPP
+
+#include "mbed.h"
+#include "Label.hpp"
+#include "ButtonGroup.hpp"
+#include "SD_WavReader.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_WavReader &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]),
+ nonString_(NULL), rect_(NULL), fileNameLabels_(NULL),
+ lcd_(GuiBase::GetLcdPtr()),
+ sdReader_(reader), prevFileCount_(0), prev_(-1) {}
+
+ ~FileSelector()
+ {
+ for (int n=0; n<fileCount_; n++)
+ delete fileNameLabels_[n];
+ delete[] fileNameLabels_;
+ delete rect_;
+ delete[] nonString_;
+ delete[] sortedFileNames_;
+ delete[] fileNames_;
+ }
+
+ 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(".wav") != string::npos) ||
+ (strName.find(".WAV") != string::npos) )
+ {
+ sdReader_.Open(strName); // ファイルオープン
+
+ // PCM,16 ビットステレオ,標本化周波数 44.1 kHz 以外のファイルは除外
+ if (sdReader_.IsWavFile())
+ {
+ fileNames_[fileCount_] = strName;
+ fileCount_++;
+ }
+ sdReader_.Close();
+ }
+
+
+ if (fileCount_ >= MAX_FILES_) break;
+ }
+ closedir(dp);
+ }
+ else
+ return false;
+
+ if (fileCount_ == 0) return false;
+
+ if (nonString_ == NULL) delete[] nonString_;
+ nonString_ = new string[fileCount_];
+ for (int n=0; n<fileCount_; n++) nonString_[n] = "";
+
+ if (rect_ != NULL) delete rect_;
+ 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();
+ prevFileCount_ = fileCount_;
+ 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(X_, 0, MAX_NAME_LENGTH_*((sFONT *)(&Font16))->Width, 288);
+ rect_->DrawAll();
+ for (int n=0; n<fileCount_; n++)
+ fileNameLabels_[n]->Draw(GetFileNameNoExt(n));
+ }
+
+ void Erase(uint16_t x, uint16_t y, 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_WavReader &sdReader_;
+ int fileCount_, prevFileCount_;
+ int prev_;
+
+ // Label を生成
+ void CreateLabels()
+ {
+ if (fileNameLabels_ != NULL)
+ {
+ for (int n=0; n<prevFileCount_; n++)
+ delete fileNameLabels_[n];
+ delete[] fileNameLabels_;
+ }
+ 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/GrEqParamsCalculator.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+// Parameters calculator class of buquad unit for graphic equalizer
+// グラフィックイコライザで使う biquad フィルタの係数を計算するクラス
+//
+// 2016/05/09, Copyright (c) 2016 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#ifndef GRAPHIC_EQALIZER_PARAMETER_CALCULATOR_HPP
+#define GRAPHIC_EQALIZER_PARAMETER_CALCULATOR_HPP
+
+#include "mbed.h"
+#include "BiquadGrEq.hpp"
+
+namespace Mikami
+{
+ class GrEqParams
+ {
+ public:
+ // Constructor
+ GrEqParams(int bands, float fs) : BANDS_(bands), FS_(fs) {}
+
+ // 係数を計算する
+ BiquadGrEq::Coefs Execute(int band, float f0, float gDb, float qVal)
+ {
+ const float PI = 3.1415926536f;
+ BiquadGrEq::Coefs coefs;
+
+ float gSqrt = sqrtf(powf(10, gDb/20.0f));
+ float w0 = 2.0f*PI*f0/FS_;
+
+ if ( (band != 0) && (band != BANDS_-1) )
+ {
+ float alpha = sinf(w0)/(2.0f*qVal);
+ float a0 = 1.0f + alpha/gSqrt;
+ coefs.a1 = 2.0f*cosf(w0)/a0;
+ coefs.a2 = -(1.0f - alpha/gSqrt)/a0;
+ coefs.b0 = (1.0f + alpha*gSqrt)/a0;
+ coefs.b1 = -coefs.a1;
+ coefs.b2 = (1.0f - alpha*gSqrt)/a0;
+ }
+ else
+ {
+ w0 = (band == 0) ? w0*1.414f : w0/1.414f;
+ float alpha = sinf(w0)/sqrtf(2.0f); // Q = 1/sqrt(2)
+ float g_a = sqrtf(gSqrt);
+ float cosW0 = cosf(w0);
+ float gSqrtP1 = gSqrt+1.0f;
+ float gSqrtM1 = gSqrt-1.0f;
+ if (band == 0)
+ {
+ float a0 = gSqrtP1 + gSqrtM1*cosW0
+ + 2.0f*g_a*alpha;
+ coefs.a1 = 2.0f*(gSqrtM1 + gSqrtP1*cosW0)/a0;
+ coefs.a2 = -(gSqrtP1 + gSqrtM1*cosW0
+ - 2.0f*g_a*alpha)/a0;
+ coefs.b0 = gSqrt*(gSqrtP1 - gSqrtM1*cosW0
+ + 2.0f*g_a*alpha)/a0;
+ coefs.b1 = 2.0f*gSqrt*(gSqrtM1
+ - gSqrtP1*cosW0)/a0;
+ coefs.b2 = gSqrt*(gSqrtP1 - gSqrtM1*cosW0
+ - 2.0f*g_a*alpha)/a0;
+ }
+ else
+ {
+ float a0 = gSqrtP1 - gSqrtM1*cosW0
+ + 2.0f*g_a*alpha;
+ coefs.a1 = -2.0f*(gSqrtM1 - gSqrtP1*cosW0)/a0;
+ coefs.a2 = -(gSqrtP1 - gSqrtM1*cosW0
+ - 2.0f*g_a*alpha)/a0;
+ coefs.b0 = gSqrt*(gSqrtP1 + gSqrtM1*cosW0
+ + 2.0f*g_a*alpha)/a0;
+ coefs.b1 = -2.0f*gSqrt*(gSqrtM1 + gSqrtP1*cosW0)/a0;
+ coefs.b2 = gSqrt*(gSqrtP1 + gSqrtM1*cosW0
+ - 2.0f*g_a*alpha)/a0;
+ }
+ }
+
+ return coefs;
+ }
+
+ private:
+ const int BANDS_;
+ const float FS_;
+ };
+}
+#endif // GRAPHIC_EQALIZER_PARAMETER_CALCULATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/GrEqualizerFrqResp.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------
+// グラフィックイコライザで使う IIR フィルタの周波数応答
+// Frequency response for graphic equalizer
+//
+// 2016/04/27, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef GRAPHIC_EQUALIZER_FREQUENCY_RESPONSE_HPP
+#define GRAPHIC_EQUALIZER_FREQUENCY_RESPONSE_HPP
+
+#include "FrequancyResponseBase.hpp"
+#include "BiquadGrEq.hpp"
+
+namespace Mikami
+{
+ class GrEqualizerFrqResp : public FrequencyResponse
+ {
+ public:
+ GrEqualizerFrqResp(int stages) : STAGES_(stages)
+ { ck_ = new BiquadGrEq::Coefs[stages]; }
+
+ ~GrEqualizerFrqResp()
+ { delete[] ck_; }
+
+ // フィルタの係数設定
+ void SetParams(BiquadGrEq::Coefs ck[])
+ { for (int n=0; n<STAGES_; n++) ck_[n] = ck[n]; }
+
+ void SetParam(BiquadGrEq::Coefs ck, int n)
+ { ck_[n] = ck; }
+
+ // 周波数応答の絶対値を返す関数, 引数: z^(-1)
+ virtual float AbsH_z(Complex u)
+ {
+ Complex h = 1;
+ for (int k=0; k<STAGES_; k++)
+ h = h*(ck_[k].b0 + (ck_[k].b1 + ck_[k].b2*u)*u)
+ /((1.0f - (ck_[k].a1 + ck_[k].a2*u)*u));
+ return abs(h);
+ }
+
+ private:
+ const int STAGES_;
+ float g0_;
+ BiquadGrEq::Coefs *ck_;
+
+ // disallow copy constructor and assignment operator
+ GrEqualizerFrqResp(const GrEqualizerFrqResp&);
+ GrEqualizerFrqResp& operator=(const GrEqualizerFrqResp&);
+ };
+}
+#endif // GRAPHIC_EQUALIZER_FREQUENCY_RESPONSE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/MyFunctions.cpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,83 @@
+//--------------------------------------------------------------
+// グラフィックイコライザ付き SD オーディオプレーヤーで使う大域関数
+//
+// 2016/05/09, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "MyFunctions.hpp"
+
+// 1フレーム分の信号処理 (イコライザ) の実行
+void SignalProcessing(SD_WavReader &sdReader, SaiIO &mySai,
+ int16_t sn[], BiquadGrEq hn[],
+ int stages, bool on)
+{
+ // 1フレーム分のデータを SD から読み込む
+ sdReader.ReadAndToMono(sn, mySai.GetLength());
+
+ while (!mySai.IsXferred()) {} // データの転送が終わるまで待つ
+ //--------------------------------------------------------------
+ // 1フレーム分のイコライザ処理を行い,その結果を出力する
+ for (int n=0; n<mySai.GetLength(); n++)
+ {
+ // 縦続形の IIR フィルタ実行
+ float xn = 0.125f*sn[n]; // 0.125 の乗算はブースとしてもクリップ
+ // されないようにするため
+ float yn = xn;
+ for (int k=0; k<stages; k++) yn = hn[k].Execute(yn);
+ int16_t value = on ? (int16_t)yn : xn;
+ mySai.Output(value, value); // 音響信号の出力
+ }
+ //--------------------------------------------------------------
+ mySai.ResetXferred(); // 次のデータ転送に備える
+}
+
+// SD カードのファイルのオープン
+int32_t SD_Open(SD_WavReader &sdReader,
+ string fileName, int32_t frameSize)
+{
+ sdReader.Open(fileName);
+ sdReader.IsWavFile();
+ return sdReader.GetSize()/frameSize;
+}
+
+// ファイルの選択
+// selectedName: 選択されたファイル名
+void SelectFile(ButtonGroup &menu, FileSelector &selector,
+ Label &msg, string &selectedName)
+{
+ selector.DisplayFileList();
+ msg.Draw("Select file");
+ do
+ {
+ if (selector.Select(selectedName))
+ menu.Activate(1); // PLAY 有効
+ wait_ms(200);
+ } while (!menu.Touched(1)); // PLAY がタッチされるまで繰り返す
+}
+
+// フィルタの周波数特性の変更
+void ModifyFilter(DesignerDrawer &drawerObj,
+ SeekbarGroup &myBars, BiquadGrEq hn[],
+ Button &flat, ButtonGroup &onOff, bool &on)
+{
+
+ // 周波数特性を平坦化
+ if (flat.Touched())
+ {
+ drawerObj.DrawFlat();
+ for (int n=0; n<drawerObj.GetStages(); n++)
+ hn[n] = BiquadGrEq(drawerObj.GetCoefficient(n));
+ myBars.DrawAll(0); // ツマミの位置を 0 dB に設定する
+ flat.Draw();
+ return;
+ }
+
+ int sw = 0;
+ if (onOff.GetTouchedNumber(sw))
+ on = (sw == 0) ? true : false;
+
+ static int num = 0;
+ if (!myBars.GetSlidedNumber(num)) return;
+ drawerObj.DesignAndRedraw(myBars.GetValue(num), num);
+ hn[num] = BiquadGrEq(drawerObj.GetCoefficient(num));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyClasses_Functions/MyFunctions.hpp Mon May 09 08:54:09 2016 +0000 @@ -0,0 +1,38 @@ +//-------------------------------------------------------------- +// グラフィックイコライザ付き SD オーディオプレーヤーで使う大域関数(ヘッダ) +// +// 2016/05/09, Copyright (c) 2016 MIKAMI, Naoki +//-------------------------------------------------------------- + +#ifndef F746_MY_FUNCTIONS_HPP +#define F746_MY_FUNCTIONS_HPP + +#include "SAI_InOut.hpp" +#include "ButtonGroup.hpp" +#include "FileSelectorWav.hpp" +#include "DesignerDrawer.hpp" +#include "SD_WavReader.hpp" +#include "SeekbarGroup.hpp" +#include "BiquadGrEq.hpp" + +using namespace Mikami; + +// 1フレーム分の信号処理 (イコライザ) の実行 +void SignalProcessing(SD_WavReader &sdReader, SaiIO &mySai, + int16_t sn[], BiquadGrEq hn[], + int stages, bool on); + +// SD カードのファイルのオープン +int32_t SD_Open(SD_WavReader &sdReader, + string fileName, int32_t frameSize); + +// ファイルの選択 +void SelectFile(ButtonGroup &menu, FileSelector &selector, + Label &msg, string &selectedName); + +// フィルタの変更 +void ModifyFilter(DesignerDrawer &drawerObj, + SeekbarGroup &myBars, BiquadGrEq hn[], + Button &flat, ButtonGroup &onOff, bool &on); + +#endif // F746_MY_FUNCTIONS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/SD_WavReader.cpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,113 @@
+//--------------------------------------------------------------
+// SD_WavReader class
+// SD カードの *.wav ファイルの内容を読み出す
+// 以下のフォーマット以外は扱わない
+// PCM,16 ビットステレオ,標本化周波数 44.1 kHz
+//
+// 2016/04/19, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "SD_WavReader.hpp"
+
+namespace Mikami
+{
+ SD_WavReader::SD_WavReader(int32_t bufferSize)
+ : STR_("sd"), ok_(false)
+ {
+ sd_ = new SDFileSystem(STR_.c_str());
+ sd_->mount();
+
+ buffer = new int16_t[bufferSize*2];
+ }
+
+ SD_WavReader::~SD_WavReader()
+ {
+ delete[] buffer;
+ sd_->unmount();
+ delete sd_;
+ }
+
+ void SD_WavReader::Open(const string fileName)
+ {
+ string name = (string)"/" + STR_ + "/" + fileName;
+ fp_ = fopen(name.c_str(), "rb");
+ if (fp_ == NULL) ErrorMsg("open error!!");
+ }
+
+
+ // ファイルのヘッダ (RIFFxxxxWAVEfm ) 読み込み
+ // 戻り値: *.wav で,16 ビットステレオ,
+ // 標本化周波数:44.1 kHz の場合 true
+ bool SD_WavReader::IsWavFile()
+ {
+ char data[17];
+ fread(data, 1, 16, fp_);
+ string strRead = "";
+ for (int n=0; n<4; n++) strRead += data[n];
+ for (int n=8; n<16; n++) strRead += data[n];
+
+ // "RIFF", "WAVE", "fmt " が存在することを確認
+ if (strRead != "RIFFWAVEfmt ") return false;
+
+ // fmt chunck のサイズを取得
+ uint32_t fmtChunkSize;
+ fread(&fmtChunkSize, sizeof(uint32_t), 1, fp_);
+
+ // PCM, Stereo, 44.1 kHz, 16 bit であることを確認
+ WaveFormatEx fmtData;
+ fread(&fmtData, fmtChunkSize, 1, fp_);
+ if ((fmtData.wFormatTag != 1) ||
+ (fmtData.nChannels != 2) ||
+ (fmtData.nSamplesPerSec != 44100) ||
+ (fmtData.wBitsPerSample != 16)
+ ) return false;
+
+ // data chunk を探す
+ char dataId[5];
+ dataId[4] = 0;
+ fread(dataId, 1, 4, fp_);
+ if ("data" != (string)dataId)
+ for (int n=0; n<100; n++)
+ {
+ char oneByte;
+ fread(&oneByte, 1, 1, fp_);
+ for (int k=0; k<3; k++)
+ dataId[k] = dataId[k+1];
+ dataId[3] = oneByte;
+ if ("data" == (string)dataId) break;
+
+ if (n == 99) return false;
+ }
+
+ // データサイズ (byte) を取得
+ int32_t sizeByte;
+ fread(&sizeByte, sizeof(int32_t), 1, fp_);
+ size_ = sizeByte/4;
+
+ ok_ = true;
+ return true;
+ }
+
+ // ファイルからデータの取得
+ void SD_WavReader::Read(int16_t data[], uint32_t size)
+ {
+ if (!ok_) ErrorMsg("Get data FAILED");
+ fread(data, sizeof(int16_t), size, fp_);
+ }
+
+ // ファイルからデータをモノラルに変換しての取得
+ void SD_WavReader::ReadAndToMono(int16_t data[], uint32_t size)
+ {
+ if (!ok_) ErrorMsg("Get data FAILED");
+ fread(buffer, sizeof(int16_t), size*2, fp_);
+ for (int n=0; n<size; n++)
+ data[n] = (buffer[2*n] + buffer[2*n+1])/2;
+ }
+
+ // データサイズ(標本化点の数)の取得
+ int32_t SD_WavReader::GetSize()
+ {
+ if (!ok_) ErrorMsg("Get data size FAILED");
+ return size_;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyClasses_Functions/SD_WavReader.hpp Mon May 09 08:54:09 2016 +0000
@@ -0,0 +1,72 @@
+//--------------------------------------------------------------
+// SD_WavReader class ---- Header
+// SD カードの *.wav ファイルの内容を読み出す
+// 以下のフォーマット以外は扱わない
+// PCM,16 ビットステレオ,標本化周波数 44.1 kHz
+//
+// 2016/04/19, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef SD_WAV_READER_HPP
+#define SD_WAV_READER_HPP
+
+#include "SDFileSystem.h"
+#include "BlinkLabel.hpp"
+#include <string>
+
+namespace Mikami
+{
+ class SD_WavReader
+ {
+ public:
+ SD_WavReader(int32_t bufferSize);
+ ~SD_WavReader();
+
+ void Open(const string fileName);
+
+ void Close() { fclose(fp_); }
+
+ // ファイルのヘッダ (RIFFxxxxWAVEfm ) 読み込み
+ // 戻り値: *.wav で,16 ビットステレオ,
+ // 標本化周波数:44.1 kHz の場合 true
+ bool IsWavFile();
+
+ // ファイルからデータの取得
+ void Read(int16_t data[], uint32_t size);
+
+ // ファイルからデータをモノラルに変換しての取得
+ void ReadAndToMono(int16_t data[], uint32_t size);
+
+ // データサイズ(標本化点の数)の取得
+ int32_t GetSize();
+
+ private:
+ const string STR_;
+
+ struct WaveFormatEx
+ {
+ uint16_t wFormatTag; // 1: PCM
+ uint16_t nChannels; // 1:モノラル,2: ステレオ
+ uint32_t nSamplesPerSec; // 標本化周波数 (Hz)
+ uint32_t nAvgBytesPerSec; // 転送速度 (bytes/s)
+ uint16_t nBlockAlign; // 4: 16ビットステレオの場合
+ uint16_t wBitsPerSample; // データのビット数,8 または 16
+ uint16_t cbSize;
+ };
+
+ SDFileSystem *sd_;
+ FILE *fp_;
+
+ bool ok_;
+ int32_t size_; // モノラルデータのサイズ
+ int16_t *buffer; // ステレオをモノラルに変換する際の作業領域
+
+ void ErrorMsg(char msg[])
+ { BlinkLabel errLabel(240, 100, msg, Label::CENTER); }
+
+ // disallow copy constructor and assignment operator
+ SD_WavReader(const SD_WavReader&);
+ SD_WavReader& operator=(const SD_WavReader&);
+ };
+}
+#endif // SD_BINARY_READER_HPP
