initial commit

This commit is contained in:
2026-09-25 10:48:51 +10:00
commit b90beea8ae
1020 changed files with 131665 additions and 0 deletions
@@ -0,0 +1,184 @@
/*
* This sketch illustrates opening files by index
* which can significantly reduce latency.
*
* How to prepare a test SD:
* Start with a clean newly formatted SD.
* First copy the 400 files in the 'fill' folder to the SD.
* Next copy the 16 files in the 'DTMF' folder to the SD.
* There should be 416 files in the SD root directory.
*
* You must copy the files in the above order so the 'fill'
* files occur in the directory before the DTMF files.
*
* Run this sketch using the prepared SD. Notice the
* difference in latency between play by name and
* play by index.
*/
#include <WaveHC.h>
#include <WaveUtil.h>
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
// time to play each tone in milliseconds
#define PLAY_TIME 200
/*
* Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))
//////////////////////////////////// SETUP
void setup() {
Serial.begin(9600);
if (!card.init()) error("card.init");
// enable optimized read - some cards may timeout
card.partialBlockRead(true);
if (!vol.init(card)) error("vol.init");
if (!root.openRoot(vol)) error("openRoot");
PgmPrintln("Index files");
indexFiles();
PgmPrintln("Play files by index");
playByIndex();
PgmPrintln("Play files by name");
playByName();
}
//////////////////////////////////// LOOP
void loop() { }
/////////////////////////////////// HELPERS
/*
* print error message and halt
*/
void error_P(const char *str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* print error message and halt if SD I/O error, great for debugging!
*/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
// Number of files.
#define FILE_COUNT 16
// Files are 'touch tone phone' DTMF tones, P = #, S = *
// Most phones don't have A, B, C, and D tones.
// file names are of the form DTMFx.WAV where x is one of
// the letters from fileLetter[]
char fileLetter[] = {'0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'A', 'B', 'C', 'D', 'P', 'S'};
// index of DTMF files in the root directory
uint16_t fileIndex[FILE_COUNT];
/*
* Find files and save file index. A file's index is is the
* index of it's directory entry in it's directory file.
*/
void indexFiles(void) {
char name[10];
// copy flash string to RAM
strcpy_P(name, PSTR("DTMFx.WAV"));
for (uint8_t i = 0; i < FILE_COUNT; i++) {
// Make file name
name[4] = fileLetter[i];
// Open file by name
if (!file.open(root, name)) error("open by name");
// Save file's index (byte offset of directory entry divided by entry size)
// Current position is just after entry so subtract one.
fileIndex[i] = root.readPosition()/32 - 1;
}
PgmPrintln("Done");
}
/*
* Play file by index and print latency in ms
*/
void playByIndex(void) {
for (uint8_t i = 0; i < FILE_COUNT; i++) {
// start time
uint32_t t = millis();
// open by index
if (!file.open(root, fileIndex[i])) {
error("open by index");
}
// create and play Wave
if (!wave.create(file)) error("wave.create");
wave.play();
// print time to open file and start play
Serial.println(millis() - t);
// stop after PLAY_TIME ms
while((millis() - t) < PLAY_TIME);
wave.stop();
// check for play errors
sdErrorCheck();
}
PgmPrintln("Done");
}
/*
* Play file by name and print latency in ms
*/
void playByName(void) {
char name[10];
// copy flash string to RAM
strcpy_P(name, PSTR("DTMFx.WAV"));
for (uint8_t i = 0; i < FILE_COUNT; i++) {
// start time
uint32_t t = millis();
// make file name
name[4] = fileLetter[i];
// open file by name
if (!file.open(root, name)) error("open by name");
// create wave and start play
if (!wave.create(file))error("wave.create");
wave.play();
// print time
Serial.println(millis() - t);
// stop after PLAY_TIME ms
while((millis() - t) < PLAY_TIME);
wave.stop();
// check for play errors
sdErrorCheck();
}
PgmPrintln("Done");
}