Geluid met Arduino

Stationsgeluiden, de bellen bij een overweg, enz enz.
Hartstikke leuk natuurlijk om die ook te laten horen op de baan. En dat moet dan toch kunnen met een Arduino? Ja, maar niet zonder slag of stoot…

Het probleem is dat er geen eenvoudige manier is waarmee je ‘gewoon’ een MP3 of WAV aan kunt bieden en dat die dan afgespeeld wordt.
Wat ik uiteindelijk heb gebruikt is https://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio. Probleem daarmee is dat er nogal wat onduidelijkheden staan op die site. Ik zal hier mijn bevindingen plaatsen:

Allereerst heb je iets nodig om je geluidsbestanden op te plaatsen: een SD-kaart. Ik heb deze bij AliExpress aangeschaft: https://nl.aliexpress.com/item/1PCS-Micro-SD-Storage-Expansion-Board-Mciro-SD-TF-Card-Memory-Shield-Module-SPI-For-Arduino/32523546123.html

SimpleSDAudio leest NIET het bestand dat opgegeven wordt, maar zoekt de eerste sector op de schijf op en leest daarna domweg de volgende sectoren. Als een bestand gefragmenteerd is werkt dit dus niet. Oplossing: formatteer je SD-kaart, en plaats je bestanden. Nieuw bestand toevoegen? Geen probleem…. totdat je ook een keer een bestand hebt verwijderd 🙁

SimpleSDAudio leest geen MP3 of WAV(!), maar alleen een raw-bestand dat in feite per byte het volume weergeeft. Door dat 31250 keer per seconde te doen krijg je geluid.
Zo’n raw-bestand maak je met het meegeleverde ‘sox’. Het commando dat ik gebruik en goed werkt is:

sox spoor12.mp3 --norm=-1 -e unsigned-integer -b 8 -r 31250 -c 1 -t raw converted/spoor12.raw

Let er ook op dat bestandsnamen aan de prehistorische eis van maximaal 8+3 karakters moet voldoen.

Hierna is het een kwestie van een kleine sketch maken:

#include <SimpleSDAudio.h>

void setup() {
SdPlay.setSDCSPin(4); // sd card cs pin
SdPlay.init(SSDA_MODE_HALFRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER);
play("ding.raw");
play("spoor12.raw");
}

void loop(void) { }

void play(String file) {
SdPlay.setFile(file.c_str());
SdPlay.play(); // play music
while (!SdPlay.isStopped()) { }
}