Hey guys, last year I built a music box that plays different tunes depending on the Skylander/Amiibo/Disney Infinity type figure placed on top. It is great for what it does but it isn't very efficient. I used a template code from the internet and have been refining it and now I need to tackle the large global/program storage space.
I have noticed it could be heavily cut down if the way it loads the music to play. Below are the snippets of the code related to it.
const char string_0[] PROGMEM = "smhbytin.wav";
const char string_1[] PROGMEM = "smhbytlp.wav";
const char string_2[] PROGMEM = "smhhllin.wav";
const char string_3[] PROGMEM = "smhhlllp.wav";
const char string_4[] PROGMEM = "smhbsrin.wav";
//etc,etc
This is where they store the filenames as Globals. In my code they follow a strict file naming format which would make it easy to generate on the fly. I use an 8 character name that comprises of the following
AAABBBCC.wav
AAA - The type of figure ("smh")
BBB - The character name ("byt")
CC - Either "in" (for intro) or "lp" (for loop)
const char* const string_table[] PROGMEM =
{
string_0, string_1, string_2, string_3, string_4, //etc etc
}
It then creates a global array for the strings
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 for a pi digit or period
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
char buffer[71];
Loads the objects needed for it to run
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0]))); //The array number is different
playfile(buffer);
This code is run when the nfc figure has been identified (For example, "it's a Spyro Skylander figure!")
I assume this is coping the value to the buffer. This part I am hazy on its function.
void playfile(char *name) {
wave.stop();
if (!file.open(root, name)) {
PgmPrint("Can't open file ");
Serial.println(name);
return;
}
if (!wave.create(file)) {
PgmPrintln("Invalid WAV");
return;
}
// ok time to play!
wave.play();
}
This is where all the code happens for the music playing
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);
}
This is the error code it throws if there is a problem with playing the music.
The rest of the code is based on loading the nfc figure and determining what track is played. If I could pass in a string to play the music file (for example, str = "smhbytin.wav" , we could then generate the name of the file as we discover which figure it is. It would make the need to store the globals redundant and cut a lot of code out as well reduce the amount of code that is added per figure.
The problem is I wouldn't know where to begin. This isn't my usual sort of coding so I am in the dark on how to work on it.
Can anyone advise me on a way to pass in a string to load a music file?
EDIT: I have been working on multiple solutions and none of them have worked. If anyone does have a solution I'd love to know how it works.