a
Dependencies: SRC_STM32F7 F746-GUI SD_PlayerSkeleton F746-SAI-IO
main.cpp@0:a26ecfb99239, 2019-06-10 (annotated)
- Committer:
- fundokukiri
- Date:
- Mon Jun 10 08:05:28 2019 +0000
- Revision:
- 0:a26ecfb99239
a\
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fundokukiri | 0:a26ecfb99239 | 1 | |
fundokukiri | 0:a26ecfb99239 | 2 | //-------------------------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 3 | #include "VolumeCtrl.hpp" |
fundokukiri | 0:a26ecfb99239 | 4 | #include "FileSelectorWav.hpp" |
fundokukiri | 0:a26ecfb99239 | 5 | #include "SD_PlayerSkeleton.hpp" |
fundokukiri | 0:a26ecfb99239 | 6 | #include "SD_WavReader.hpp" |
fundokukiri | 0:a26ecfb99239 | 7 | |
fundokukiri | 0:a26ecfb99239 | 8 | using namespace Mikami; |
fundokukiri | 0:a26ecfb99239 | 9 | |
fundokukiri | 0:a26ecfb99239 | 10 | int main() |
fundokukiri | 0:a26ecfb99239 | 11 | { |
fundokukiri | 0:a26ecfb99239 | 12 | VolumeCtrl myPlayer("Music Player"); |
fundokukiri | 0:a26ecfb99239 | 13 | myPlayer.Execute(); |
fundokukiri | 0:a26ecfb99239 | 14 | |
fundokukiri | 0:a26ecfb99239 | 15 | } |
fundokukiri | 0:a26ecfb99239 | 16 | //------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 17 | //Chương trình con điều chỉnh biên độ âm thanh |
fundokukiri | 0:a26ecfb99239 | 18 | |
fundokukiri | 0:a26ecfb99239 | 19 | namespace Mikami |
fundokukiri | 0:a26ecfb99239 | 20 | { |
fundokukiri | 0:a26ecfb99239 | 21 | // Thực thi xử lý tín hiệu cho một khối |
fundokukiri | 0:a26ecfb99239 | 22 | void VolumeCtrl::SignalProcessing() |
fundokukiri | 0:a26ecfb99239 | 23 | { |
fundokukiri | 0:a26ecfb99239 | 24 | // Đọc giá trị dữ liệu âm thanh nổi của một khối từ SD và biến nó thành đơn âm |
fundokukiri | 0:a26ecfb99239 | 25 | sdReader_.ReadAndToMono(sn_); |
fundokukiri | 0:a26ecfb99239 | 26 | |
fundokukiri | 0:a26ecfb99239 | 27 | while (!mySai_.IsXferred()) {} // Chờ cho đến khi truyền dữ liệu hoàn tất |
fundokukiri | 0:a26ecfb99239 | 28 | |
fundokukiri | 0:a26ecfb99239 | 29 | for (int n=0; n<BUFF_SIZE_; n++) |
fundokukiri | 0:a26ecfb99239 | 30 | { |
fundokukiri | 0:a26ecfb99239 | 31 | int16_t data = volume_*sn_[n]; //Thay đổi âm lượng đầu ra |
fundokukiri | 0:a26ecfb99239 | 32 | mySai_.Output(data, data); |
fundokukiri | 0:a26ecfb99239 | 33 | } |
fundokukiri | 0:a26ecfb99239 | 34 | //-------------------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 35 | } |
fundokukiri | 0:a26ecfb99239 | 36 | |
fundokukiri | 0:a26ecfb99239 | 37 | // Điều chỉnh âm lượng |
fundokukiri | 0:a26ecfb99239 | 38 | void VolumeCtrl::Modefy() |
fundokukiri | 0:a26ecfb99239 | 39 | { |
fundokukiri | 0:a26ecfb99239 | 40 | if (myBar_.Slide()) |
fundokukiri | 0:a26ecfb99239 | 41 | volume_ = myBar_.GetValue(); |
fundokukiri | 0:a26ecfb99239 | 42 | } |
fundokukiri | 0:a26ecfb99239 | 43 | // Hiển thị khi phát một bài hát |
fundokukiri | 0:a26ecfb99239 | 44 | void VolumeCtrl::Display() |
fundokukiri | 0:a26ecfb99239 | 45 | { |
fundokukiri | 0:a26ecfb99239 | 46 | Label musicTitle(207, 80, GetFileNameNoExt(), Label::CENTER, Font16); |
fundokukiri | 0:a26ecfb99239 | 47 | ctrl_.Draw(); |
fundokukiri | 0:a26ecfb99239 | 48 | myBar_.Redraw(); |
fundokukiri | 0:a26ecfb99239 | 49 | } |
fundokukiri | 0:a26ecfb99239 | 50 | } |
fundokukiri | 0:a26ecfb99239 | 51 | //-------------------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 52 | namespace Mikami |
fundokukiri | 0:a26ecfb99239 | 53 | { |
fundokukiri | 0:a26ecfb99239 | 54 | FileSelector::FileSelector(uint8_t x0, uint8_t y0, int maxFiles, |
fundokukiri | 0:a26ecfb99239 | 55 | int maxNameLength, SD_WavReader &reader) |
fundokukiri | 0:a26ecfb99239 | 56 | : X_(x0), Y_(y0), |
fundokukiri | 0:a26ecfb99239 | 57 | MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength), |
fundokukiri | 0:a26ecfb99239 | 58 | fileNames_(maxFiles), fileNameLabels_(MAX_LIST_PAGE_), |
fundokukiri | 0:a26ecfb99239 | 59 | next_(50, 238, 64, 36, 2, (string[]){"<", ">"}, 10, 0, 2, -1, Font24), |
fundokukiri | 0:a26ecfb99239 | 60 | pageLabel_(210, 250, Label::LEFT, Font16), |
fundokukiri | 0:a26ecfb99239 | 61 | lcd_(GuiBase::GetLcd()), sdReader_(reader), page_(1), |
fundokukiri | 0:a26ecfb99239 | 62 | nOld_(-1), kOld_(-1) |
fundokukiri | 0:a26ecfb99239 | 63 | { |
fundokukiri | 0:a26ecfb99239 | 64 | Array<string> nonString(MAX_LIST_PAGE_, ""); |
fundokukiri | 0:a26ecfb99239 | 65 | rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, MAX_LIST_PAGE_, |
fundokukiri | 0:a26ecfb99239 | 66 | nonString, 0, V_L_-W_H_, 1, |
fundokukiri | 0:a26ecfb99239 | 67 | -1, Font12, 0, GuiBase::ENUM_BACK, |
fundokukiri | 0:a26ecfb99239 | 68 | BASE_COLOR_, TOUCHED_COLOR_); |
fundokukiri | 0:a26ecfb99239 | 69 | rect_->EraseAll(); |
fundokukiri | 0:a26ecfb99239 | 70 | next_.EraseAll(); |
fundokukiri | 0:a26ecfb99239 | 71 | |
fundokukiri | 0:a26ecfb99239 | 72 | // Tạo Label |
fundokukiri | 0:a26ecfb99239 | 73 | for (int n=0; n<MAX_LIST_PAGE_; n++) |
fundokukiri | 0:a26ecfb99239 | 74 | fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "", |
fundokukiri | 0:a26ecfb99239 | 75 | Label::LEFT, Font16, BASE_COLOR_); |
fundokukiri | 0:a26ecfb99239 | 76 | } |
fundokukiri | 0:a26ecfb99239 | 77 | |
fundokukiri | 0:a26ecfb99239 | 78 | FileSelector::~FileSelector() |
fundokukiri | 0:a26ecfb99239 | 79 | { |
fundokukiri | 0:a26ecfb99239 | 80 | delete rect_; |
fundokukiri | 0:a26ecfb99239 | 81 | for (int n=0; n<MAX_LIST_PAGE_; n++) delete fileNameLabels_[n]; |
fundokukiri | 0:a26ecfb99239 | 82 | } |
fundokukiri | 0:a26ecfb99239 | 83 | |
fundokukiri | 0:a26ecfb99239 | 84 | // Lập danh sách các tập tin. Trả về false nếu tệp WAV không tồn tại |
fundokukiri | 0:a26ecfb99239 | 85 | bool FileSelector::CreateTable() |
fundokukiri | 0:a26ecfb99239 | 86 | { |
fundokukiri | 0:a26ecfb99239 | 87 | DIR* dp = opendir("/sd"); |
fundokukiri | 0:a26ecfb99239 | 88 | fileCount_ = 0; |
fundokukiri | 0:a26ecfb99239 | 89 | if (dp != NULL) |
fundokukiri | 0:a26ecfb99239 | 90 | { |
fundokukiri | 0:a26ecfb99239 | 91 | dirent* entry; |
fundokukiri | 0:a26ecfb99239 | 92 | for (int n=0; n<256; n++) |
fundokukiri | 0:a26ecfb99239 | 93 | { |
fundokukiri | 0:a26ecfb99239 | 94 | entry = readdir(dp); |
fundokukiri | 0:a26ecfb99239 | 95 | if (entry == NULL) break; |
fundokukiri | 0:a26ecfb99239 | 96 | |
fundokukiri | 0:a26ecfb99239 | 97 | string strName = entry->d_name; |
fundokukiri | 0:a26ecfb99239 | 98 | if ( (strName.find(".wav") != string::npos) || |
fundokukiri | 0:a26ecfb99239 | 99 | (strName.find(".WAV") != string::npos) ) |
fundokukiri | 0:a26ecfb99239 | 100 | { |
fundokukiri | 0:a26ecfb99239 | 101 | sdReader_.Open(strName); // mở tập tin |
fundokukiri | 0:a26ecfb99239 | 102 | |
fundokukiri | 0:a26ecfb99239 | 103 | // 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 |
fundokukiri | 0:a26ecfb99239 | 104 | if (sdReader_.IsWavFile()) |
fundokukiri | 0:a26ecfb99239 | 105 | fileNames_[fileCount_++] = strName; |
fundokukiri | 0:a26ecfb99239 | 106 | sdReader_.Close(); |
fundokukiri | 0:a26ecfb99239 | 107 | } |
fundokukiri | 0:a26ecfb99239 | 108 | if (fileCount_ >= MAX_FILES_) break; |
fundokukiri | 0:a26ecfb99239 | 109 | } |
fundokukiri | 0:a26ecfb99239 | 110 | closedir(dp); |
fundokukiri | 0:a26ecfb99239 | 111 | } |
fundokukiri | 0:a26ecfb99239 | 112 | else |
fundokukiri | 0:a26ecfb99239 | 113 | return false; // nếu thẻ SD không được cài đặt |
fundokukiri | 0:a26ecfb99239 | 114 | if (fileCount_ == 0) return false; //Nếu tệp WAV tương ứng không tồn tại |
fundokukiri | 0:a26ecfb99239 | 115 | |
fundokukiri | 0:a26ecfb99239 | 116 | div_t m = div(fileCount_, MAX_LIST_PAGE_); |
fundokukiri | 0:a26ecfb99239 | 117 | maxPage_ = (m.rem == 0) ? m.quot : m.quot+1; |
fundokukiri | 0:a26ecfb99239 | 118 | return true; //Khi tệp WAV tương ứng tồn tại |
fundokukiri | 0:a26ecfb99239 | 119 | } |
fundokukiri | 0:a26ecfb99239 | 120 | |
fundokukiri | 0:a26ecfb99239 | 121 | // chọn tập tin |
fundokukiri | 0:a26ecfb99239 | 122 | bool FileSelector::Select(string &fileName) |
fundokukiri | 0:a26ecfb99239 | 123 | { |
fundokukiri | 0:a26ecfb99239 | 124 | int m; |
fundokukiri | 0:a26ecfb99239 | 125 | if (next_.GetTouchedNumber(m)) |
fundokukiri | 0:a26ecfb99239 | 126 | { |
fundokukiri | 0:a26ecfb99239 | 127 | if (m==0) page_--; |
fundokukiri | 0:a26ecfb99239 | 128 | else page_++; |
fundokukiri | 0:a26ecfb99239 | 129 | DisplayFileList(false); |
fundokukiri | 0:a26ecfb99239 | 130 | nOld_ = -1; |
fundokukiri | 0:a26ecfb99239 | 131 | wait_ms(300); |
fundokukiri | 0:a26ecfb99239 | 132 | } |
fundokukiri | 0:a26ecfb99239 | 133 | |
fundokukiri | 0:a26ecfb99239 | 134 | int n; |
fundokukiri | 0:a26ecfb99239 | 135 | if (rect_->GetTouchedNumber(n)) |
fundokukiri | 0:a26ecfb99239 | 136 | { |
fundokukiri | 0:a26ecfb99239 | 137 | int k = (page_ - 1)*MAX_LIST_PAGE_ + n; |
fundokukiri | 0:a26ecfb99239 | 138 | fileNameLabels_[n]->Draw(GetFileNameNoExt(k), |
fundokukiri | 0:a26ecfb99239 | 139 | TOUCHED_COLOR_); |
fundokukiri | 0:a26ecfb99239 | 140 | fileName = fileNames_[k]; |
fundokukiri | 0:a26ecfb99239 | 141 | // Trả về màu của tên tệp đã chọn trước đó trên cùng một trang |
fundokukiri | 0:a26ecfb99239 | 142 | if (nOld_ != -1) |
fundokukiri | 0:a26ecfb99239 | 143 | fileNameLabels_[nOld_]->Draw(GetFileNameNoExt(kOld_), |
fundokukiri | 0:a26ecfb99239 | 144 | BASE_COLOR_); |
fundokukiri | 0:a26ecfb99239 | 145 | if (page_ == maxPage_) // xóa hình chữ nhật phụ trên trang cuối |
fundokukiri | 0:a26ecfb99239 | 146 | for (int j=fileCount_ % MAX_LIST_PAGE_ + 1; |
fundokukiri | 0:a26ecfb99239 | 147 | j < MAX_LIST_PAGE_; j++) rect_->Erase(j); |
fundokukiri | 0:a26ecfb99239 | 148 | nOld_ = n; |
fundokukiri | 0:a26ecfb99239 | 149 | kOld_ = k; |
fundokukiri | 0:a26ecfb99239 | 150 | wait_ms(300); |
fundokukiri | 0:a26ecfb99239 | 151 | return true; |
fundokukiri | 0:a26ecfb99239 | 152 | } |
fundokukiri | 0:a26ecfb99239 | 153 | else |
fundokukiri | 0:a26ecfb99239 | 154 | return false; |
fundokukiri | 0:a26ecfb99239 | 155 | } |
fundokukiri | 0:a26ecfb99239 | 156 | |
fundokukiri | 0:a26ecfb99239 | 157 | // Hiển thị danh sách các tập tin |
fundokukiri | 0:a26ecfb99239 | 158 | void FileSelector::DisplayFileList(bool sortEnable) |
fundokukiri | 0:a26ecfb99239 | 159 | { |
fundokukiri | 0:a26ecfb99239 | 160 | if (sortEnable) |
fundokukiri | 0:a26ecfb99239 | 161 | std::sort((string *)fileNames_, |
fundokukiri | 0:a26ecfb99239 | 162 | (string *)fileNames_+fileCount_); |
fundokukiri | 0:a26ecfb99239 | 163 | |
fundokukiri | 0:a26ecfb99239 | 164 | Erase(X_, Y_, MAX_NAME_LENGTH_*((sFONT *)(&Font16))->Width, 272-Y_); |
fundokukiri | 0:a26ecfb99239 | 165 | |
fundokukiri | 0:a26ecfb99239 | 166 | div_t m = div(fileCount_, MAX_LIST_PAGE_); |
fundokukiri | 0:a26ecfb99239 | 167 | int count = (m.quot >= page_) ? MAX_LIST_PAGE_ : m.rem; |
fundokukiri | 0:a26ecfb99239 | 168 | for (int n=0; n<count; n++) rect_->Draw(n); |
fundokukiri | 0:a26ecfb99239 | 169 | for (int n=0; n<count; n++) |
fundokukiri | 0:a26ecfb99239 | 170 | fileNameLabels_[n]->Draw(GetFileNameNoExt(n+(page_-1)*MAX_LIST_PAGE_)); |
fundokukiri | 0:a26ecfb99239 | 171 | // Hiển thị trang trước, nút chọn trang tiếp theo, v.v. |
fundokukiri | 0:a26ecfb99239 | 172 | next_.InactivateAll(); |
fundokukiri | 0:a26ecfb99239 | 173 | if (page_ > 1) next_.Activate(0); // "<" hợp lệ |
fundokukiri | 0:a26ecfb99239 | 174 | if (page_ < maxPage_) next_.Activate(1); // ">" hợp lệ |
fundokukiri | 0:a26ecfb99239 | 175 | char page[6]; |
fundokukiri | 0:a26ecfb99239 | 176 | sprintf(page, "%d/%d", page_, maxPage_); |
fundokukiri | 0:a26ecfb99239 | 177 | pageLabel_.Draw(page); |
fundokukiri | 0:a26ecfb99239 | 178 | } |
fundokukiri | 0:a26ecfb99239 | 179 | |
fundokukiri | 0:a26ecfb99239 | 180 | // xóa danh sách các tập tin |
fundokukiri | 0:a26ecfb99239 | 181 | void FileSelector::Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height, |
fundokukiri | 0:a26ecfb99239 | 182 | uint32_t color) |
fundokukiri | 0:a26ecfb99239 | 183 | { |
fundokukiri | 0:a26ecfb99239 | 184 | lcd_.SetTextColor(color); |
fundokukiri | 0:a26ecfb99239 | 185 | lcd_.FillRect(x, y, width, height); |
fundokukiri | 0:a26ecfb99239 | 186 | } |
fundokukiri | 0:a26ecfb99239 | 187 | |
fundokukiri | 0:a26ecfb99239 | 188 | // Lấy tên tệp với phần mở rộng bị xóa |
fundokukiri | 0:a26ecfb99239 | 189 | string FileSelector::GetFileNameNoExt(int n) |
fundokukiri | 0:a26ecfb99239 | 190 | { |
fundokukiri | 0:a26ecfb99239 | 191 | string name = fileNames_[n]; |
fundokukiri | 0:a26ecfb99239 | 192 | int k = name.rfind("."); |
fundokukiri | 0:a26ecfb99239 | 193 | if (k != string::npos) |
fundokukiri | 0:a26ecfb99239 | 194 | return name.erase(k); |
fundokukiri | 0:a26ecfb99239 | 195 | else |
fundokukiri | 0:a26ecfb99239 | 196 | return name; |
fundokukiri | 0:a26ecfb99239 | 197 | } |
fundokukiri | 0:a26ecfb99239 | 198 | } |
fundokukiri | 0:a26ecfb99239 | 199 | //-------------------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 200 | //chương trình hiển thị giao diện & điều khiển |
fundokukiri | 0:a26ecfb99239 | 201 | |
fundokukiri | 0:a26ecfb99239 | 202 | namespace Mikami |
fundokukiri | 0:a26ecfb99239 | 203 | { |
fundokukiri | 0:a26ecfb99239 | 204 | SD_PlayerSkeleton::SD_PlayerSkeleton(string str, bool resetButton) |
fundokukiri | 0:a26ecfb99239 | 205 | : BUFF_SIZE_(2048), sn_(BUFF_SIZE_), |
fundokukiri | 0:a26ecfb99239 | 206 | mySai_(SaiIO::OUTPUT, BUFF_SIZE_, AUDIO_FREQUENCY_44K), |
fundokukiri | 0:a26ecfb99239 | 207 | sdReader_(BUFF_SIZE_), |
fundokukiri | 0:a26ecfb99239 | 208 | fileName_(""), |
fundokukiri | 0:a26ecfb99239 | 209 | title_(214, 4, str, Label::CENTER, Font16), |
fundokukiri | 0:a26ecfb99239 | 210 | selector_(0, 22, 256, 37, sdReader_), |
fundokukiri | 0:a26ecfb99239 | 211 | menu_(BG_LEFT_, 2, BG_WIDTH_, BG_HEIGHT_, 5, |
fundokukiri | 0:a26ecfb99239 | 212 | (string[]){"SELECT", "PLAY", "PAUSE", "RESUME", "STOP"}, |
fundokukiri | 0:a26ecfb99239 | 213 | 0, 2, 1) |
fundokukiri | 0:a26ecfb99239 | 214 | { |
fundokukiri | 0:a26ecfb99239 | 215 | menu_.InactivateAll(); |
fundokukiri | 0:a26ecfb99239 | 216 | menu_.Activate(0); |
fundokukiri | 0:a26ecfb99239 | 217 | |
fundokukiri | 0:a26ecfb99239 | 218 | if (!selector_.CreateTable()) |
fundokukiri | 0:a26ecfb99239 | 219 | BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER); |
fundokukiri | 0:a26ecfb99239 | 220 | |
fundokukiri | 0:a26ecfb99239 | 221 | if (resetButton) reset_ = new ResetButton(); |
fundokukiri | 0:a26ecfb99239 | 222 | else reset_ = NULL; |
fundokukiri | 0:a26ecfb99239 | 223 | } |
fundokukiri | 0:a26ecfb99239 | 224 | |
fundokukiri | 0:a26ecfb99239 | 225 | // thực thi xử lý trình phát SD |
fundokukiri | 0:a26ecfb99239 | 226 | void SD_PlayerSkeleton::Execute() |
fundokukiri | 0:a26ecfb99239 | 227 | { |
fundokukiri | 0:a26ecfb99239 | 228 | bool playOk = false; |
fundokukiri | 0:a26ecfb99239 | 229 | int32_t loopCount; |
fundokukiri | 0:a26ecfb99239 | 230 | |
fundokukiri | 0:a26ecfb99239 | 231 | while (true) |
fundokukiri | 0:a26ecfb99239 | 232 | { |
fundokukiri | 0:a26ecfb99239 | 233 | if (playOk) // Trong trường hợp PLAY sau PAUSE |
fundokukiri | 0:a26ecfb99239 | 234 | loopCount = SD_Open(); |
fundokukiri | 0:a26ecfb99239 | 235 | else // Nếu không PLAY sau PAUSE |
fundokukiri | 0:a26ecfb99239 | 236 | { |
fundokukiri | 0:a26ecfb99239 | 237 | if (0 == WaitTouched()) SelectFile(); |
fundokukiri | 0:a26ecfb99239 | 238 | loopCount = SD_Open(); |
fundokukiri | 0:a26ecfb99239 | 239 | while (1 != WaitTouched()) {} // Đợi cho đến khi PLAY được chạm |
fundokukiri | 0:a26ecfb99239 | 240 | } |
fundokukiri | 0:a26ecfb99239 | 241 | |
fundokukiri | 0:a26ecfb99239 | 242 | Display(); // Xử lý hiển thị dành riêng cho ứng dụng (chức năng ảo) |
fundokukiri | 0:a26ecfb99239 | 243 | if (reset_ != NULL) reset_->Draw(); |
fundokukiri | 0:a26ecfb99239 | 244 | |
fundokukiri | 0:a26ecfb99239 | 245 | menu_.Inactivate(0); // SELECT bị vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 246 | menu_.Activate(2); // PAUSE bị vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 247 | menu_.Activate(4); // STOP bị vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 248 | |
fundokukiri | 0:a26ecfb99239 | 249 | playOk = false; |
fundokukiri | 0:a26ecfb99239 | 250 | bool stopOk = false; |
fundokukiri | 0:a26ecfb99239 | 251 | |
fundokukiri | 0:a26ecfb99239 | 252 | Clear(); // Quá trình xóa ứng dụng cụ thể (chức năng ảo) |
fundokukiri | 0:a26ecfb99239 | 253 | |
fundokukiri | 0:a26ecfb99239 | 254 | mySai_.PlayOut(); // Play |
fundokukiri | 0:a26ecfb99239 | 255 | |
fundokukiri | 0:a26ecfb99239 | 256 | // Lặp lại cho đến khi hết dữ liệu tệp |
fundokukiri | 0:a26ecfb99239 | 257 | for (int k=0; k<loopCount; k++) |
fundokukiri | 0:a26ecfb99239 | 258 | { |
fundokukiri | 0:a26ecfb99239 | 259 | int touch42 = -1; |
fundokukiri | 0:a26ecfb99239 | 260 | menu_.GetTouchedNumber(touch42); |
fundokukiri | 0:a26ecfb99239 | 261 | if (touch42 == 4) break; // STOP |
fundokukiri | 0:a26ecfb99239 | 262 | if (touch42 == 2) // PAUSE Xử lý khi chạm vào nút |
fundokukiri | 0:a26ecfb99239 | 263 | { |
fundokukiri | 0:a26ecfb99239 | 264 | menu_.Inactivate(2); // PAUSE Nút không hợp lệ |
fundokukiri | 0:a26ecfb99239 | 265 | menu_.Activate(3); // RESUME Đã bật nút |
fundokukiri | 0:a26ecfb99239 | 266 | mySai_.PauseOut(); |
fundokukiri | 0:a26ecfb99239 | 267 | |
fundokukiri | 0:a26ecfb99239 | 268 | // PLAY Đợi cho đến khi 'RESUME' hoặc 'STOP' được chạm vào |
fundokukiri | 0:a26ecfb99239 | 269 | switch (WaitTouched()) |
fundokukiri | 0:a26ecfb99239 | 270 | { |
fundokukiri | 0:a26ecfb99239 | 271 | case 1: playOk = true; // PLAY từ đầu |
fundokukiri | 0:a26ecfb99239 | 272 | break; |
fundokukiri | 0:a26ecfb99239 | 273 | case 3: mySai_.ResumeOut(); // Tiếp tục PLAY từ điểm PAUSE |
fundokukiri | 0:a26ecfb99239 | 274 | menu_.Activate(2); |
fundokukiri | 0:a26ecfb99239 | 275 | menu_.Inactivate(3); |
fundokukiri | 0:a26ecfb99239 | 276 | menu_.TouchedColor(1); |
fundokukiri | 0:a26ecfb99239 | 277 | break; |
fundokukiri | 0:a26ecfb99239 | 278 | case 4: stopOk = true; // STOP |
fundokukiri | 0:a26ecfb99239 | 279 | break; |
fundokukiri | 0:a26ecfb99239 | 280 | } |
fundokukiri | 0:a26ecfb99239 | 281 | } |
fundokukiri | 0:a26ecfb99239 | 282 | if (playOk || stopOk) break; |
fundokukiri | 0:a26ecfb99239 | 283 | |
fundokukiri | 0:a26ecfb99239 | 284 | DoIfHandled(); |
fundokukiri | 0:a26ecfb99239 | 285 | // 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) |
fundokukiri | 0:a26ecfb99239 | 286 | SignalProcessing(); |
fundokukiri | 0:a26ecfb99239 | 287 | } |
fundokukiri | 0:a26ecfb99239 | 288 | mySai_.StopOut(); |
fundokukiri | 0:a26ecfb99239 | 289 | if (!playOk) menu_.Activate(0); // SELECT hợp lệ |
fundokukiri | 0:a26ecfb99239 | 290 | menu_.Draw(1); // Khởi tạo màu của nút PLAY |
fundokukiri | 0:a26ecfb99239 | 291 | for (int n=2; n<5; n++) // Các nút khác bị vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 292 | menu_.Inactivate(n); |
fundokukiri | 0:a26ecfb99239 | 293 | |
fundokukiri | 0:a26ecfb99239 | 294 | sdReader_.Close(); // Đóng tệp SD |
fundokukiri | 0:a26ecfb99239 | 295 | } |
fundokukiri | 0:a26ecfb99239 | 296 | } |
fundokukiri | 0:a26ecfb99239 | 297 | |
fundokukiri | 0:a26ecfb99239 | 298 | // Lấy tên tệp đã chọn mà không cần phần mở rộng |
fundokukiri | 0:a26ecfb99239 | 299 | string SD_PlayerSkeleton::GetFileNameNoExt() |
fundokukiri | 0:a26ecfb99239 | 300 | { |
fundokukiri | 0:a26ecfb99239 | 301 | string fName = fileName_; |
fundokukiri | 0:a26ecfb99239 | 302 | int k = fName.rfind("."); |
fundokukiri | 0:a26ecfb99239 | 303 | if (k != string::npos) |
fundokukiri | 0:a26ecfb99239 | 304 | return fName.erase(k); |
fundokukiri | 0:a26ecfb99239 | 305 | else |
fundokukiri | 0:a26ecfb99239 | 306 | return fName; |
fundokukiri | 0:a26ecfb99239 | 307 | } |
fundokukiri | 0:a26ecfb99239 | 308 | |
fundokukiri | 0:a26ecfb99239 | 309 | // Mở tệp thẻ SD |
fundokukiri | 0:a26ecfb99239 | 310 | int32_t SD_PlayerSkeleton::SD_Open() |
fundokukiri | 0:a26ecfb99239 | 311 | { |
fundokukiri | 0:a26ecfb99239 | 312 | if (fileName_.empty()) SelectFile(); |
fundokukiri | 0:a26ecfb99239 | 313 | sdReader_.Open(fileName_); |
fundokukiri | 0:a26ecfb99239 | 314 | sdReader_.IsWavFile(); |
fundokukiri | 0:a26ecfb99239 | 315 | return sdReader_.GetSize()/BUFF_SIZE_; |
fundokukiri | 0:a26ecfb99239 | 316 | } |
fundokukiri | 0:a26ecfb99239 | 317 | |
fundokukiri | 0:a26ecfb99239 | 318 | // Lựa chọn tập tin |
fundokukiri | 0:a26ecfb99239 | 319 | void SD_PlayerSkeleton::SelectFile() |
fundokukiri | 0:a26ecfb99239 | 320 | { |
fundokukiri | 0:a26ecfb99239 | 321 | selector_.DisplayFileList(); |
fundokukiri | 0:a26ecfb99239 | 322 | title_.Draw("Select file"); |
fundokukiri | 0:a26ecfb99239 | 323 | menu_.Inactivate(0); // SELECT vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 324 | menu_.Inactivate(1); // PLAY vô hiệu hóa |
fundokukiri | 0:a26ecfb99239 | 325 | do |
fundokukiri | 0:a26ecfb99239 | 326 | if (selector_.Select(fileName_)) |
fundokukiri | 0:a26ecfb99239 | 327 | menu_.Activate(1); // PLAY đã bật |
fundokukiri | 0:a26ecfb99239 | 328 | while (!menu_.Touched(1)); // PLAY Lặp lại cho đến khi nút được chạm |
fundokukiri | 0:a26ecfb99239 | 329 | |
fundokukiri | 0:a26ecfb99239 | 330 | selector_.Erase(0, 0, BG_LEFT_-4, 272); |
fundokukiri | 0:a26ecfb99239 | 331 | title_.Draw(); |
fundokukiri | 0:a26ecfb99239 | 332 | } |
fundokukiri | 0:a26ecfb99239 | 333 | |
fundokukiri | 0:a26ecfb99239 | 334 | // Xử lý khi bảng điều khiển được vận hành |
fundokukiri | 0:a26ecfb99239 | 335 | void SD_PlayerSkeleton::DoIfHandled() |
fundokukiri | 0:a26ecfb99239 | 336 | { |
fundokukiri | 0:a26ecfb99239 | 337 | if (reset_ != NULL) reset_->DoIfTouched(); |
fundokukiri | 0:a26ecfb99239 | 338 | Modefy(); // Ứng dụng thay đổi tham số cụ thể (chức năng ảo) |
fundokukiri | 0:a26ecfb99239 | 339 | } |
fundokukiri | 0:a26ecfb99239 | 340 | |
fundokukiri | 0:a26ecfb99239 | 341 | //Đợi trong khi thực hiện Do IfHandled () cho đến khi bất kỳ nút nào trên menu được chạm vào |
fundokukiri | 0:a26ecfb99239 | 342 | int SD_PlayerSkeleton::WaitTouched() |
fundokukiri | 0:a26ecfb99239 | 343 | { |
fundokukiri | 0:a26ecfb99239 | 344 | int touchNum; |
fundokukiri | 0:a26ecfb99239 | 345 | while (!menu_.GetTouchedNumber(touchNum)) DoIfHandled(); |
fundokukiri | 0:a26ecfb99239 | 346 | return touchNum; |
fundokukiri | 0:a26ecfb99239 | 347 | } |
fundokukiri | 0:a26ecfb99239 | 348 | } |
fundokukiri | 0:a26ecfb99239 | 349 | //------------------------------------------------- |
fundokukiri | 0:a26ecfb99239 | 350 | //chương trình con đọc file WAV-PCM-16bit-44.1KHz |
fundokukiri | 0:a26ecfb99239 | 351 | |
fundokukiri | 0:a26ecfb99239 | 352 | namespace Mikami |
fundokukiri | 0:a26ecfb99239 | 353 | { |
fundokukiri | 0:a26ecfb99239 | 354 | SD_WavReader::SD_WavReader(int32_t bufferSize) |
fundokukiri | 0:a26ecfb99239 | 355 | : STR_("sd"), ok_(false) |
fundokukiri | 0:a26ecfb99239 | 356 | { |
fundokukiri | 0:a26ecfb99239 | 357 | sd_ = new SDFileSystem(STR_.c_str()); |
fundokukiri | 0:a26ecfb99239 | 358 | sd_->mount(); |
fundokukiri | 0:a26ecfb99239 | 359 | buffer.SetSize(bufferSize*2); |
fundokukiri | 0:a26ecfb99239 | 360 | } |
fundokukiri | 0:a26ecfb99239 | 361 | |
fundokukiri | 0:a26ecfb99239 | 362 | SD_WavReader::~SD_WavReader() |
fundokukiri | 0:a26ecfb99239 | 363 | { |
fundokukiri | 0:a26ecfb99239 | 364 | sd_->unmount(); |
fundokukiri | 0:a26ecfb99239 | 365 | delete sd_; |
fundokukiri | 0:a26ecfb99239 | 366 | } |
fundokukiri | 0:a26ecfb99239 | 367 | |
fundokukiri | 0:a26ecfb99239 | 368 | void SD_WavReader::Open(const string fileName) |
fundokukiri | 0:a26ecfb99239 | 369 | { |
fundokukiri | 0:a26ecfb99239 | 370 | string name = (string)"/" + STR_ + "/" + fileName; |
fundokukiri | 0:a26ecfb99239 | 371 | fp_ = fopen(name.c_str(), "rb"); |
fundokukiri | 0:a26ecfb99239 | 372 | if (fp_ == NULL) ErrorMsg("Loi The SD!!!"); |
fundokukiri | 0:a26ecfb99239 | 373 | } |
fundokukiri | 0:a26ecfb99239 | 374 | |
fundokukiri | 0:a26ecfb99239 | 375 | |
fundokukiri | 0:a26ecfb99239 | 376 | // Đọc một phần của tiêu đề tệp "RIFFxxxxWAVEfmt" |
fundokukiri | 0:a26ecfb99239 | 377 | // Giá trị trả về: true nếu âm thanh nổi 16 bit, tần số lấy mẫu là 44,1 kHz |
fundokukiri | 0:a26ecfb99239 | 378 | bool SD_WavReader::IsWavFile() |
fundokukiri | 0:a26ecfb99239 | 379 | { |
fundokukiri | 0:a26ecfb99239 | 380 | char data[17]; |
fundokukiri | 0:a26ecfb99239 | 381 | fread(data, 1, 16, fp_); // Đọc 16 byte |
fundokukiri | 0:a26ecfb99239 | 382 | string strRead = ""; |
fundokukiri | 0:a26ecfb99239 | 383 | for (int n=0; n<4; n++) strRead += data[n]; |
fundokukiri | 0:a26ecfb99239 | 384 | // Không kiểm tra 4 ký tự giữa |
fundokukiri | 0:a26ecfb99239 | 385 | for (int n=8; n<16; n++) strRead += data[n]; |
fundokukiri | 0:a26ecfb99239 | 386 | |
fundokukiri | 0:a26ecfb99239 | 387 | // Kiểm tra xem "RIFF", "WAVE", "fmt" có tồn tại không |
fundokukiri | 0:a26ecfb99239 | 388 | if (strRead != "RIFFWAVEfmt ") return false; |
fundokukiri | 0:a26ecfb99239 | 389 | |
fundokukiri | 0:a26ecfb99239 | 390 | // có được kích thước của fmt chunck |
fundokukiri | 0:a26ecfb99239 | 391 | uint32_t fmtChunkSize; |
fundokukiri | 0:a26ecfb99239 | 392 | fread(&fmtChunkSize, sizeof(uint32_t), 1, fp_); |
fundokukiri | 0:a26ecfb99239 | 393 | |
fundokukiri | 0:a26ecfb99239 | 394 | // Xác nhận rằng đó là PCM, Stereo, 44.1 kHz, 16 bit |
fundokukiri | 0:a26ecfb99239 | 395 | WaveFormatEx fmtData; |
fundokukiri | 0:a26ecfb99239 | 396 | fread(&fmtData, fmtChunkSize, 1, fp_); |
fundokukiri | 0:a26ecfb99239 | 397 | if ((fmtData.wFormatTag != 1) || |
fundokukiri | 0:a26ecfb99239 | 398 | (fmtData.nChannels != 2) || |
fundokukiri | 0:a26ecfb99239 | 399 | (fmtData.nSamplesPerSec != AUDIO_FREQUENCY_44K) || |
fundokukiri | 0:a26ecfb99239 | 400 | (fmtData.wBitsPerSample != 16) |
fundokukiri | 0:a26ecfb99239 | 401 | ) return false; |
fundokukiri | 0:a26ecfb99239 | 402 | |
fundokukiri | 0:a26ecfb99239 | 403 | // Tìm dữ liệu |
fundokukiri | 0:a26ecfb99239 | 404 | char dataId[5]; |
fundokukiri | 0:a26ecfb99239 | 405 | dataId[4] = 0; |
fundokukiri | 0:a26ecfb99239 | 406 | fread(dataId, 1, 4, fp_); |
fundokukiri | 0:a26ecfb99239 | 407 | if ("data" != (string)dataId) |
fundokukiri | 0:a26ecfb99239 | 408 | for (int n=0; n<100; n++) |
fundokukiri | 0:a26ecfb99239 | 409 | { |
fundokukiri | 0:a26ecfb99239 | 410 | char oneByte; |
fundokukiri | 0:a26ecfb99239 | 411 | fread(&oneByte, 1, 1, fp_); |
fundokukiri | 0:a26ecfb99239 | 412 | for (int k=0; k<3; k++) |
fundokukiri | 0:a26ecfb99239 | 413 | dataId[k] = dataId[k+1]; |
fundokukiri | 0:a26ecfb99239 | 414 | dataId[3] = oneByte; |
fundokukiri | 0:a26ecfb99239 | 415 | if ("data" == (string)dataId) break; |
fundokukiri | 0:a26ecfb99239 | 416 | |
fundokukiri | 0:a26ecfb99239 | 417 | if (n == 99) return false; |
fundokukiri | 0:a26ecfb99239 | 418 | } |
fundokukiri | 0:a26ecfb99239 | 419 | |
fundokukiri | 0:a26ecfb99239 | 420 | // Nhận kích thước dữ liệu (byte) |
fundokukiri | 0:a26ecfb99239 | 421 | int32_t sizeByte; |
fundokukiri | 0:a26ecfb99239 | 422 | fread(&sizeByte, sizeof(int32_t), 1, fp_); |
fundokukiri | 0:a26ecfb99239 | 423 | size_ = sizeByte/4; |
fundokukiri | 0:a26ecfb99239 | 424 | |
fundokukiri | 0:a26ecfb99239 | 425 | ok_ = true; |
fundokukiri | 0:a26ecfb99239 | 426 | return true; |
fundokukiri | 0:a26ecfb99239 | 427 | } |
fundokukiri | 0:a26ecfb99239 | 428 | |
fundokukiri | 0:a26ecfb99239 | 429 | // Nhận dữ liệu âm thanh nổi từ tập tin |
fundokukiri | 0:a26ecfb99239 | 430 | void SD_WavReader::ReadStereo(Array<int16_t>& dataL, |
fundokukiri | 0:a26ecfb99239 | 431 | Array<int16_t>& dataR) |
fundokukiri | 0:a26ecfb99239 | 432 | { |
fundokukiri | 0:a26ecfb99239 | 433 | if (!ok_) ErrorMsg("Get data FAILED"); |
fundokukiri | 0:a26ecfb99239 | 434 | uint32_t size = dataL.Length(); |
fundokukiri | 0:a26ecfb99239 | 435 | fread(buffer, sizeof(int16_t), size*2, fp_); |
fundokukiri | 0:a26ecfb99239 | 436 | for (int n=0; n<size; n++) |
fundokukiri | 0:a26ecfb99239 | 437 | { |
fundokukiri | 0:a26ecfb99239 | 438 | dataL[n] = buffer[2*n]; |
fundokukiri | 0:a26ecfb99239 | 439 | dataR[n] = buffer[2*n+1]; |
fundokukiri | 0:a26ecfb99239 | 440 | } |
fundokukiri | 0:a26ecfb99239 | 441 | } |
fundokukiri | 0:a26ecfb99239 | 442 | |
fundokukiri | 0:a26ecfb99239 | 443 | // Chuyển đổi dữ liệu từ tập tin sang đơn âm |
fundokukiri | 0:a26ecfb99239 | 444 | void SD_WavReader::ReadAndToMono(Array<int16_t>& data) |
fundokukiri | 0:a26ecfb99239 | 445 | { |
fundokukiri | 0:a26ecfb99239 | 446 | if (!ok_) ErrorMsg("Get data FAILED"); |
fundokukiri | 0:a26ecfb99239 | 447 | uint32_t size = data.Length(); |
fundokukiri | 0:a26ecfb99239 | 448 | fread(buffer, sizeof(int16_t), size*2, fp_); |
fundokukiri | 0:a26ecfb99239 | 449 | for (int n=0; n<size; n++) |
fundokukiri | 0:a26ecfb99239 | 450 | data[n] = (buffer[2*n] + buffer[2*n+1])/2; |
fundokukiri | 0:a26ecfb99239 | 451 | } |
fundokukiri | 0:a26ecfb99239 | 452 | |
fundokukiri | 0:a26ecfb99239 | 453 | // Thu thập kích thước dữ liệu (số điểm lấy mẫu) |
fundokukiri | 0:a26ecfb99239 | 454 | int32_t SD_WavReader::GetSize() |
fundokukiri | 0:a26ecfb99239 | 455 | { |
fundokukiri | 0:a26ecfb99239 | 456 | if (!ok_) ErrorMsg("Get data size FAILED"); |
fundokukiri | 0:a26ecfb99239 | 457 | return size_; |
fundokukiri | 0:a26ecfb99239 | 458 | } |
fundokukiri | 0:a26ecfb99239 | 459 | } |