////////////////////////////////////// PLAY TUNE ////////////////////////////////////// #include "play.h" #include #include int repcnt; int dur; int chan; const unsigned char *tune; const unsigned char *tuneStartPos; int ramTune = 0; struct tune_rec { const unsigned char *ptr; const unsigned char *startp; int rep; int ram; }tunestk[4]; int tunesp = 0; void repeatTune(int n) { repcnt = n; } void startTune( const unsigned char *data, int ram) { tunestk[tunesp].ptr = tune; tunestk[tunesp].ram = ramTune; tunestk[tunesp].rep = repcnt; tunestk[tunesp].startp = tuneStartPos; tune = data; tuneStartPos = data; ramTune = ram; if( tunesp < 3){ tunesp++; } } int playing() { if( tune == NULL){ return 0; } return 1; } void playTune() { byte d; byte t; while( tune){ if( ramTune){ d = tune[0]; t = tune[1]; }else { d = pgm_read_byte_near(tune); t = pgm_read_byte_near(tune+1); } if( d ==0 && t == 0){ if( repcnt > 0){ --repcnt; if( repcnt == 0){ tune = NULL; }else { tune = tuneStartPos; // repeat tune } }else { // pop the tune stack. if( tunesp > 0){ tunesp--; tune = tunestk[tunesp].ptr; ramTune = tunestk[tunesp].ram; repcnt = tunestk[tunesp].rep; tuneStartPos = tunestk[tunesp].startp; }else { tune = NULL; } } monophonic = 0; #ifdef DEBUGNOTE Serial.print("End of Tune\n"); #endif break; }else { if( t == 1){ if( noteOn(d, 0x7f, chan) == 0 ){ tune = &tune[2]; } continue; }else if( t == 2){ noteOff(d, chan); tune = &tune[2]; continue; }else if( t == 6){ if( dur ==0){ dur = d; }else { --dur; if( dur == 0){ // end of duration tune = &tune[2]; } } break; }else if( t == 7){ if( d == 1){ monophonic = 1; }else if( d == 0){ monophonic = 0; } tune = &tune[2]; continue; }else if( t == 8){ // channel select chan = d; tune = &tune[2]; continue; }else { tune = &tune[2]; } } } }