void mp3player(void *pvParameters) { rprintf("mp3player()"); OSHANDLES *osHandles = (OSHANDLES*)pvParameters; char songname[15]; char command; while(1) { if(xQueueReceive(osHandles->queue.songname, &songname[0], portMAX_DELAY)) { rprintf("SONG RECEIVED: %s\n", songname); FIL fileHandle; BYTE buffer[2048]; if(FR_OK == f_open(&fileHandle, songname, FA_OPEN_EXISTING | FA_READ)) { rprintf("File opened, about to play %s\n", songname); int numOfReadBytes = sizeof(buffer); while(numOfReadBytes == sizeof(buffer)) { if(FR_OK == f_read(&fileHandle, buffer, sizeof(buffer), &numOfReadBytes)) { rprintf("successful read\n"); if(xSemaphoreTake(osHandles->lock.SPI, 1000)) { rprintf("***** Playing mp3\ *****\n"); SELECT_MP3_CS(); int i = 0; while( i < numOfReadBytes) { //if( STA013_NEEDS_DATA() && !paused) if( STA013_NEEDS_DATA()) { rxTxByteSSPSPI(buffer[i++]); } else { vTaskDelay(1); } } DESELECT_MP3_CS(); xSemaphoreGive(osHandles->lock.SPI); } else { rprintf("Error taking SPI semaphore while playing mp3\n"); } }
void mp3_task(void *pvParameters) { OSHANDLES *osHandles = (OSHANDLES*)pvParameters; // Cast the void pointer to pointer of OSHANDLES player_status.has_song = 0; player_status.playing = 0; vTaskDelay(100); scan_root(); //scan/populate database of artist & their albums. //artist_list->tracks = bubblesort(artist_list->tracks); for(;;) { Track * playlist; player_status.playlist_pos = 0; unsigned char cntl = RESUME; if (xQueueReceive(osHandles->queue.playback_playlist, &playlist,999999999)) { player_status.playlist_pos = 0; while (1) { //playlist loop Track * this_song = get_track_number(player_status.playlist_pos, playlist); if (this_song == NULL) {rprintf("get_track_number returned null."); break;} //past end of the playlist. rprintf("item(%i) track(%s) path(%s)",player_status.playlist_pos,this_song->name,this_song->filename); /* ---- check file's extention. ---- */ char* got_ext = strrchr(this_song->filename,'.'); //get position of last '.' if ((got_ext == NULL) || (0 != strncmp(got_ext, ".MP3", 4)) ){ rprintf("file not .mp3\n"); break; // filename didn't have a .mp3 extention. } /* ---- open the file. ---- */ FIL file; FRESULT rstat = f_open(&file, this_song->filename, (FA_READ | FA_OPEN_EXISTING)); if (rstat != FR_OK) { rprintf("open error #%i (0x%02X).\n",rstat,rstat); f_close(&file); break; } /* ---- file opened successfully ---- */ player_status.has_song = 1; player_status.playing = 1; //player_status.legnth = Finfo.fsize; player_status.position = 0; while (1){ /* ---- check about the control queue ---- */ if (xQueueReceive(osHandles->queue.mp3_control, &cntl,0)){ if ((cntl == PAUSE) || (cntl == PLAY_PAUSE)) { player_status.playing = 0; if (xQueueReceive(osHandles->queue.mp3_control, &cntl,1000*60*5)) {} else {cntl = STOP; break;} //stop if past timeout (5 mins) } if ((cntl == NEXT_T)||(cntl == PREV_T)||(cntl == STOP)) break; //breaks the playing loop.. } if (cntl == SEEK_F_8X) { f_lseek(&file, file.fptr + 4096*8); player_status.position += 8; } if (cntl == SEEK_R_8X) { f_lseek(&file, file.fptr - 4096*8); player_status.position -= 8; } player_status.position += 1; /* ---- read a chunk of data to the buffer ---- */ player_status.playing = 1; char buff[4096]; unsigned int bytesRead = 0; unsigned int start_ms = xTaskGetTickCount(); f_read(&file, buff, sizeof(buff), &bytesRead); player_status.read_speed = bytesRead/(xTaskGetTickCount()-start_ms); /* ---- send chunked data to the mp3 decoder ---- */ int i = 0; while( i < bytesRead) { if (MP3_DATAREQ_IS_HIGH) { if (xSemaphoreTake( osHandles->lock.SPI, 100)){ IOSET1 = (1<<29); //MP3-decoder CS => active high rxTxByteSSPSPI(buff[i++]); IOCLR1 = (1<<29); //MP3-decoder CS xSemaphoreGive( osHandles->lock.SPI ); } } } if(sizeof(buff) > bytesRead){ // Last Chunk in file break; // Break outer loop, song ended } } f_close(&file); player_status.has_song = 0; player_status.playing = 0; //done playing the current playlist position, increment and continue. if (cntl == STOP) break; //breaks the playlist loop.. else if (cntl == PREV_T) { //previous / skip to beginning of track. if ((player_status.position < 50) && (player_status.playlist_pos > 0)){ player_status.playlist_pos--; } } else if (cntl == NEXT_T) {player_status.playlist_pos++;} else {player_status.playlist_pos++;cntl = RESUME;} } //playlist loop } //xQueueReceive } //endless for loop. don't break; this. }