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: SRC_STM32F7 F746-GUI SD_PlayerSkeleton F746-SAI-IO
main.cpp
- Committer:
- nhancap98
- Date:
- 2019-06-10
- Revision:
- 1:1e9ab332e036
- Parent:
- 0:415638154129
File content as of revision 1:1e9ab332e036:
//--------------------------------------------------------------------
#include "VolumeCtrl.hpp"
#include "FileSelectorWav.hpp"
#include "SD_PlayerSkeleton.hpp"
#include "SD_WavReader.hpp"
using namespace Mikami;
int main()
{
VolumeCtrl myPlayer("Music Player");
myPlayer.Execute();
}
//-------------------------------------------------
//Chuong trình con di?u ch?nh biên d? âm thanh
namespace Mikami
{
// Th?c thi x? lý tín hi?u cho m?t kh?i
void VolumeCtrl::SignalProcessing()
{
// Ð?c giá tr? d? li?u âm thanh n?i c?a m?t kh?i t? SD và bi?n nó thành don âm
sdReader_.ReadAndToMono(sn_);
while (!mySai_.IsXferred()) {} // Ch? cho d?n khi truy?n d? li?u hoàn t?t
for (int n=0; n<BUFF_SIZE_; n++)
{
int16_t data = volume_*sn_[n]; //Thay d?i âm lu?ng d?u ra
mySai_.Output(data, data);
}
//--------------------------------------------------------------
}
// Ði?u ch?nh âm lu?ng
void VolumeCtrl::Modefy()
{
if (myBar_.Slide())
volume_ = myBar_.GetValue();
}
// Hi?n th? khi phát m?t bài hát
void VolumeCtrl::Display()
{
Label musicTitle(207, 80, GetFileNameNoExt(), Label::CENTER, Font16);
ctrl_.Draw();
myBar_.Redraw();
}
}
//--------------------------------------------------------------
namespace Mikami
{
FileSelector::FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
int maxNameLength, SD_WavReader &reader)
: X_(x0), Y_(y0),
MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength),
fileNames_(maxFiles), fileNameLabels_(MAX_LIST_PAGE_),
next_(50, 238, 64, 36, 2, (string[]){"<", ">"}, 10, 0, 2, -1, Font24),
pageLabel_(210, 250, Label::LEFT, Font16),
lcd_(GuiBase::GetLcd()), sdReader_(reader), page_(1),
nOld_(-1), kOld_(-1)
{
Array<string> nonString(MAX_LIST_PAGE_, "");
rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, MAX_LIST_PAGE_,
nonString, 0, V_L_-W_H_, 1,
-1, Font12, 0, GuiBase::ENUM_BACK,
BASE_COLOR_, TOUCHED_COLOR_);
rect_->EraseAll();
next_.EraseAll();
// T?o Label
for (int n=0; n<MAX_LIST_PAGE_; n++)
fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
Label::LEFT, Font16, BASE_COLOR_);
}
FileSelector::~FileSelector()
{
delete rect_;
for (int n=0; n<MAX_LIST_PAGE_; n++) delete fileNameLabels_[n];
}
// L?p danh sách các t?p tin. Tr? v? false n?u t?p WAV không t?n t?i
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); // m? t?p tin
// Lo?i tr? các t?p không ph?i PCM, âm thanh n?i 16 bit, t?n s? l?y m?u 44,1 kHz
if (sdReader_.IsWavFile())
fileNames_[fileCount_++] = strName;
sdReader_.Close();
}
if (fileCount_ >= MAX_FILES_) break;
}
closedir(dp);
}
else
return false; // n?u th? SD không du?c cài d?t
if (fileCount_ == 0) return false; //N?u t?p WAV tuong ?ng không t?n t?i
div_t m = div(fileCount_, MAX_LIST_PAGE_);
maxPage_ = (m.rem == 0) ? m.quot : m.quot+1;
return true; //Khi t?p WAV tuong ?ng t?n t?i
}
// ch?n t?p tin
bool FileSelector::Select(string &fileName)
{
int m;
if (next_.GetTouchedNumber(m))
{
if (m==0) page_--;
else page_++;
DisplayFileList(false);
nOld_ = -1;
wait_ms(300);
}
int n;
if (rect_->GetTouchedNumber(n))
{
int k = (page_ - 1)*MAX_LIST_PAGE_ + n;
fileNameLabels_[n]->Draw(GetFileNameNoExt(k),
TOUCHED_COLOR_);
fileName = fileNames_[k];
// Tr? v? màu c?a tên t?p dã ch?n tru?c dó trên cùng m?t trang
if (nOld_ != -1)
fileNameLabels_[nOld_]->Draw(GetFileNameNoExt(kOld_),
BASE_COLOR_);
if (page_ == maxPage_) // xóa hình ch? nh?t ph? trên trang cu?i
for (int j=fileCount_ % MAX_LIST_PAGE_ + 1;
j < MAX_LIST_PAGE_; j++) rect_->Erase(j);
nOld_ = n;
kOld_ = k;
wait_ms(300);
return true;
}
else
return false;
}
// Hi?n th? danh sách các t?p tin
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_);
div_t m = div(fileCount_, MAX_LIST_PAGE_);
int count = (m.quot >= page_) ? MAX_LIST_PAGE_ : m.rem;
for (int n=0; n<count; n++) rect_->Draw(n);
for (int n=0; n<count; n++)
fileNameLabels_[n]->Draw(GetFileNameNoExt(n+(page_-1)*MAX_LIST_PAGE_));
// Hi?n th? trang tru?c, nút ch?n trang ti?p theo, v.v.
next_.InactivateAll();
if (page_ > 1) next_.Activate(0); // "<" h?p l?
if (page_ < maxPage_) next_.Activate(1); // ">" h?p l?
char page[6];
sprintf(page, "%d/%d", page_, maxPage_);
pageLabel_.Draw(page);
}
// xóa danh sách các t?p tin
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);
}
// L?y tên t?p v?i ph?n m? r?ng b? xóa
string FileSelector::GetFileNameNoExt(int n)
{
string name = fileNames_[n];
int k = name.rfind(".");
if (k != string::npos)
return name.erase(k);
else
return name;
}
}
//--------------------------------------------------------------
//chuong trình hi?n th? giao di?n & di?u khi?n
namespace Mikami
{
SD_PlayerSkeleton::SD_PlayerSkeleton(string str, bool resetButton)
: BUFF_SIZE_(2048), sn_(BUFF_SIZE_),
mySai_(SaiIO::OUTPUT, BUFF_SIZE_, AUDIO_FREQUENCY_44K),
sdReader_(BUFF_SIZE_),
fileName_(""),
title_(214, 4, str, Label::CENTER, Font16),
selector_(0, 22, 256, 37, sdReader_),
menu_(BG_LEFT_, 2, BG_WIDTH_, BG_HEIGHT_, 5,
(string[]){"SELECT", "PLAY", "PAUSE", "RESUME", "STOP"},
0, 2, 1)
{
menu_.InactivateAll();
menu_.Activate(0);
if (!selector_.CreateTable())
BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
if (resetButton) reset_ = new ResetButton();
else reset_ = NULL;
}
// th?c thi x? lý trình phát SD
void SD_PlayerSkeleton::Execute()
{
bool playOk = false;
int32_t loopCount;
while (true)
{
if (playOk) // Trong tru?ng h?p PLAY sau PAUSE
loopCount = SD_Open();
else // N?u không PLAY sau PAUSE
{
if (0 == WaitTouched()) SelectFile();
loopCount = SD_Open();
while (1 != WaitTouched()) {} // Ð?i cho d?n khi PLAY du?c ch?m
}
Display(); // X? lý hi?n th? dành riêng cho ?ng d?ng (ch?c nang ?o)
if (reset_ != NULL) reset_->Draw();
menu_.Inactivate(0); // SELECT b? vô hi?u hóa
menu_.Activate(2); // PAUSE b? vô hi?u hóa
menu_.Activate(4); // STOP b? vô hi?u hóa
playOk = false;
bool stopOk = false;
Clear(); // Quá trình xóa ?ng d?ng c? th? (ch?c nang ?o)
mySai_.PlayOut(); // Play
// L?p l?i cho d?n khi h?t d? li?u t?p
for (int k=0; k<loopCount; k++)
{
int touch42 = -1;
menu_.GetTouchedNumber(touch42);
if (touch42 == 4) break; // STOP
if (touch42 == 2) // PAUSE X? lý khi ch?m vào nút
{
menu_.Inactivate(2); // PAUSE Nút không h?p l?
menu_.Activate(3); // RESUME Ðã b?t nút
mySai_.PauseOut();
// PLAY Ð?i cho d?n khi 'RESUME' ho?c 'STOP' du?c ch?m vào
switch (WaitTouched())
{
case 1: playOk = true; // PLAY t? d?u
break;
case 3: mySai_.ResumeOut(); // Ti?p t?c PLAY t? di?m PAUSE
menu_.Activate(2);
menu_.Inactivate(3);
menu_.TouchedColor(1);
break;
case 4: stopOk = true; // STOP
break;
}
}
if (playOk || stopOk) break;
DoIfHandled();
// X? lý tín hi?u cho m?t kh?i dành riêng cho ?ng d?ng (hàm ?o thu?n túy)
SignalProcessing();
}
mySai_.StopOut();
if (!playOk) menu_.Activate(0); // SELECT h?p l?
menu_.Draw(1); // Kh?i t?o màu c?a nút PLAY
for (int n=2; n<5; n++) // Các nút khác b? vô hi?u hóa
menu_.Inactivate(n);
sdReader_.Close(); // Ðóng t?p SD
}
}
// L?y tên t?p dã ch?n mà không c?n ph?n m? r?ng
string SD_PlayerSkeleton::GetFileNameNoExt()
{
string fName = fileName_;
int k = fName.rfind(".");
if (k != string::npos)
return fName.erase(k);
else
return fName;
}
// M? t?p th? SD
int32_t SD_PlayerSkeleton::SD_Open()
{
if (fileName_.empty()) SelectFile();
sdReader_.Open(fileName_);
sdReader_.IsWavFile();
return sdReader_.GetSize()/BUFF_SIZE_;
}
// L?a ch?n t?p tin
void SD_PlayerSkeleton::SelectFile()
{
selector_.DisplayFileList();
title_.Draw("Select file");
menu_.Inactivate(0); // SELECT vô hi?u hóa
menu_.Inactivate(1); // PLAY vô hi?u hóa
do
if (selector_.Select(fileName_))
menu_.Activate(1); // PLAY dã b?t
while (!menu_.Touched(1)); // PLAY L?p l?i cho d?n khi nút du?c ch?m
selector_.Erase(0, 0, BG_LEFT_-4, 272);
title_.Draw();
}
// X? lý khi b?ng di?u khi?n du?c v?n hành
void SD_PlayerSkeleton::DoIfHandled()
{
if (reset_ != NULL) reset_->DoIfTouched();
Modefy(); // ?ng d?ng thay d?i tham s? c? th? (ch?c nang ?o)
}
//Ð?i trong khi th?c hi?n Do IfHandled () cho d?n khi b?t k? nút nào trên menu du?c ch?m vào
int SD_PlayerSkeleton::WaitTouched()
{
int touchNum;
while (!menu_.GetTouchedNumber(touchNum)) DoIfHandled();
return touchNum;
}
}
//-------------------------------------------------
//chuong trình con d?c file WAV-PCM-16bit-44.1KHz
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("Loi The SD!!!");
}
// Ð?c m?t ph?n c?a tiêu d? t?p "RIFFxxxxWAVEfmt"
// Giá tr? tr? v?: true n?u âm thanh n?i 16 bit, t?n s? l?y m?u là 44,1 kHz
bool SD_WavReader::IsWavFile()
{
char data[17];
fread(data, 1, 16, fp_); // Ð?c 16 byte
string strRead = "";
for (int n=0; n<4; n++) strRead += data[n];
// Không ki?m tra 4 ký t? gi?a
for (int n=8; n<16; n++) strRead += data[n];
// Ki?m tra xem "RIFF", "WAVE", "fmt" có t?n t?i không
if (strRead != "RIFFWAVEfmt ") return false;
// có du?c kích thu?c c?a fmt chunck
uint32_t fmtChunkSize;
fread(&fmtChunkSize, sizeof(uint32_t), 1, fp_);
// Xác nh?n r?ng dó là PCM, Stereo, 44.1 kHz, 16 bit
WaveFormatEx fmtData;
fread(&fmtData, fmtChunkSize, 1, fp_);
if ((fmtData.wFormatTag != 1) ||
(fmtData.nChannels != 2) ||
(fmtData.nSamplesPerSec != AUDIO_FREQUENCY_44K) ||
(fmtData.wBitsPerSample != 16)
) return false;
// Tìm d? li?u
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;
}
// Nh?n kích thu?c d? li?u (byte)
int32_t sizeByte;
fread(&sizeByte, sizeof(int32_t), 1, fp_);
size_ = sizeByte/4;
ok_ = true;
return true;
}
// Nh?n d? li?u âm thanh n?i t? t?p tin
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];
}
}
// Chuy?n d?i d? li?u t? t?p tin sang don âm
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;
}
// Thu th?p kích thu?c d? li?u (s? di?m l?y m?u)
int32_t SD_WavReader::GetSize()
{
if (!ok_) ErrorMsg("Get data size FAILED");
return size_;
}
}