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: SDFileSystem_Warning_Fixed
Revision 0:d310bb78455d, committed 2016-08-15
- Comitter:
- MikamiUitOpen
- Date:
- Mon Aug 15 04:38:45 2016 +0000
- Child:
- 1:c7968701f7b3
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FileSelectorWav.cpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,113 @@
+//--------------------------------------------------------------
+// FileSelector class
+// SD カード内のファイル名の一覧を表示し,ファイルを選択する
+//
+// 2016/07/27, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "FileSelectorWav.hpp"
+
+namespace Mikami
+{
+ bool FileSelector::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;
+ sdReader_.Close();
+ }
+
+ if (fileCount_ >= MAX_FILES_) break;
+ }
+ closedir(dp);
+ }
+ else
+ return false;
+
+ if (fileCount_ == 0) return false;
+
+ if (rect_ != NULL) delete rect_;
+ Array<string> nonString(fileCount_, "");
+ 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 FileSelector::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 = fileNames_[n];
+ return true;
+ }
+ else
+ return false;
+ }
+
+ // ファイルの一覧の表示
+ void FileSelector::DisplayFileList(bool sortEnable)
+ {
+ if (sortEnable)
+ std::sort((string *)fileNames_,
+ (string *)fileNames_+fileCount_);
+
+ Erase(X_, Y_, MAX_NAME_LENGTH_*((sFONT *)(&Font16))->Width, 272-Y_);
+ rect_->DrawAll();
+ for (int n=0; n<fileCount_; n++)
+ fileNameLabels_[n]->Draw(GetFileNameNoExt(n));
+ }
+
+ // ファイルの一覧の消去
+ void FileSelector::Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
+ uint32_t color)
+ {
+ lcd_->SetTextColor(color);
+ lcd_->FillRect(x, y, width, height);
+ }
+
+ // Label を生成
+ void FileSelector::CreateLabels()
+ {
+ fileNameLabels_.SetSize(fileCount_);
+
+ for (int n=0; n<fileCount_; n++)
+ fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
+ Label::LEFT, Font16,
+ BASE_COLOR_);
+ }
+
+ // 拡張子を削除した文字列を取得
+ string FileSelector::GetFileNameNoExt(int n)
+ {
+ string name = fileNames_[n];
+ name.erase(name.find("."));
+ return name.substr(0, MAX_NAME_LENGTH_);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FileSelectorWav.hpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,71 @@
+//--------------------------------------------------------------
+// FileSelector class ---- Header ----
+// SD カード内のファイル名の一覧を表示し,ファイルを選択する
+//
+// 2016/07/27, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef FILE_SELECTOR_HPP
+#define FILE_SELECTOR_HPP
+
+#include "F746_GUI.hpp"
+#include "SD_WavReader.hpp"
+#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_(maxFiles),
+ rect_(NULL), lcd_(GuiBase::GetLcdPtr()),
+ sdReader_(reader), prevFileCount_(0), prev_(-1) {}
+
+ virtual ~FileSelector()
+ { delete rect_; }
+
+ bool CreateTable();
+
+ // ファイルを選択する
+ bool Select(string &fileName);
+
+ // ファイルの一覧の表示
+ void DisplayFileList(bool sortEnable = true);
+
+ // ファイルの一覧の消去
+ void Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
+ uint32_t color = GuiBase::ENUM_BACK);
+
+ 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_;
+
+ Array<string> fileNames_;
+ ButtonGroup *rect_;
+ Array<Label *> fileNameLabels_;
+ LCD_DISCO_F746NG *lcd_;
+ SD_WavReader &sdReader_;
+ int fileCount_, prevFileCount_;
+ int prev_;
+
+ // Label を生成
+ void CreateLabels();
+
+ // 拡張子を削除した文字列を取得
+ string GetFileNameNoExt(int n);
+
+ // 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/SD_PlayerSkeleton.cpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,141 @@
+//--------------------------------------------------------------
+// SD プレーヤー用抽象基底クラス
+//
+// 2016/07/17, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "SD_PlayerSkeleton.hpp"
+
+namespace Mikami
+{
+ SD_PlayerSkeleton::SD_PlayerSkeleton(string str, int fs)
+ : FRAME_SIZE_(2048), sn_(FRAME_SIZE_),
+ mySai_(SaiIO::OUTPUT, FRAME_SIZE_, fs),
+ sdReader_(FRAME_SIZE_),
+ title_(214, 4, str, Label::CENTER, Font16),
+ selector_(4, 22, 7, 37, sdReader_),
+ menu_(BG_LEFT_, 2, BG_WIDTH_, BG_HEIGHT_, 5,
+ (string[]){"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"},
+ 0, 2, 1)
+ {
+ if (!selector_.CreateTable())
+ BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
+
+ menu_.InactivateAll();
+ menu_.Activate(0);
+ }
+
+ void SD_PlayerSkeleton::Execute()
+ {
+ bool playOk = false;
+ bool whileFirst = true;
+ int32_t loopCount;
+
+ while (true)
+ {
+ if (!playOk)
+ {
+ if (whileFirst)
+ {
+ whileFirst = false;
+ while (!menu_.Touched(0)) // OPEN がタッチされるまで待つ
+ Modefy();
+ SelectFile();
+ }
+ else
+ {
+ menu_.Activate(1); // PLAY 有効
+ int touch10;
+ while (!menu_.GetTouchedNumber(touch10))
+ Modefy();
+ if (touch10 == 0) SelectFile();
+ }
+
+ loopCount = SD_Open();
+ while (!menu_.Touched(1)) // PLAY がタッチされるまで待つ
+ Modefy();
+ }
+ else
+ loopCount = SD_Open();
+
+ selector_.Erase(0, 0, BG_LEFT_-4, 272);
+ title_.Draw();
+
+ Display(); // アプリ固有の表示処理
+
+ menu_.Inactivate(0); // OPEN 無効
+ menu_.Activate(2); // PAUSE 有効
+ menu_.Activate(4); // STOP 有効
+
+ playOk = false;
+ bool stopOk = false;
+
+ Clear(); // アプリ固有のクリア処理
+
+ mySai_.PlayOut(); // Play 開始
+
+ for (int k=0; k<loopCount; k++)
+ {
+ int touch42 = -1;
+ menu_.GetTouchedNumber(touch42);
+ if (touch42 == 4) break; // STOP
+ if (touch42 == 2) // PAUSE
+ {
+ menu_.Inactivate(2); // PAUSE 無効
+ menu_.Activate(3); // RESUME 有効
+ mySai_.PauseOut();
+
+ // PLAY か RESUME か STOP がタッチされるまで待つ
+ int touch134 = -1;
+ while (!menu_.GetTouchedNumber(touch134))
+ Modefy();
+ switch (touch134)
+ {
+ case 1: playOk = true; // 最初から PLAY
+ break;
+ case 3: mySai_.ResumeOut(); // PAUSE したところから PLAY 再開
+ menu_.Activate(2);
+ menu_.Inactivate(3);
+ menu_.TouchedColor(1);
+ break;
+ case 4: stopOk = true; // STOP
+ break;
+ }
+ }
+ if (playOk || stopOk) break;
+
+ Modefy();
+ // 1フレーム分の信号処理の実行
+ SignalProcessing();
+ }
+ mySai_.StopOut();
+ menu_.Activate(0); // OPEN 有効
+ if (!playOk) menu_.Activate(1); // PLAY 有効
+ for (int n=2; n<5; n++) // その他は無効
+ menu_.Inactivate(n);
+ sdReader_.Close(); // SD のファイルのクローズ
+ }
+ }
+
+ // SD カードのファイルのオープン
+ int32_t SD_PlayerSkeleton::SD_Open()
+ {
+ sdReader_.Open(fileName_);
+ sdReader_.IsWavFile();
+ return sdReader_.GetSize()/FRAME_SIZE_;
+ }
+
+ // ファイルの選択
+ // selectedName: 選択されたファイル名
+ void SD_PlayerSkeleton::SelectFile()
+ {
+ selector_.DisplayFileList();
+ title_.Draw("Select file");
+ do
+ {
+ if (selector_.Select(fileName_))
+ menu_.Activate(1); // PLAY 有効
+ wait_ms(200);
+ } while (!menu_.Touched(1)); // PLAY がタッチされるまで繰り返す
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SD_PlayerSkeleton.hpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,64 @@
+//--------------------------------------------------------------
+// SD プレーヤー用抽象基底クラス(ヘッダ)
+//
+// 2016/07/17, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef F746_SD_PLAYER_SKELETON_HPP
+#define F746_SD_PLAYER_SKELETON_HPP
+
+#include "SAI_InOut.hpp"
+#include "ButtonGroup.hpp"
+#include "FileSelectorWav.hpp"
+#include "SD_WavReader.hpp"
+
+using namespace Mikami;
+
+namespace Mikami
+{
+ class SD_PlayerSkeleton
+ {
+ public:
+ SD_PlayerSkeleton(string str, int fs);
+ virtual ~SD_PlayerSkeleton() {}
+ void Execute();
+
+ protected:
+ // ボタン用の定数
+ static const uint16_t BG_LEFT_ = 414;
+ static const uint16_t BG_WIDTH_ = 66;
+ static const uint16_t BG_HEIGHT_ = 36;
+
+ const int32_t FRAME_SIZE_; // フレームバッファのサイズ
+ Array<int16_t> sn_; // フレームバッファ
+
+ SaiIO mySai_;
+ SD_WavReader sdReader_; // SD カード読み込み用オブジェクト
+
+ string GetFileName() { return fileName_; }
+
+ private:
+ string fileName_; // 選択されたファイル名
+ Label title_; // 上部に表示されるタイトル
+ FileSelector selector_;
+ ButtonGroup menu_;
+
+ // SD カードのファイルのオープン
+ int32_t SD_Open();
+ // ファイルの選択
+ void SelectFile();
+
+ //-------------------------------------
+ // 以下は仮想関数
+ //-------------------------------------
+ // 1フレーム分の信号処理の実行
+ virtual void SignalProcessing() = 0;
+ // サウンドエフェクタのパラメータ変更など
+ virtual void Modefy() {}
+ // 曲の再生中に表示する
+ virtual void Display() {}
+ // サウンドエフェクタ処理のデータ等のクリア
+ virtual void Clear() {}
+ };
+}
+#endif // F746_SD_PLAYER_SKELETON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SD_WavReader.cpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,119 @@
+//--------------------------------------------------------------
+// SD_WavReader class
+// SD カードの *.wav ファイルの内容を読み出す
+// 以下のフォーマット以外は扱わない
+// PCM,16 ビットステレオ,標本化周波数 44.1 kHz
+//
+// 2016/06/17, 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.SetSize(bufferSize*2);
+ }
+
+ SD_WavReader::~SD_WavReader()
+ {
+ 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::ReadStereo(Array<int16_t>& dataL,
+ Array<int16_t>& dataR)
+ {
+ if (!ok_) ErrorMsg("Get data FAILED");
+ uint32_t size = dataL.Length();
+ fread(buffer, sizeof(int16_t), size*2, fp_);
+ for (int n=0; n<size; n++)
+ {
+ dataL[n] = buffer[2*n];
+ dataR[n] = buffer[2*n+1];
+ }
+ }
+
+ // ファイルからデータをモノラルに変換しての取得
+ void SD_WavReader::ReadAndToMono(Array<int16_t>& data)
+ {
+ if (!ok_) ErrorMsg("Get data FAILED");
+ uint32_t size = data.Length();
+ 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/SD_WavReader.hpp Mon Aug 15 04:38:45 2016 +0000
@@ -0,0 +1,73 @@
+//--------------------------------------------------------------
+// SD_WavReader class ---- Header
+// SD カードの *.wav ファイルの内容を読み出す
+// 以下のフォーマット以外は扱わない
+// PCM,16 ビットステレオ,標本化周波数 44.1 kHz
+//
+// 2016/07/12, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef SD_WAV_READER_HPP
+#define SD_WAV_READER_HPP
+
+#include "SDFileSystem.h"
+#include "BlinkLabel.hpp"
+#include "Array.hpp"
+#include <string>
+
+namespace Mikami
+{
+ class SD_WavReader
+ {
+ public:
+ SD_WavReader(int32_t bufferSize);
+ virtual ~SD_WavReader();
+
+ void Open(const string fileName);
+
+ void Close() { fclose(fp_); }
+
+ // ファイルのヘッダ読み込み
+ // 戻り値: *.wav で,16 ビットステレオ,
+ // 標本化周波数:44.1 kHz の場合 true
+ bool IsWavFile();
+
+ // ファイルからステレオデータの取得
+ void ReadStereo(Array<int16_t>& dataL, Array<int16_t>& dataR);
+
+ // ファイルからデータをモノラルに変換しての取得
+ void ReadAndToMono(Array<int16_t>& data);
+
+ // データサイズ(標本化点の数)の取得
+ 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; // PCM の場合使わない
+ };
+
+ SDFileSystem *sd_;
+ FILE *fp_;
+
+ bool ok_;
+ int32_t size_; // データサイズ(標本化点の数)
+ Array<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