├── library.properties ├── .github ├── workflows │ └── githubci.yml ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── README.md ├── Adafruit_Soundboard.h ├── examples └── menucommands │ └── menucommands.ino └── Adafruit_Soundboard.cpp /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit Soundboard library 2 | version=1.1.2 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Arduino Library for UART control of the Adafruit Soundboard 6 | paragraph=Arduino Library for UART control of the Adafruit Soundboard 7 | category=Device Control 8 | url=https://github.com/adafruit/Adafruit_Soundboard_library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py uno leonardo mega2560 24 | 25 | - name: clang 26 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 27 | 28 | - name: doxygen 29 | env: 30 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 31 | PRETTYNAME : "Adafruit SoundBoard Library" 32 | run: bash ci/doxy_gen_and_deploy.sh 33 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit_Soundboard_library [![Build Status](https://github.com/adafruit/Adafruit_Soundboard_library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_Soundboard_library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_Soundboard_library/html/index.html) 2 | 3 | This is a library for the Adafruit Audio FX Sound Boards in UART mode 4 | 5 | * [Adafruit Audio FX Mini Sound Board - WAV/OGG Trigger - 2MB Flash](https://www.adafruit.com/products/2342) 6 | * [Adafruit Audio FX Mini Sound Board - WAV/OGG Trigger - 16MB Flash](https://www.adafruit.com/products/2341) 7 | * [Adafruit Audio FX Sound Board + 2x2W Amp - WAV/OGG Trigger - 2MB](https://www.adafruit.com/products/2210) 8 | * [Adafruit Audio FX Sound Board + 2x2W Amp - WAV/OGG Trigger - 16MB](https://www.adafruit.com/products/2217) 9 | * [Adafruit Audio FX Sound Board - WAV/OGG Trigger with 2MB Flash](https://www.adafruit.com/products/2133) 10 | * [Adafruit Audio FX Sound Board - WAV/OGG Trigger with 16MB Flash](https://www.adafruit.com/products/2220) 11 | 12 | Check out the links above for our tutorials and wiring diagrams 13 | This sound fx driver uses TTL Serial to communicate 14 | 15 | This is a list of the UART strings that will trigger actions on the Sound Board. For more details, see [Adafruit_Soundboard.cpp](Adafruit_Soundboard.cpp) (all commands must be followed by a carriage return character (`\r`) and then a new line character(`\n`), just like Serial.println()) 16 | 17 | | ASCII Character(s) sent to Sound Board | Description | 18 | | :---: | :---: | 19 | | `L` | [return a list of all the files on the Sound Board over the serial connection](Adafruit_Soundboard.cpp#L94) | 20 | | `#{n}` | [play song number "{n}"](Adafruit_Soundboard.cpp#L142) | 21 | | `P{name}` | [play song with a name of "{name}"](Adafruit_Soundboard.cpp#L170) | 22 | | `+` | [increase the volume](Adafruit_Soundboard.cpp#L195) | 23 | | `-` | [decrease the volume](Adafruit_Soundboard.cpp#L208) | 24 | | `=` | [pause playback](Adafruit_Soundboard.cpp#L221) | 25 | | `>` | [resume playback](Adafruit_Soundboard.cpp#L235) | 26 | | `q` | [stop playback](Adafruit_Soundboard.cpp#L248) | 27 | | `t` | [return the current time in the track and the total time of the track in seconds over the serial connection](Adafruit_Soundboard.cpp#L262) | 28 | | `s` | [return the remaining size of the track and the total size of the track in bytes over the serial connection](Adafruit_Soundboard.cpp#L277) | 29 | 30 | 31 | Adafruit invests time and resources providing this open source code, 32 | please support Adafruit and open-source hardware by purchasing 33 | products from Adafruit! 34 | 35 | Written by Limor Fried/Ladyada for Adafruit Industries. 36 | MIT license, all text above must be included in any redistribution 37 | 38 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_Soundboard. Check that the Adafruit_Soundboard folder contains Adafruit_Soundboard.cpp and Adafruit_Soundboard.h 39 | 40 | Place the Adafruit_Soundboard library folder your *arduinosketchfolder*/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE 41 | 42 | We also have a great tutorial at: 43 | https://learn.adafruit.com/adafruit-audio-fx-sound-board 44 | -------------------------------------------------------------------------------- /Adafruit_Soundboard.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_Soundboard.h 3 | */ 4 | 5 | #ifndef _ADAFRUIT_SOUNDBOARD_H_ 6 | #define _ADAFRUIT_SOUNDBOARD_H_ 7 | 8 | #include "Arduino.h" 9 | 10 | #define LINE_BUFFER_SIZE 80 //!< Size of the line buffer 11 | #define MAXFILES 25 //!< Max number of files 12 | 13 | /*! 14 | * @brief Class that stores the state and functions of the soundboard object 15 | */ 16 | class Adafruit_Soundboard : public Print { 17 | public: 18 | /*! 19 | * @brief Adafruit_Soundboard constructor 20 | * @param s Pointer to the Serial stream 21 | * @param d Pointer to the debug port 22 | * @param r Reset pin 23 | */ 24 | Adafruit_Soundboard(Stream *s, Stream *d, int8_t r); 25 | 26 | boolean reset(void); 27 | 28 | /*! 29 | * @brief Reads a line from the stream 30 | * @return Returns the line read 31 | */ 32 | int readLine(void); 33 | uint8_t listFiles(void); 34 | 35 | /*! 36 | * @brief Returns the filename 37 | * @param n Id of the file 38 | * @return Returns the filename 39 | */ 40 | char *fileName(uint8_t n); 41 | /*! 42 | * @brief Returns the size of the file 43 | * @param n id of the file 44 | * @return Returns the filesize 45 | */ 46 | uint32_t fileSize(uint8_t n); 47 | 48 | /*! 49 | * @brief Raises the volume 50 | * @return Returns the current volume 51 | */ 52 | uint8_t volUp(void); 53 | /*! 54 | * @brief Lowers the volume 55 | * @return Returns the current volume 56 | */ 57 | uint8_t volDown(void); 58 | 59 | /*! 60 | * @brief Play the specified track 61 | * @param n track id 62 | * @return Returns true if the track was played 63 | */ 64 | boolean playTrack(uint8_t n); 65 | /*! 66 | * @brief Play the specified track 67 | * @param name track name 68 | * @return Returns true if the track was played 69 | */ 70 | boolean playTrack(char *name); 71 | /*! 72 | * @brief Pauses track 73 | * @return Returns if pausing was successful 74 | */ 75 | boolean pause(void); 76 | /*! 77 | * @brief Unpauses track 78 | * @return Returns if unpausing was successful 79 | */ 80 | boolean unpause(void); 81 | /*! 82 | * @brief Stops track 83 | * @return Returns if stopping was successful 84 | */ 85 | boolean stop(void); 86 | 87 | /*! 88 | * @brief Returns the track time 89 | * @param current Buffer with the current track time 90 | * @param total Buffer with the total track time 91 | * @return Returns the current track time 92 | */ 93 | boolean trackTime(uint32_t *current, uint32_t *total); 94 | /*! 95 | * @brief Returns the track size 96 | * @param current Buffer with the current track size 97 | * @param total Buffer with the total track size 98 | * @return Returns how many bytes are remaining over the total track size 99 | */ 100 | boolean trackSize(uint32_t *current, uint32_t *total); 101 | 102 | private: 103 | Stream *stream; // -> sound board, e.g. SoftwareSerial or Serial1 104 | Stream *debug; // -> host, e.g. Serial 105 | 106 | int8_t reset_pin; 107 | char line_buffer[LINE_BUFFER_SIZE]; 108 | boolean writing; 109 | 110 | // File name & size caching 111 | uint8_t files; 112 | char filenames[MAXFILES][12]; 113 | uint32_t filesizes[MAXFILES]; 114 | 115 | virtual size_t write(uint8_t); // Because Print subclass 116 | }; 117 | #endif 118 | -------------------------------------------------------------------------------- /examples/menucommands/menucommands.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Menu driven control of a sound board over UART. 3 | Commands for playing by # or by name (full 11-char name) 4 | Hard reset and List files (when not playing audio) 5 | Vol + and - (only when not playing audio) 6 | Pause, unpause, quit playing (when playing audio) 7 | Current play time, and bytes remaining & total bytes (when playing audio) 8 | 9 | Connect UG to ground to have the sound board boot into UART mode 10 | */ 11 | 12 | #include 13 | #include "Adafruit_Soundboard.h" 14 | 15 | 16 | // Choose any two pins that can be used with SoftwareSerial to RX & TX 17 | #define SFX_TX 5 18 | #define SFX_RX 6 19 | 20 | // Connect to the RST pin on the Sound Board 21 | #define SFX_RST 4 22 | 23 | // You can also monitor the ACT pin for when audio is playing! 24 | 25 | // we'll be using software serial 26 | SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); 27 | 28 | // pass the software serial to Adafruit_soundboard, the second 29 | // argument is the debug port (not used really) and the third 30 | // arg is the reset pin 31 | Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST); 32 | // can also try hardware serial with 33 | // Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST); 34 | 35 | void setup() { 36 | Serial.begin(115200); 37 | Serial.println("Adafruit Sound Board!"); 38 | 39 | // softwareserial at 9600 baud 40 | ss.begin(9600); 41 | // can also do Serial1.begin(9600) 42 | 43 | if (!sfx.reset()) { 44 | Serial.println("Not found"); 45 | while (1); 46 | } 47 | Serial.println("SFX board found"); 48 | } 49 | 50 | 51 | void loop() { 52 | flushInput(); 53 | 54 | Serial.println(F("What would you like to do?")); 55 | Serial.println(F("[r] - reset")); 56 | Serial.println(F("[+] - Vol +")); 57 | Serial.println(F("[-] - Vol -")); 58 | Serial.println(F("[L] - List files")); 59 | Serial.println(F("[P] - play by file name")); 60 | Serial.println(F("[#] - play by file number")); 61 | Serial.println(F("[=] - pause playing")); 62 | Serial.println(F("[>] - unpause playing")); 63 | Serial.println(F("[q] - stop playing")); 64 | Serial.println(F("[t] - playtime status")); 65 | Serial.println(F("> ")); 66 | 67 | while (!Serial.available()); 68 | char cmd = Serial.read(); 69 | 70 | flushInput(); 71 | 72 | switch (cmd) { 73 | case 'r': { 74 | if (!sfx.reset()) { 75 | Serial.println("Reset failed"); 76 | } 77 | break; 78 | } 79 | 80 | case 'L': { 81 | uint8_t files = sfx.listFiles(); 82 | 83 | Serial.println("File Listing"); 84 | Serial.println("========================"); 85 | Serial.println(); 86 | Serial.print("Found "); Serial.print(files); Serial.println(" Files"); 87 | for (uint8_t f=0; f"); 109 | char name[20]; 110 | readline(name, 20); 111 | 112 | Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\""); 113 | if (! sfx.playTrack(name) ) { 114 | Serial.println("Failed to play track?"); 115 | } 116 | break; 117 | } 118 | 119 | case '+': { 120 | Serial.println("Vol up..."); 121 | uint16_t v; 122 | if (! (v = sfx.volUp()) ) { 123 | Serial.println("Failed to adjust"); 124 | } else { 125 | Serial.print("Volume: "); Serial.println(v); 126 | } 127 | break; 128 | } 129 | 130 | case '-': { 131 | Serial.println("Vol down..."); 132 | uint16_t v; 133 | if (! (v=sfx.volDown()) ) { 134 | Serial.println("Failed to adjust"); 135 | } else { 136 | Serial.print("Volume: "); 137 | Serial.println(v); 138 | } 139 | break; 140 | } 141 | 142 | case '=': { 143 | Serial.println("Pausing..."); 144 | if (! sfx.pause() ) Serial.println("Failed to pause"); 145 | break; 146 | } 147 | 148 | case '>': { 149 | Serial.println("Unpausing..."); 150 | if (! sfx.unpause() ) Serial.println("Failed to unpause"); 151 | break; 152 | } 153 | 154 | case 'q': { 155 | Serial.println("Stopping..."); 156 | if (! sfx.stop() ) Serial.println("Failed to stop"); 157 | break; 158 | } 159 | 160 | case 't': { 161 | Serial.print("Track time: "); 162 | uint32_t current, total; 163 | if (! sfx.trackTime(¤t, &total) ) Serial.println("Failed to query"); 164 | Serial.print(current); Serial.println(" seconds"); 165 | break; 166 | } 167 | 168 | case 's': { 169 | Serial.print("Track size (bytes remaining/total): "); 170 | uint32_t remain, total; 171 | if (! sfx.trackSize(&remain, &total) ) 172 | Serial.println("Failed to query"); 173 | Serial.print(remain); Serial.print("/"); Serial.println(total); 174 | break; 175 | } 176 | 177 | } 178 | } 179 | 180 | 181 | 182 | 183 | 184 | 185 | /************************ MENU HELPERS ***************************/ 186 | 187 | void flushInput() { 188 | // Read all available serial input to flush pending data. 189 | uint16_t timeoutloop = 0; 190 | while (timeoutloop++ < 40) { 191 | while(ss.available()) { 192 | ss.read(); 193 | timeoutloop = 0; // If char was received reset the timer 194 | } 195 | delay(1); 196 | } 197 | } 198 | 199 | char readBlocking() { 200 | while (!Serial.available()); 201 | return Serial.read(); 202 | } 203 | 204 | uint16_t readnumber() { 205 | uint16_t x = 0; 206 | char c; 207 | while (! isdigit(c = readBlocking())) { 208 | //Serial.print(c); 209 | } 210 | Serial.print(c); 211 | x = c - '0'; 212 | while (isdigit(c = readBlocking())) { 213 | Serial.print(c); 214 | x *= 10; 215 | x += c - '0'; 216 | } 217 | return x; 218 | } 219 | 220 | uint8_t readline(char *buff, uint8_t maxbuff) { 221 | uint16_t buffidx = 0; 222 | 223 | while (true) { 224 | if (buffidx > maxbuff) { 225 | break; 226 | } 227 | 228 | if (Serial.available()) { 229 | char c = Serial.read(); 230 | //Serial.print(c, HEX); Serial.print("#"); Serial.println(c); 231 | 232 | if (c == '\r') continue; 233 | if (c == 0xA) { 234 | if (buffidx == 0) { // the first 0x0A is ignored 235 | continue; 236 | } 237 | buff[buffidx] = 0; // null term 238 | return buffidx; 239 | } 240 | buff[buffidx] = c; 241 | buffidx++; 242 | } 243 | } 244 | buff[buffidx] = 0; // null term 245 | return buffidx; 246 | } 247 | /************************ MENU HELPERS ***************************/ -------------------------------------------------------------------------------- /Adafruit_Soundboard.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_Soundboard.cpp 3 | * 4 | * @mainpage Adafruit Soundboard Library 5 | * 6 | * @section intro_sec Introduction 7 | * 8 | * This is a library for the Adafruit Sound Boards in UART mode 9 | * 10 | * ----> http://www.adafruit.com/products/2342 11 | * ----> http://www.adafruit.com/products/2341 12 | * ----> http://www.adafruit.com/products/2217 13 | * ----> http://www.adafruit.com/products/2210 14 | * ----> http://www.adafruit.com/products/2133 15 | * ----> http://www.adafruit.com/products/2220 16 | * 17 | * Check out the links above for our tutorials and wiring diagrams 18 | * This sound fx driver uses TTL Serial to communicate 19 | * 20 | * Adafruit invests time and resources providing this open source code, 21 | * please support Adafruit and open-source hardware by purchasing 22 | * products from Adafruit! 23 | * 24 | * @section author Author 25 | * 26 | * Written by Limor Fried/Ladyada for Adafruit Industries. 27 | * 28 | * @section license License 29 | * 30 | * MIT license, all text above must be included in any redistribution 31 | */ 32 | 33 | #include "Adafruit_Soundboard.h" 34 | 35 | //#define DEBUG 1 36 | 37 | // Constructor 38 | Adafruit_Soundboard::Adafruit_Soundboard(Stream *s, Stream *d, int8_t r) 39 | : stream(s), debug(d), reset_pin(r) { 40 | stream->setTimeout(500); 41 | writing = false; 42 | files = 0; 43 | } 44 | 45 | int Adafruit_Soundboard::readLine(void) { 46 | int x = stream->readBytesUntil('\n', line_buffer, LINE_BUFFER_SIZE); 47 | line_buffer[x] = 0; 48 | 49 | if (stream->peek() == '\r') 50 | stream->read(); 51 | // stream->readBytesUntil('\r', line_buffer, LINE_BUFFER_SIZE); 52 | return x; 53 | } 54 | 55 | /*! 56 | * @brief Anything printed to Soundboard object will be split to both the sound 57 | * card and debug streams. Saves having to print everything twice in debug 58 | * code. 59 | */ 60 | size_t Adafruit_Soundboard::write(uint8_t c) { 61 | if (debug) { 62 | if (!writing) { 63 | debug->print(F("---> ")); 64 | writing = true; 65 | } 66 | debug->write(c); 67 | } 68 | return stream->write(c); 69 | } 70 | 71 | /*! 72 | * @brief Do a hard reset by bringing the RST pin low 73 | * then read out the output lines 74 | * @return Returns the output lines 75 | */ 76 | boolean Adafruit_Soundboard::reset(void) { 77 | digitalWrite(reset_pin, LOW); 78 | pinMode(reset_pin, OUTPUT); 79 | delay(10); 80 | pinMode(reset_pin, INPUT); 81 | delay(1000); // give a bit of time to 'boot up' 82 | 83 | // eat new line 84 | readLine(); 85 | #ifdef DEBUG 86 | Serial.println(line_buffer); // Date and name 87 | #endif 88 | 89 | readLine(); 90 | // "Adafruit FX Sound Board 9/10/14" 91 | #ifdef DEBUG 92 | Serial.println(line_buffer); // Date and name 93 | #endif 94 | if (!strstr(line_buffer, "Adafruit FX Sound Board")) 95 | return false; 96 | 97 | delay(250); 98 | 99 | readLine(); 100 | // Serial.print("3>"); Serial.println(line_buffer); // FAT type 101 | readLine(); 102 | // Serial.print("4>"); Serial.println(line_buffer); // # of files 103 | 104 | return true; 105 | } 106 | 107 | /*! 108 | * @brief Query the board for the # of files and names/sizes 109 | * @return Returns the information about the files 110 | */ 111 | uint8_t Adafruit_Soundboard::listFiles(void) { 112 | uint32_t filesize; 113 | 114 | while (stream->available()) 115 | stream->read(); 116 | 117 | stream->println('L'); // 'L' for 'l'ist 118 | 119 | files = 0; 120 | 121 | while (stream->readBytesUntil('\n', line_buffer, LINE_BUFFER_SIZE)) { 122 | // copy over the file name 123 | memcpy(filenames[files], line_buffer, 12); 124 | filenames[files][11] = 0; 125 | 126 | // parse out the file size after the name + tab 127 | filesizes[files] = 0; 128 | for (uint8_t i = 0; i < 16; i++) { 129 | uint8_t c = line_buffer[12 + i]; 130 | if ((c > '9') || (c < '0')) { 131 | break; 132 | } 133 | 134 | filesizes[files] *= 10; 135 | 136 | filesizes[files] += c - '0'; 137 | } 138 | 139 | files++; 140 | if (files >= MAXFILES) 141 | break; 142 | } 143 | return files; 144 | } 145 | 146 | // for public consumption 147 | char *Adafruit_Soundboard::fileName(uint8_t n) { 148 | if (n >= files) 149 | return NULL; 150 | 151 | return filenames[n]; 152 | } 153 | 154 | uint32_t Adafruit_Soundboard::fileSize(uint8_t n) { 155 | if (n >= files) 156 | return 0; 157 | 158 | return filesizes[n]; 159 | } 160 | 161 | boolean Adafruit_Soundboard::playTrack(uint8_t n) { 162 | while (stream->available()) 163 | stream->read(); 164 | 165 | stream->print("#"); 166 | stream->println(n); 167 | 168 | readLine(); // eat return 169 | 170 | readLine(); 171 | 172 | #ifdef DEBUG 173 | Serial.print("<---"); 174 | Serial.println(line_buffer); 175 | #endif 176 | 177 | // check we got "play" back 178 | if (strstr(line_buffer, "play") == 0) { 179 | return false; 180 | } 181 | // check the # is correct 182 | int playing = atoi(line_buffer + 5); 183 | #ifdef DEBUG 184 | Serial.print("# = "); 185 | Serial.println(playing); 186 | #endif 187 | if (n != playing) 188 | return false; 189 | 190 | return true; 191 | } 192 | 193 | boolean Adafruit_Soundboard::playTrack(char *name) { 194 | while (stream->available()) 195 | stream->read(); 196 | 197 | stream->print("P"); 198 | stream->println(name); 199 | 200 | readLine(); // eat return 201 | #ifdef DEBUG 202 | Serial.print("\n\r<--- "); 203 | Serial.println(line_buffer); 204 | #endif 205 | 206 | readLine(); 207 | 208 | #ifdef DEBUG 209 | Serial.print("\n\r<--- "); 210 | Serial.println(line_buffer); 211 | #endif 212 | 213 | // check we got "play" back 214 | if (strstr(line_buffer, "play") == 0) { 215 | return false; 216 | } 217 | return true; 218 | } 219 | 220 | uint8_t Adafruit_Soundboard::volUp() { 221 | while (stream->available()) 222 | stream->read(); 223 | 224 | stream->println("+"); 225 | readLine(); 226 | // Serial.println(line_buffer); 227 | 228 | uint8_t v = atoi(line_buffer); 229 | 230 | return v; 231 | } 232 | 233 | uint8_t Adafruit_Soundboard::volDown() { 234 | while (stream->available()) 235 | stream->read(); 236 | 237 | stream->println("-"); 238 | readLine(); 239 | // Serial.println(line_buffer); 240 | 241 | uint8_t v = atoi(line_buffer); 242 | 243 | return v; 244 | } 245 | 246 | boolean Adafruit_Soundboard::pause() { 247 | while (stream->available()) 248 | stream->read(); 249 | 250 | stream->print("="); 251 | if (!stream->readBytes(line_buffer, 1)) 252 | return false; 253 | 254 | if (line_buffer[0] != '=') 255 | return false; 256 | return true; 257 | } 258 | 259 | boolean Adafruit_Soundboard::unpause() { 260 | while (stream->available()) 261 | stream->read(); 262 | 263 | stream->print(">"); 264 | if (!stream->readBytes(line_buffer, 1)) 265 | return false; 266 | 267 | if (line_buffer[0] != '>') 268 | return false; 269 | return true; 270 | } 271 | 272 | boolean Adafruit_Soundboard::stop() { 273 | while (stream->available()) 274 | stream->read(); 275 | 276 | stream->print("q"); 277 | readLine(); 278 | 279 | if (line_buffer[0] != 'q') 280 | return false; 281 | 282 | return true; 283 | } 284 | 285 | boolean Adafruit_Soundboard::trackTime(uint32_t *current, uint32_t *total) { 286 | while (stream->available()) 287 | stream->read(); 288 | 289 | stream->print('t'); 290 | readLine(); 291 | // Serial.println(line_buffer); 292 | // Serial.println(strlen(line_buffer)); 293 | if (strlen(line_buffer) != 12) 294 | return false; 295 | *current = atoi(line_buffer); 296 | *total = atoi(line_buffer + 6); 297 | 298 | return true; 299 | } 300 | 301 | boolean Adafruit_Soundboard::trackSize(uint32_t *remain, uint32_t *total) { 302 | while (stream->available()) 303 | stream->read(); 304 | 305 | stream->print('s'); 306 | readLine(); 307 | // Serial.println(line_buffer); 308 | // Serial.println(strlen(line_buffer)); 309 | if (strlen(line_buffer) != 22) 310 | return false; 311 | *remain = atol(line_buffer); 312 | *total = atol(line_buffer + 11); 313 | 314 | return true; 315 | } 316 | --------------------------------------------------------------------------------