This program utilizes an LCD, RPG, 8 ohm speaker, and SD card to provide the basic functions of a music player. The project cycles through the SD card for .wav files and tracks elapsed time. See http://mbed.org/users/rsartin3/notebook/audio-player/ for more information.

Dependencies:   DebounceIn RPG SDFileSystem TextLCD mbed wav_header wave_player

Committer:
rsartin3
Date:
Tue Mar 05 06:34:43 2013 +0000
Revision:
1:f31b40073d35
Parent:
0:040129c3d961
;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rsartin3 0:040129c3d961 1 /*
rsartin3 1:f31b40073d35 2 * Audio Player
rsartin3 1:f31b40073d35 3 */
rsartin3 0:040129c3d961 4
rsartin3 0:040129c3d961 5 #include "mbed.h"
rsartin3 0:040129c3d961 6 #include "DebounceIn.h"
rsartin3 0:040129c3d961 7 #include "SDFileSystem.h"
rsartin3 0:040129c3d961 8 #include "wave_player.h"
rsartin3 0:040129c3d961 9 #include "TextLCD.h"
rsartin3 0:040129c3d961 10 #include "RPG.h"
rsartin3 0:040129c3d961 11 #include "Wav_Support_File.h"
rsartin3 0:040129c3d961 12 #include "string"
rsartin3 0:040129c3d961 13
rsartin3 0:040129c3d961 14 // Debug mode on: 1
rsartin3 0:040129c3d961 15 #define DEBUG 0
rsartin3 0:040129c3d961 16
rsartin3 0:040129c3d961 17 // -- Debug I/O --
rsartin3 0:040129c3d961 18 DigitalOut myled(LED1);
rsartin3 0:040129c3d961 19 DigitalOut myled2(LED2);
rsartin3 0:040129c3d961 20 DigitalOut myled3(LED3);
rsartin3 0:040129c3d961 21 DigitalOut myled4(LED4);
rsartin3 0:040129c3d961 22 Serial pc(USBTX, USBRX);
rsartin3 0:040129c3d961 23
rsartin3 0:040129c3d961 24 // -- RPG I/O --
rsartin3 0:040129c3d961 25 RPG rpg(p17, p16, p19);
rsartin3 0:040129c3d961 26
rsartin3 0:040129c3d961 27 // -- Text LCD I/O --
rsartin3 0:040129c3d961 28 TextLCD lcd(p25, p26, p27, p28, p29, p30); // rs, e, d4-d7
rsartin3 0:040129c3d961 29
rsartin3 0:040129c3d961 30 // -- SD card I/O --
rsartin3 0:040129c3d961 31 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
rsartin3 0:040129c3d961 32 DigitalIn sdDetect(p9); // Grounded if no card is inserted, Requires pull up
rsartin3 0:040129c3d961 33
rsartin3 0:040129c3d961 34 // -- Wave Player I/O --
rsartin3 0:040129c3d961 35 AnalogOut DACout(p18);
rsartin3 0:040129c3d961 36 wave_player waver(&DACout);
rsartin3 0:040129c3d961 37
rsartin3 1:f31b40073d35 38 // Ticker for interrupting song
rsartin3 0:040129c3d961 39 Ticker songTick;
rsartin3 0:040129c3d961 40 time_t time_i;
rsartin3 0:040129c3d961 41
rsartin3 0:040129c3d961 42 struct playlist {
rsartin3 0:040129c3d961 43 // Doubly-linked list to easily traverse between filenames
rsartin3 1:f31b40073d35 44 char s_name[30]; // File name without .wav extension
rsartin3 1:f31b40073d35 45 playlist *prev; // Pointer to next filename
rsartin3 1:f31b40073d35 46 playlist *next; // Pointer to previous filename
rsartin3 1:f31b40073d35 47 };
rsartin3 0:040129c3d961 48
rsartin3 0:040129c3d961 49 void insert( struct playlist *root, string songName)
rsartin3 0:040129c3d961 50 {
rsartin3 0:040129c3d961 51 /* Insert
rsartin3 0:040129c3d961 52 Put a new songname at the end of the linked list
rsartin3 0:040129c3d961 53 @param *head: Pointer to root node of playlist
rsartin3 0:040129c3d961 54 @param songName: String holding the song name to be inserted
rsartin3 0:040129c3d961 55 */
rsartin3 0:040129c3d961 56 playlist *new1=(playlist *) malloc(sizeof(playlist)); // Create new playlist node
rsartin3 0:040129c3d961 57 playlist *temp = root; // Start at root node
rsartin3 0:040129c3d961 58
rsartin3 0:040129c3d961 59 while(temp -> next != NULL)
rsartin3 0:040129c3d961 60 {
rsartin3 0:040129c3d961 61 temp = temp -> next; // Traverse playlist until at last node
rsartin3 0:040129c3d961 62 }
rsartin3 0:040129c3d961 63
rsartin3 0:040129c3d961 64 strcpy(new1 -> s_name, songName.c_str()); // Copy song name into the file name of the node
rsartin3 0:040129c3d961 65 new1 -> next = NULL; // Set next pointer as null
rsartin3 0:040129c3d961 66 new1 -> prev = temp; // Set previous pointer to the last mode
rsartin3 0:040129c3d961 67 temp -> next = new1; // Hhave last node point to newly created node
rsartin3 0:040129c3d961 68 };
rsartin3 0:040129c3d961 69
rsartin3 0:040129c3d961 70 int createPlaylist(const char *location, playlist *root) {
rsartin3 0:040129c3d961 71 /* createPlaylist
rsartin3 0:040129c3d961 72 Read from given directory and if a file has a .wav extension, add it to the playlist. Output the number of songs added to playlist
rsartin3 0:040129c3d961 73 @param *location: Location to look for .wav files, tested for base SD card directory "/sd/"
rsartin3 0:040129c3d961 74 @param *root: Pointer to root of a playlist. The playlist should be empty except for the root node which will be overwritten
rsartin3 0:040129c3d961 75 @out count: Outputs the number of songs added to the playlist
rsartin3 0:040129c3d961 76 */
rsartin3 0:040129c3d961 77 DIR *d; // Directory pointer
rsartin3 0:040129c3d961 78 dirent *file; // dirent to get file name
rsartin3 1:f31b40073d35 79 // playlist *curr = root;
rsartin3 0:040129c3d961 80 int count = 0; // count of songs added to playlist
rsartin3 0:040129c3d961 81
rsartin3 0:040129c3d961 82 if(DEBUG) pc.printf("\n\rWell... Let's get started!\r\n");
rsartin3 1:f31b40073d35 83 if((d = opendir(location)) == NULL) { // Attempt to open directory at given location
rsartin3 0:040129c3d961 84 // If Error
rsartin3 0:040129c3d961 85 lcd.cls();
rsartin3 0:040129c3d961 86 lcd.printf("Unable to open directory!");
rsartin3 0:040129c3d961 87 if(DEBUG) pc.printf("[!] Unable to open directory\r\n");
rsartin3 0:040129c3d961 88 }else{
rsartin3 0:040129c3d961 89 // If Successful
rsartin3 0:040129c3d961 90 while((file = readdir(d)) !=NULL) { // While able to read files in directory
rsartin3 0:040129c3d961 91 if(DEBUG) pc.printf("Parsing file: %s\n\r", file->d_name);
rsartin3 0:040129c3d961 92
rsartin3 0:040129c3d961 93 string str(file->d_name); // Parse filename
rsartin3 0:040129c3d961 94 size_t exten = str.find_last_of("."); // Find final '.'
rsartin3 0:040129c3d961 95
rsartin3 0:040129c3d961 96 if(DEBUG) pc.printf("path: %s\n\r", (str.substr(0,exten)).c_str()); // Prints everything before final '.'
rsartin3 0:040129c3d961 97 if(DEBUG) pc.printf("file: %s\n\r", (str.substr(exten+1)).c_str()); // Prints everything after final '.'
rsartin3 0:040129c3d961 98
rsartin3 0:040129c3d961 99 // If the extension is wav or WAV, add to playlist. Otherwise read in next file
rsartin3 0:040129c3d961 100 if((str.substr(exten+1)).compare("wav") == 0 || (str.substr(exten+1)).compare("WAV") == 0 ){
rsartin3 0:040129c3d961 101 if(DEBUG) pc.printf("This is a file that I like very much!\r\n");
rsartin3 0:040129c3d961 102
rsartin3 0:040129c3d961 103 if(count == 0){ // If still at root node
rsartin3 0:040129c3d961 104 count++; // Increment count
rsartin3 1:f31b40073d35 105 strcpy(root->s_name, (str.substr(0,exten)).c_str()); // Copy filename into root node
rsartin3 1:f31b40073d35 106 // curr = root;
rsartin3 0:040129c3d961 107 }else{
rsartin3 1:f31b40073d35 108 count++; // Increment count
rsartin3 0:040129c3d961 109 insert(root,str.substr(0,exten)); // Add new song to playlist
rsartin3 0:040129c3d961 110 }
rsartin3 0:040129c3d961 111 }
rsartin3 0:040129c3d961 112 }
rsartin3 0:040129c3d961 113 closedir(d); // Close directory
rsartin3 0:040129c3d961 114 }
rsartin3 1:f31b40073d35 115 return count; // Return number of songnames added to playlist
rsartin3 0:040129c3d961 116 }
rsartin3 0:040129c3d961 117
rsartin3 0:040129c3d961 118 void printList(playlist *root) {
rsartin3 0:040129c3d961 119 /* printList
rsartin3 0:040129c3d961 120 (DEBUG function) Traverses the playlist and writes all songnames to the pc
rsartin3 0:040129c3d961 121 @param *root: pointer to playlist to print
rsartin3 0:040129c3d961 122 */
rsartin3 0:040129c3d961 123 int count = 1; // Track number, starts at 1
rsartin3 0:040129c3d961 124 struct playlist *curr = root; // playlist node used to traverse playlist
rsartin3 0:040129c3d961 125 pc.printf("\n\rPrinting File Names:\n\r");
rsartin3 0:040129c3d961 126 pc.printf("Track #%d: %s\n\r", count, curr->s_name); //Root node song name
rsartin3 0:040129c3d961 127
rsartin3 0:040129c3d961 128 while(curr -> next != NULL) { // While there is a following node...
rsartin3 0:040129c3d961 129 curr = curr -> next; // Move to it
rsartin3 0:040129c3d961 130 count++; // Increment song count
rsartin3 0:040129c3d961 131 pc.printf("Track #%d: %s\n\r", count, curr->s_name); // And print the current song name
rsartin3 0:040129c3d961 132 }
rsartin3 0:040129c3d961 133 }
rsartin3 0:040129c3d961 134
rsartin3 0:040129c3d961 135 void freeList(playlist ** root) {
rsartin3 0:040129c3d961 136 /* freeList
rsartin3 0:040129c3d961 137 * Deallocate playlist structure memory, including root node
rsartin3 0:040129c3d961 138 * Sets root pointer to NULL so old memory location cannot be accessed
rsartin3 0:040129c3d961 139 * usage: freeList(&root);
rsartin3 0:040129c3d961 140 */
rsartin3 0:040129c3d961 141
rsartin3 0:040129c3d961 142 playlist * node = *root;
rsartin3 0:040129c3d961 143 playlist * temp;
rsartin3 0:040129c3d961 144
rsartin3 0:040129c3d961 145 if(node == NULL)
rsartin3 0:040129c3d961 146 return; // Protect against an empty root node (no playlist)
rsartin3 0:040129c3d961 147
rsartin3 0:040129c3d961 148 while(node != NULL) {
rsartin3 0:040129c3d961 149 temp = node->next;
rsartin3 0:040129c3d961 150 free(node);
rsartin3 0:040129c3d961 151 node = temp;
rsartin3 0:040129c3d961 152 }
rsartin3 0:040129c3d961 153 *root = NULL;
rsartin3 0:040129c3d961 154 }
rsartin3 0:040129c3d961 155
rsartin3 0:040129c3d961 156 void deleteList(playlist * root) {
rsartin3 0:040129c3d961 157 /* deleteList
rsartin3 0:040129c3d961 158 * Deallocates all non-root playlist structures, leaving the root
rsartin3 0:040129c3d961 159 * node with a default "No wavefile" string and null'ed pointers
rsartin3 0:040129c3d961 160 */
rsartin3 0:040129c3d961 161
rsartin3 0:040129c3d961 162 if(root == NULL)
rsartin3 0:040129c3d961 163 return;
rsartin3 0:040129c3d961 164
rsartin3 0:040129c3d961 165 freeList(&(root->next));
rsartin3 0:040129c3d961 166
rsartin3 0:040129c3d961 167 root->next = NULL;
rsartin3 0:040129c3d961 168 root->prev = NULL;
rsartin3 0:040129c3d961 169 strcpy(root->s_name, "No wavefile");
rsartin3 0:040129c3d961 170 }
rsartin3 0:040129c3d961 171
rsartin3 0:040129c3d961 172 void songClock() {
rsartin3 0:040129c3d961 173 time_t time_f;
rsartin3 0:040129c3d961 174 time_f = time(NULL);
rsartin3 0:040129c3d961 175
rsartin3 0:040129c3d961 176 // if(DEBUG) printf("Time Elapsed: %d. (Start: %d, Stop: %d)\n\r", time_f - time_i, time_i, time_f);
rsartin3 0:040129c3d961 177 lcd.locate(6,1);
rsartin3 0:040129c3d961 178 lcd.printf("%d", time_f - time_i + 1);
rsartin3 0:040129c3d961 179 }
rsartin3 0:040129c3d961 180
rsartin3 0:040129c3d961 181 int main() {
rsartin3 0:040129c3d961 182 // --- Control Variables ---
rsartin3 0:040129c3d961 183 int songCount = 0; // Number of songs in the playlist linked list
rsartin3 0:040129c3d961 184
rsartin3 0:040129c3d961 185 bool sdInsert = false;
rsartin3 0:040129c3d961 186 bool firstList = false; // Is it first instance of reading from SD card
rsartin3 0:040129c3d961 187 bool playlistExist = false;
rsartin3 0:040129c3d961 188
rsartin3 0:040129c3d961 189 int rpgTick = 0; // Slow down RPG turning speed
rsartin3 0:040129c3d961 190 const int rpgThresh = 5;
rsartin3 0:040129c3d961 191
rsartin3 0:040129c3d961 192 FILE *wave_file;
rsartin3 0:040129c3d961 193 string mySongName = "Invalid";
rsartin3 0:040129c3d961 194 unsigned char wave_array[30];
rsartin3 0:040129c3d961 195
rsartin3 0:040129c3d961 196
rsartin3 0:040129c3d961 197 // --- Debug That Junk ---
rsartin3 0:040129c3d961 198 lcd.printf("Hello World!");
rsartin3 0:040129c3d961 199 if(DEBUG) pc.printf("Hello World!\n\r");
rsartin3 0:040129c3d961 200
rsartin3 0:040129c3d961 201 // --- Initialize Playlist ---
rsartin3 0:040129c3d961 202 struct playlist *root; // Create root node
rsartin3 0:040129c3d961 203 root = (playlist *)malloc(sizeof(struct playlist));
rsartin3 0:040129c3d961 204 root -> next = NULL; // Only node
rsartin3 0:040129c3d961 205 root -> prev = NULL;
rsartin3 0:040129c3d961 206 strcpy(root->s_name, "No wavefile"); // Put song name as "No wavfile"
rsartin3 0:040129c3d961 207 if(DEBUG) printList(root);
rsartin3 0:040129c3d961 208
rsartin3 0:040129c3d961 209 struct playlist *curr = root; // Current node for playlist traversal
rsartin3 0:040129c3d961 210
rsartin3 0:040129c3d961 211 // --- Internal Pull-ups ---
rsartin3 0:040129c3d961 212 sdDetect.mode(PullUp);
rsartin3 0:040129c3d961 213 wait(.001);
rsartin3 0:040129c3d961 214
rsartin3 0:040129c3d961 215 /* ================================
rsartin3 0:040129c3d961 216 =========== Start Main Program ============
rsartin3 0:040129c3d961 217 ================================
rsartin3 0:040129c3d961 218 */
rsartin3 0:040129c3d961 219 while(1) {
rsartin3 0:040129c3d961 220 // ------------- No SD Card Detected -------------
rsartin3 0:040129c3d961 221 // Current bug... When SD card is removed and replaced, stays in not detected loop... or something
rsartin3 0:040129c3d961 222 myled = sdDetect;
rsartin3 0:040129c3d961 223 myled2 = 0;
rsartin3 0:040129c3d961 224 if(!sdDetect)
rsartin3 0:040129c3d961 225 {
rsartin3 0:040129c3d961 226 if(DEBUG) {
rsartin3 0:040129c3d961 227 myled2 = 1 - myled2;
rsartin3 0:040129c3d961 228 wait_ms(50);
rsartin3 0:040129c3d961 229 }
rsartin3 0:040129c3d961 230 sdInsert = false; // Note no card is inserted
rsartin3 0:040129c3d961 231 if(playlistExist){
rsartin3 0:040129c3d961 232 playlistExist = false;
rsartin3 0:040129c3d961 233 deleteList(root);
rsartin3 0:040129c3d961 234 curr = root;
rsartin3 0:040129c3d961 235 }
rsartin3 0:040129c3d961 236 lcd.cls();
rsartin3 0:040129c3d961 237 lcd.printf("No SD Card!");
rsartin3 0:040129c3d961 238 if(DEBUG) pc.printf("No SD card detected! Please insert one\n\r");
rsartin3 0:040129c3d961 239 }
rsartin3 0:040129c3d961 240 // ------------ SD Card Detected ------------
rsartin3 0:040129c3d961 241 else {
rsartin3 0:040129c3d961 242 // ---------- Set-up Playlist ----------
rsartin3 0:040129c3d961 243 if(!sdInsert) {
rsartin3 0:040129c3d961 244 // If first loop after inserting SD card
rsartin3 0:040129c3d961 245 sdInsert = true;
rsartin3 0:040129c3d961 246 songCount = createPlaylist("/sd/", root); // Create playlist from .wav files in "/sd/"
rsartin3 0:040129c3d961 247 playlistExist = true; // A playlist now exists
rsartin3 0:040129c3d961 248 firstList = true; // First time through playlist
rsartin3 0:040129c3d961 249 curr = root; // Put current at root node
rsartin3 0:040129c3d961 250 if(DEBUG) printList(root);
rsartin3 0:040129c3d961 251 lcd.cls(); // Display number of songs found
rsartin3 0:040129c3d961 252 lcd.printf("Songs found: %d", songCount);
rsartin3 0:040129c3d961 253 }
rsartin3 0:040129c3d961 254
rsartin3 0:040129c3d961 255 // ----------------- Turn RPG Clockwise -----------------
rsartin3 0:040129c3d961 256 if(rpg.dir() == 1) {
rsartin3 0:040129c3d961 257 // If turned clockwise, see if increment is greater than threshold
rsartin3 0:040129c3d961 258 if(rpgTick < rpgThresh){
rsartin3 0:040129c3d961 259 rpgTick++; //if not increment and do nothing else
rsartin3 0:040129c3d961 260 if(DEBUG) printf("rpgThresh: %d\r\n", rpgThresh);
rsartin3 0:040129c3d961 261 }
rsartin3 0:040129c3d961 262 else {
rsartin3 0:040129c3d961 263 rpgTick = 0; // Clear rpg counter
rsartin3 0:040129c3d961 264
rsartin3 0:040129c3d961 265 if(firstList){ // If first time controlling just put display node song name
rsartin3 0:040129c3d961 266 firstList = false;
rsartin3 0:040129c3d961 267 lcd.cls();
rsartin3 0:040129c3d961 268 lcd.printf("%s", curr->s_name);
rsartin3 0:040129c3d961 269 }
rsartin3 0:040129c3d961 270 else { // Otherwise increment if possible and display song name
rsartin3 0:040129c3d961 271 if(curr -> next != NULL){
rsartin3 0:040129c3d961 272 curr = curr -> next;
rsartin3 0:040129c3d961 273 lcd.cls();
rsartin3 0:040129c3d961 274 lcd.printf("%s",curr->s_name);
rsartin3 0:040129c3d961 275 }
rsartin3 0:040129c3d961 276 }
rsartin3 0:040129c3d961 277 }
rsartin3 0:040129c3d961 278 }
rsartin3 0:040129c3d961 279 // ----------------- Turn RPG Counter Clockwise -----------------
rsartin3 0:040129c3d961 280 else {
rsartin3 0:040129c3d961 281 if(rpg.dir() == -1) {
rsartin3 0:040129c3d961 282 // Check if increment is greater than threshold
rsartin3 0:040129c3d961 283 if(rpgTick < rpgThresh) {
rsartin3 0:040129c3d961 284 rpgTick++;
rsartin3 0:040129c3d961 285 }
rsartin3 0:040129c3d961 286 else {
rsartin3 0:040129c3d961 287 rpgTick = 0; // Clear increment
rsartin3 0:040129c3d961 288
rsartin3 0:040129c3d961 289 if(!firstList ){ //if on song selection, decrement if possible and displays song name
rsartin3 0:040129c3d961 290 if(curr -> prev != NULL){
rsartin3 0:040129c3d961 291 curr = curr -> prev;
rsartin3 0:040129c3d961 292 lcd.cls();
rsartin3 0:040129c3d961 293 lcd.printf("%s",curr->s_name);
rsartin3 0:040129c3d961 294 }
rsartin3 0:040129c3d961 295 }
rsartin3 0:040129c3d961 296 }
rsartin3 0:040129c3d961 297 }
rsartin3 0:040129c3d961 298 }
rsartin3 0:040129c3d961 299 // ----------------- Press RPG Button -----------------
rsartin3 0:040129c3d961 300 if(rpg.pb()) {
rsartin3 0:040129c3d961 301 // if push button is pressed ... SOMETHING
rsartin3 0:040129c3d961 302 lcd.cls();
rsartin3 0:040129c3d961 303 lcd.printf("Song playing");
rsartin3 0:040129c3d961 304
rsartin3 0:040129c3d961 305 //Check sd card maybes
rsartin3 0:040129c3d961 306
rsartin3 0:040129c3d961 307 // File location name thing
rsartin3 0:040129c3d961 308 mySongName.erase();
rsartin3 0:040129c3d961 309 mySongName.append("/sd/");
rsartin3 0:040129c3d961 310 mySongName.append(curr->s_name);
rsartin3 0:040129c3d961 311 mySongName.append(".wav");
rsartin3 0:040129c3d961 312
rsartin3 0:040129c3d961 313 // Open File
rsartin3 0:040129c3d961 314 if(DEBUG) printf("Appended Name: %s\n\r", mySongName.c_str());
rsartin3 0:040129c3d961 315 wave_file=fopen(mySongName.c_str(),"r");
rsartin3 0:040129c3d961 316
rsartin3 0:040129c3d961 317 wave_file_check(wave_array, wave_file);
rsartin3 0:040129c3d961 318 if(DEBUG) printf("Sample Rate: %d\r\n", wave_file_info.samples_per_second);
rsartin3 0:040129c3d961 319 fclose(wave_file);
rsartin3 0:040129c3d961 320
rsartin3 0:040129c3d961 321 lcd.locate(0,1);
rsartin3 0:040129c3d961 322 lcd.printf("Time: / sec");
rsartin3 0:040129c3d961 323 lcd.locate(10,1);
rsartin3 0:040129c3d961 324 lcd.printf("%d", (int)(wave_file_info.length_of_file / (wave_file_info.samples_per_second * wave_file_info.number_of_channels * wave_file_info.bytes_per_sample)) );
rsartin3 0:040129c3d961 325
rsartin3 0:040129c3d961 326
rsartin3 0:040129c3d961 327 wave_file=fopen(mySongName.c_str(),"r");
rsartin3 0:040129c3d961 328
rsartin3 0:040129c3d961 329 songTick.attach(&songClock, 1.0);
rsartin3 0:040129c3d961 330 set_time(1357020000);
rsartin3 0:040129c3d961 331 time_i = time(NULL);
rsartin3 0:040129c3d961 332
rsartin3 0:040129c3d961 333 if(DEBUG) printf("Start Song\r\n");
rsartin3 0:040129c3d961 334 waver.play(wave_file);
rsartin3 0:040129c3d961 335
rsartin3 0:040129c3d961 336 if(DEBUG) printf("Close Song!\r\n");
rsartin3 0:040129c3d961 337 fclose(wave_file);
rsartin3 0:040129c3d961 338
rsartin3 0:040129c3d961 339 songTick.detach();
rsartin3 0:040129c3d961 340 time_i = 0;
rsartin3 0:040129c3d961 341
rsartin3 0:040129c3d961 342 lcd.cls();
rsartin3 0:040129c3d961 343 lcd.printf(curr->s_name);
rsartin3 0:040129c3d961 344 if(DEBUG) printf("Finished mai SONG!\r\n");
rsartin3 0:040129c3d961 345 }
rsartin3 0:040129c3d961 346 if(DEBUG) printf("rpgTick: %d \r\n",rpgTick);
rsartin3 0:040129c3d961 347 }
rsartin3 0:040129c3d961 348 }
rsartin3 0:040129c3d961 349 }