Basic Outline: Each arrow below represents processing that we would need to apply to our song data.
To make data transfer between the the processing stage and the playing stage convenient, we developed a data structure to neatly contian the data. Music would be stored in a 2d array, where each row represented a time stamp, and each column represented a note. A 1 means that note is played; a zero means it's not. So it would look something like this if I were to walk up each note.
byte music[][5] = { {1,0,0,0,0},
{0,1,0,0,0},
{0,0,1,0,0},
{0,0,0,1,0},
{0,0,0,0,1} };
music[0] //the piano keys played on the first time stamp
music[0][3] //whether the second note is played during the first time stamp
Storing each number as an byte is wasteful, since a byte on the ATmega chip is 8 bits. We could be using 8 times less data if we stored our binary array as a bit array. If we need more than 8 bits, we just add another byte column to our array. The above song would look like this:
byte music[][1] = { {B10000000}
{B01000000}
{B00100000}
{B00010000}
{B00001000} };
music[0] //the piano keys played on the first time stamp
music[0] & B01000000//whether the second note is played during the first time stamp
Often a note is held down for a while and adjacent rows in the array can often be found as duplicates. We'll leverage that heuristic and compress adjacent time stamps by encoding the number of duplicates in the last 4 bits of the row. (This leaves 60bits, and hence 60 keys on the piano, still usable). This provides another 16x max-compression rate.
This example song:
byte music[][8] = {
{B00000000,...,B00100000,...,B00000000},
{B00000000,...,B00100000,...,B00000000},
{B00000000,...,B00100000,...,B00000000}
};
Converts to :
byte music[][8] = {
{B00000000,...,B00100000,...,B00000010}
};
If you store a variable in the SRAM of the ATMega2560 chip (verify that's what we have), we have a max cap of 8 kilobytes that can be used. However, there's another portion of memory lesser known about -- the Flash. No, he doesn't wear a red skin tight suit. The ATMega2560's flash can store 256 kilobytes. That's an increase of 32x!