diff options
| author | jdlugosz963 <jdlugosz963@gmail.com> | 2022-12-22 18:50:33 +0100 |
|---|---|---|
| committer | jdlugosz963 <jdlugosz963@gmail.com> | 2022-12-22 18:50:33 +0100 |
| commit | afe2df4dfa6d6858f5352f55e8e00ba05faf69fa (patch) | |
| tree | 700861716c349065de1f55938ff0c53c8d7f24d4 | |
| parent | 8ac38a78b40eef6c0b9bd770a28332537c339675 (diff) | |
| download | shack-afe2df4dfa6d6858f5352f55e8e00ba05faf69fa.tar.gz shack-afe2df4dfa6d6858f5352f55e8e00ba05faf69fa.zip | |
Add mp3 player
| -rw-r--r-- | mp3player.cpp | 275 | ||||
| -rw-r--r-- | mp3player.h | 69 | ||||
| -rw-r--r-- | schack.ino | 15 |
3 files changed, 359 insertions, 0 deletions
diff --git a/mp3player.cpp b/mp3player.cpp new file mode 100644 index 0000000..b57c5a1 --- /dev/null +++ b/mp3player.cpp | |||
| @@ -0,0 +1,275 @@ | |||
| 1 | #include "mp3player.h" | ||
| 2 | |||
| 3 | MP3List::MP3List(File *dir, ListMode mode) { | ||
| 4 | Serial.println("MP3List::MP3List"); | ||
| 5 | this->mode = mode; | ||
| 6 | int size = countListElements(dir); | ||
| 7 | |||
| 8 | list = new String[size]; | ||
| 9 | |||
| 10 | Serial.println(size); | ||
| 11 | |||
| 12 | listSize = size; | ||
| 13 | listCurrentPosition=0; | ||
| 14 | |||
| 15 | insertElementsToList(dir); | ||
| 16 | debug(); | ||
| 17 | } | ||
| 18 | |||
| 19 | MP3List::~MP3List() { | ||
| 20 | delete [] list; | ||
| 21 | } | ||
| 22 | |||
| 23 | void MP3List::debug() { | ||
| 24 | Serial.println("============"); | ||
| 25 | for(int i=0; i<listSize; i++) { | ||
| 26 | Serial.print(mode); | ||
| 27 | Serial.print(": "); | ||
| 28 | Serial.print(list[i]); | ||
| 29 | Serial.print("\n\n"); | ||
| 30 | } | ||
| 31 | Serial.print("List size"); | ||
| 32 | Serial.print(listSize); | ||
| 33 | Serial.print("\n"); | ||
| 34 | |||
| 35 | Serial.print("List position"); | ||
| 36 | Serial.print(listCurrentPosition); | ||
| 37 | Serial.print("\n"); | ||
| 38 | |||
| 39 | Serial.println("============"); | ||
| 40 | } | ||
| 41 | |||
| 42 | bool MP3List::canAdd(File *file) { | ||
| 43 | String fileName = file->name(); | ||
| 44 | |||
| 45 | switch(mode) { | ||
| 46 | case ListMode::SECTIONS: | ||
| 47 | Serial.println("SECTIONS"); | ||
| 48 | return file->isDirectory(); | ||
| 49 | break; | ||
| 50 | |||
| 51 | case ListMode::MUSIC_FILES: | ||
| 52 | Serial.println("MUSIC FILES"); | ||
| 53 | return fileName.endsWith(".mp3"); | ||
| 54 | break; | ||
| 55 | |||
| 56 | default: | ||
| 57 | Serial.println("DEFAULT"); | ||
| 58 | return false; | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | int MP3List::countListElements(File *dir) { | ||
| 64 | dir->rewindDirectory(); | ||
| 65 | |||
| 66 | if (!dir->isDirectory()) { | ||
| 67 | Serial.println("Not a directory"); | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | File file = dir->openNextFile(); | ||
| 72 | int elementsCount = 0; | ||
| 73 | while (file) { | ||
| 74 | if(canAdd(&file)) | ||
| 75 | elementsCount++; | ||
| 76 | |||
| 77 | file.close(); | ||
| 78 | file = dir->openNextFile(); | ||
| 79 | } | ||
| 80 | return elementsCount; | ||
| 81 | } | ||
| 82 | |||
| 83 | void MP3List::insertElementsToList(File *dir) { | ||
| 84 | dir->rewindDirectory(); | ||
| 85 | |||
| 86 | Serial.println("MP3List::insertElementsToList"); | ||
| 87 | if (!dir->isDirectory()) { | ||
| 88 | Serial.println("Not a directory"); | ||
| 89 | return; | ||
| 90 | } | ||
| 91 | |||
| 92 | File file = dir->openNextFile(); | ||
| 93 | int i=0; | ||
| 94 | while (file) { | ||
| 95 | if(canAdd(&file)) { | ||
| 96 | if (i > listSize) | ||
| 97 | continue; | ||
| 98 | list[i] = file.name(); | ||
| 99 | Serial.print("Dodaje: "); | ||
| 100 | Serial.print(file.name()); | ||
| 101 | Serial.print("\n"); | ||
| 102 | |||
| 103 | Serial.print("na index: "); | ||
| 104 | Serial.print(i); | ||
| 105 | Serial.print("\n"); | ||
| 106 | i++; | ||
| 107 | } | ||
| 108 | file.close(); | ||
| 109 | file = dir->openNextFile(); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | String MP3List::getCurrent() { | ||
| 114 | Serial.print("list size: "); | ||
| 115 | Serial.print(listSize); | ||
| 116 | Serial.print("\n"); | ||
| 117 | |||
| 118 | Serial.print("list current position: "); | ||
| 119 | Serial.print(listCurrentPosition); | ||
| 120 | Serial.print("\n"); | ||
| 121 | |||
| 122 | if(listCurrentPosition < listSize) | ||
| 123 | return list[listCurrentPosition]; | ||
| 124 | return ""; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | String MP3List::getNext() { | ||
| 129 | if(listCurrentPosition < listSize-1) | ||
| 130 | listCurrentPosition++; | ||
| 131 | else | ||
| 132 | listCurrentPosition = 0; | ||
| 133 | |||
| 134 | return getCurrent(); | ||
| 135 | } | ||
| 136 | |||
| 137 | String MP3List::getPrevious() { | ||
| 138 | if(listCurrentPosition > 0) | ||
| 139 | listCurrentPosition--; | ||
| 140 | else | ||
| 141 | listCurrentPosition = listSize-1; | ||
| 142 | |||
| 143 | return getCurrent(); | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 147 | MP3Player::MP3Player() { | ||
| 148 | Serial.println("MP3Player::MP3Player"); | ||
| 149 | |||
| 150 | source = new AudioFileSourceSD(); | ||
| 151 | mp3 = new AudioGeneratorMP3(); | ||
| 152 | out = new AudioOutputI2SNoDAC(); | ||
| 153 | updateListSections(); | ||
| 154 | } | ||
| 155 | |||
| 156 | MP3Player::~MP3Player() { | ||
| 157 | delete source; | ||
| 158 | delete mp3; | ||
| 159 | delete out; | ||
| 160 | |||
| 161 | delete listSections; | ||
| 162 | delete listMusicFiles; | ||
| 163 | } | ||
| 164 | |||
| 165 | void MP3Player::playMP3(String name) { | ||
| 166 | Serial.println("MP3Player::playMP3"); | ||
| 167 | Serial.println(name); | ||
| 168 | |||
| 169 | if (mp3->isRunning()) | ||
| 170 | mp3->stop(); | ||
| 171 | |||
| 172 | source->open(name.c_str()); | ||
| 173 | mp3->begin(source, out); | ||
| 174 | } | ||
| 175 | |||
| 176 | void MP3Player::loop() { | ||
| 177 | if (mp3->isRunning()) | ||
| 178 | if (!mp3->loop()) mp3->stop(); | ||
| 179 | } | ||
| 180 | |||
| 181 | void MP3Player::volumeUp() { | ||
| 182 | if(volume + volumeBy < 2.0) { | ||
| 183 | volume += volumeBy; | ||
| 184 | out->SetGain(volume); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | void MP3Player::volumeDown() { | ||
| 189 | if(volume - volumeBy > 0.0) { | ||
| 190 | volume -= volumeBy; | ||
| 191 | out->SetGain(volume); | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | String MP3Player::getFilePath(String fileName) { | ||
| 196 | Serial.println("MP3Player::getFilePath"); | ||
| 197 | String currentSection = listSections->getCurrent(); | ||
| 198 | |||
| 199 | if(currentSection == "" || fileName == "") | ||
| 200 | return ""; | ||
| 201 | return rootDir+"/"+currentSection+"/"+fileName; | ||
| 202 | } | ||
| 203 | |||
| 204 | void MP3Player::nextFile() { | ||
| 205 | Serial.println("MP3Player::next"); | ||
| 206 | String current = listMusicFiles->getNext(); | ||
| 207 | playMP3(getFilePath(current)); | ||
| 208 | } | ||
| 209 | |||
| 210 | void MP3Player::previousFile() { | ||
| 211 | Serial.println("MP3Player::previous"); | ||
| 212 | String current = listMusicFiles->getPrevious(); | ||
| 213 | playMP3(getFilePath(current)); | ||
| 214 | } | ||
| 215 | |||
| 216 | void MP3Player::nextSection() { | ||
| 217 | Serial.println("MP3Player::nextS"); | ||
| 218 | listSections->getNext(); | ||
| 219 | updateListMusicFiles(); | ||
| 220 | nextFile(); | ||
| 221 | } | ||
| 222 | |||
| 223 | void MP3Player::previousSection() { | ||
| 224 | Serial.println("MP3Player::previousS"); | ||
| 225 | listSections->getPrevious(); | ||
| 226 | updateListMusicFiles(); | ||
| 227 | nextFile(); | ||
| 228 | } | ||
| 229 | |||
| 230 | |||
| 231 | bool MP3Player::updateListSections() { | ||
| 232 | Serial.println("MP3Player::updateListSections"); | ||
| 233 | File root = SD.open(rootDir); | ||
| 234 | if (!root) { | ||
| 235 | Serial.println("Failed to open directory"); | ||
| 236 | return false; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (!root.isDirectory()) { | ||
| 240 | Serial.println("Not a directory"); | ||
| 241 | return false; | ||
| 242 | } | ||
| 243 | |||
| 244 | delete listSections; | ||
| 245 | listSections = new MP3List(&root, ListMode::SECTIONS); | ||
| 246 | // root.rewindDirectory(); | ||
| 247 | return updateListMusicFiles(); | ||
| 248 | } | ||
| 249 | |||
| 250 | bool MP3Player::updateListMusicFiles() { | ||
| 251 | Serial.println("MP3Player::updateMusicFiles"); | ||
| 252 | String currentSection = listSections->getCurrent(); | ||
| 253 | |||
| 254 | Serial.println("CURRENT SECTION: "); | ||
| 255 | Serial.println(currentSection); | ||
| 256 | if(currentSection == "") | ||
| 257 | return false; | ||
| 258 | |||
| 259 | File root = SD.open(rootDir + "/" + currentSection); | ||
| 260 | |||
| 261 | if (!root) { | ||
| 262 | Serial.println("Failed to open directory"); | ||
| 263 | return false; | ||
| 264 | } | ||
| 265 | if (!root.isDirectory()) { | ||
| 266 | Serial.println("Not a directory"); | ||
| 267 | return false; | ||
| 268 | } | ||
| 269 | |||
| 270 | delete listMusicFiles; | ||
| 271 | listMusicFiles = new MP3List(&root, ListMode::MUSIC_FILES); | ||
| 272 | // root.rewindDirectory(); | ||
| 273 | return true; | ||
| 274 | } | ||
| 275 | |||
diff --git a/mp3player.h b/mp3player.h new file mode 100644 index 0000000..c5efabb --- /dev/null +++ b/mp3player.h | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | #ifndef MP3_PLAYER_H | ||
| 2 | #define MP3_PLAYER_H | ||
| 3 | |||
| 4 | #include "AudioOutputI2SNoDAC.h" | ||
| 5 | #include "AudioGeneratorMP3.h" | ||
| 6 | #include "AudioFileSourceSD.h" | ||
| 7 | #include "AudioLogger.h" | ||
| 8 | #include "controller.h" | ||
| 9 | #include "SD.h" | ||
| 10 | #include <iostream> | ||
| 11 | |||
| 12 | |||
| 13 | enum ListMode { | ||
| 14 | SECTIONS=0, | ||
| 15 | MUSIC_FILES=1 | ||
| 16 | }; | ||
| 17 | |||
| 18 | class MP3List { | ||
| 19 | String *list; | ||
| 20 | int listSize = 0; | ||
| 21 | int listCurrentPosition = 0; | ||
| 22 | int countListElements(File*); | ||
| 23 | void insertElementsToList(File*); | ||
| 24 | bool canAdd(File*); | ||
| 25 | void debug(); | ||
| 26 | ListMode mode; | ||
| 27 | |||
| 28 | public: | ||
| 29 | MP3List(File*, ListMode); | ||
| 30 | ~MP3List(); | ||
| 31 | String getCurrent(); | ||
| 32 | String getNext(); | ||
| 33 | String getPrevious(); | ||
| 34 | }; | ||
| 35 | |||
| 36 | |||
| 37 | class MP3Player : public MP3Controller { | ||
| 38 | AudioFileSourceSD *source; | ||
| 39 | AudioGeneratorMP3 *mp3; | ||
| 40 | AudioOutputI2SNoDAC *out; | ||
| 41 | |||
| 42 | MP3List *listMusicFiles; | ||
| 43 | MP3List *listSections; | ||
| 44 | |||
| 45 | String currentFolder; | ||
| 46 | float volume=2.0; | ||
| 47 | float const volumeBy = 0.3; | ||
| 48 | |||
| 49 | String rootDir = "/"; | ||
| 50 | |||
| 51 | void playMP3(String); | ||
| 52 | bool updateListSections(); | ||
| 53 | bool updateListMusicFiles(); | ||
| 54 | String getFilePath(String); | ||
| 55 | |||
| 56 | |||
| 57 | public: | ||
| 58 | MP3Player(); | ||
| 59 | ~MP3Player(); | ||
| 60 | void volumeUp(); | ||
| 61 | void volumeDown(); | ||
| 62 | void nextSection() override; | ||
| 63 | void previousSection() override; | ||
| 64 | void nextFile() override; | ||
| 65 | void previousFile() override; | ||
| 66 | void loop(); | ||
| 67 | }; | ||
| 68 | |||
| 69 | #endif | ||
diff --git a/schack.ino b/schack.ino new file mode 100644 index 0000000..6efcf5c --- /dev/null +++ b/schack.ino | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | #include "mp3player.h" | ||
| 2 | |||
| 3 | MP3Player *mp3Player; | ||
| 4 | |||
| 5 | void setup() { | ||
| 6 | Serial.begin(9600); | ||
| 7 | SD.begin(SS); | ||
| 8 | |||
| 9 | mp3Player = new MP3Player(); | ||
| 10 | } | ||
| 11 | |||
| 12 | |||
| 13 | void loop() { | ||
| 14 | mp3Player->loop(); | ||
| 15 | } | ||
