* * $Log$ * *
Definition in file mp3player.c.
#include <cfg/os.h>
#include <cfg/clock.h>
#include <dev/board.h>
#include <sys/heap.h>
#include <sys/timer.h>
#include <sys/event.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include "tlv320dac.h"
#include "webradio.h"
#include "utils.h"
#include "userif.h"
#include "mp3player.h"
Include dependency graph for mp3player.c:
Go to the source code of this file.
Defines | |
#define | MP3_THREAD_STACK 2048 |
#define | ENABLE_RESAMPLER |
Functions | |
static void | Mp3PlayerBufferFill (PLAYERINFO *pip) |
Wait until the MP3 data buffer is sufficiently filled. | |
void | Mp3PlayerThread (void *arg) |
MP3 player thread. | |
int | Mp3PlayerCreate (PLAYERINFO *pip) |
Create MP3 player instance. | |
int | Mp3PlayerSetup (PLAYERINFO *pip) |
Setup MP3 player. | |
Variables | |
static void * | hres |
static int | rs_maxout |
static short * | rs_pcmbuf |
PLAYERPLUGIN | ppiMp3 |
MP3 player plug-in reference structure. |
|
Definition at line 66 of file mp3player.c. |
|
Definition at line 73 of file mp3player.c. |
|
Wait until the MP3 data buffer is sufficiently filled.
Definition at line 86 of file mp3player.c. 00088 { 00089 RECEIVERINFO *rip; 00090 time_t start = time(NULL); 00091 00092 printf("\nBuffering"); 00093 for (;;) { 00094 /* Return if 2/3 of the buffer is filled. */ 00095 rip = pip->pi_rcvr; 00096 if (rip == NULL || rip->ri_avail >= (MP3_BUFSIZ * 2) / 3) { 00097 break; 00098 } 00099 /* Return if we reached our time limit. */ 00100 if (time(NULL) - start >= MAX_WAIT_MP3BUF_FILLED) { 00101 break; 00102 } 00103 /* Return if someone stopped the player. */ 00104 if (pip->pi_status != PSTAT_RUNNING) { 00105 break; 00106 } 00107 /* Wait for an event from the producer. */ 00108 if (NutEventWait(&rip->ri_rdbque, 500) == 0) { 00109 putchar('.'); 00110 } 00111 UserIfShowMessage(1, 1, "Buffering %u%%", (rip->ri_avail * 100) / MP3_BUFSIZ); 00112 } 00113 printf(" %u bytes free\n", (u_int)NutHeapAvailable());
|
|
MP3 player thread.
Definition at line 120 of file mp3player.c. 00122 { 00123 PLAYERINFO *pip = (PLAYERINFO *)arg; 00124 MP3PLAYERINFO *mpi = (MP3PLAYERINFO *) pip->pi_bcast; 00125 RECEIVERINFO *rip; 00126 int rbytes; 00127 u_char *bufptr; 00128 int ec; 00129 int errcnt; 00130 int tmocnt; 00131 int first_frame; 00132 int samprate; 00133 00134 Tlv320DacInit(DAC_OUTPUT_RATE); 00135 Tlv320DacSetVolume(radio.rc_rvolume, radio.rc_rvolume); 00136 radio.rc_cvolume = radio.rc_rvolume; 00137 00138 for (;;) { 00139 /* Idle loop. */ 00140 for (;;) { 00141 printf("[PIDLE]"); 00142 pip->pi_status = PSTAT_IDLE; 00143 NutEventBroadcast(&pip->pi_stsevt); 00144 00145 if (mpi->mpi_mp3dec) { 00146 MP3FreeDecoder(mpi->mpi_mp3dec); 00147 mpi->mpi_mp3dec = NULL; 00148 } 00149 00150 /* Wait for start event. */ 00151 NutEventWait(&pip->pi_cmdevt, 0); 00152 printf("[PEVT%u]", pip->pi_status); 00153 if (pip->pi_status == PSTAT_START) { 00154 if (mpi->mpi_mp3dec == NULL) { 00155 if ((mpi->mpi_mp3dec = MP3InitDecoder()) == NULL) { 00156 printf("\n[ERR-MP3INI]"); 00157 } 00158 } 00159 if (mpi->mpi_mp3dec && pip->pi_rcvr) { 00160 break; 00161 } 00162 } 00163 } 00164 00165 /* Broadcast running event. */ 00166 printf("[PRUN]"); 00167 pip->pi_status = PSTAT_RUNNING; 00168 NutEventBroadcast(&pip->pi_stsevt); 00169 rip = pip->pi_rcvr; 00170 00171 /* Wait for enough data to start playing. */ 00172 NutSleep(500); 00173 Mp3PlayerBufferFill(pip); 00174 00175 /* Running loop. */ 00176 errcnt = 0; 00177 tmocnt = 0; 00178 first_frame = 1; 00179 while (pip->pi_status == PSTAT_RUNNING) { 00180 /* Wait for new data. */ 00181 if (rip->ri_avail < 2 * MAINBUF_SIZE) { 00182 if (++tmocnt > 4) { 00183 break; 00184 } 00185 Mp3PlayerBufferFill(pip); 00186 continue; 00187 } 00188 if (tmocnt) { 00189 tmocnt--; 00190 } 00191 00192 if (rip->ri_rpos > rip->ri_wpos && MP3_BUFSIZ - rip->ri_rpos < 2 * MAINBUF_SIZE) { 00193 /* The read pointer is in front of the write pointer, but 00194 there is not enough MP3 data at the end of the buffer. 00195 Wrap data from the front to the back, because the decoder 00196 requires a continous buffer. Note, that we allocated the 00197 additional bytes at the end of the MP3 data buffer for 00198 this purpose. */ 00199 memcpy(&rip->ri_buff[MP3_BUFSIZ], rip->ri_buff, 2 * MAINBUF_SIZE - (MP3_BUFSIZ - rip->ri_rpos)); 00200 } 00201 00202 /* Test for sync error. Discard data up to the next sync word. */ 00203 ec = 0; 00204 if ((rbytes = MP3FindSyncWord(&rip->ri_buff[rip->ri_rpos], 2 * MAINBUF_SIZE)) < 0) { 00205 puts("\n[ERR-SYN]"); 00206 break; 00207 } 00208 else if (rbytes == 0) { 00209 /* We are in sync. Decode the next MP3 frame. */ 00210 if (ec == 0) { 00211 rbytes = 2 * MAINBUF_SIZE; 00212 bufptr = &rip->ri_buff[rip->ri_rpos]; 00213 Led0(1); 00214 ec = MP3Decode(mpi->mpi_mp3dec, &bufptr, &rbytes, pip->pi_pcmbuf, 0); 00215 Led0(0); 00216 if (ec) { 00217 rbytes = 0; 00218 } 00219 else { 00220 rbytes = 2 * MAINBUF_SIZE - rbytes; 00221 } 00222 } 00223 if (ec == 0) { 00224 if (first_frame) { 00225 /* 00226 * This is the first frame. Retrieve the frame data, print it 00227 * to the debug port and optionally initialize the resampler. 00228 */ 00229 MP3GetLastFrameInfo(mpi->mpi_mp3dec, &mpi->mpi_frameinfo); 00230 printf("\nBitrate\t\t: %d", mpi->mpi_frameinfo.bitrate); 00231 printf("\nChannels\t: "); 00232 if (mpi->mpi_frameinfo.nChans == 1) { 00233 printf("Mono"); 00234 samprate = mpi->mpi_frameinfo.samprate / 2; 00235 } 00236 else if (mpi->mpi_frameinfo.nChans == 2) { 00237 printf("Stereo"); 00238 samprate = mpi->mpi_frameinfo.samprate; 00239 } 00240 else { 00241 samprate = 0; 00242 putchar('?'); 00243 ec = -1; 00244 } 00245 printf("\nSample rate\t: %d", mpi->mpi_frameinfo.samprate); 00246 if (mpi->mpi_frameinfo.samprate < 8000 || samprate > DAC_OUTPUT_RATE) { 00247 printf(" not supported"); 00248 ec = -1; 00249 } 00250 printf("\nBits/sample\t: %d", mpi->mpi_frameinfo.bitsPerSample); 00251 if (mpi->mpi_frameinfo.bitsPerSample != 16) { 00252 printf(" not supported"); 00253 ec = -1; 00254 } 00255 printf("\nSamples\t\t: %d", mpi->mpi_frameinfo.outputSamps); 00256 #ifdef ENABLE_RESAMPLER 00257 /* If needed, initialize resampler. */ 00258 if (ec == 0 && samprate != DAC_OUTPUT_RATE) { 00259 if ((hres = RAInitResamplerHermite(samprate, DAC_OUTPUT_RATE, mpi->mpi_frameinfo.nChans)) == NULL) { 00260 printf(" failed"); 00261 ec = -1; 00262 } 00263 rs_maxout = RAGetMaxOutputHermite(mpi->mpi_frameinfo.outputSamps, hres); 00264 printf(" -> %d", rs_maxout); 00265 if ((rs_pcmbuf = malloc(rs_maxout * 2)) == NULL) { 00266 printf(" no mem"); 00267 ec = -1; 00268 } 00269 } 00270 #endif 00271 printf("\nLayer\t\t: %d", mpi->mpi_frameinfo.layer); 00272 printf("\nVersion\t\t: %d\n", mpi->mpi_frameinfo.version); 00273 if (ec) { 00274 break; 00275 } 00276 first_frame = 0; 00277 } 00278 if (hres == NULL) { 00279 /* Same rate as our DAC. */ 00280 if (Tlv320DacWrite(pip->pi_pcmbuf, mpi->mpi_frameinfo.outputSamps)) { 00281 puts("\n[**ERR-ADC**]"); 00282 break; 00283 } 00284 } 00285 #ifdef ENABLE_RESAMPLER 00286 else { 00287 int os; 00288 00289 if (mpi->mpi_frameinfo.nChans == 1) { 00290 os = RAResampleMonoHermite(pip->pi_pcmbuf, mpi->mpi_frameinfo.outputSamps, rs_pcmbuf, hres); 00291 } 00292 else { 00293 os = RAResampleStereoHermite(pip->pi_pcmbuf, mpi->mpi_frameinfo.outputSamps, rs_pcmbuf, hres); 00294 } 00295 if (os <= 0) { 00296 puts("\n[**ERR-RSMPLR**]"); 00297 break; 00298 } 00299 if (Tlv320DacWrite(rs_pcmbuf, os)) { 00300 puts("\n[**ERR-ADC**]"); 00301 break; 00302 } 00303 } 00304 #endif 00305 if (radio.rc_rvolume != radio.rc_cvolume) { 00306 Tlv320DacSetVolume(radio.rc_rvolume, radio.rc_rvolume); 00307 radio.rc_cvolume = radio.rc_rvolume; 00308 } 00309 /* Slowly recover from previous errors. */ 00310 if (errcnt) { 00311 errcnt--; 00312 } 00313 } 00314 else { 00315 printf("\n[ERR%d] %u bytes free\n", ec, (u_int)NutHeapAvailable()); 00316 /* Move to idle state in case of fatal errors. */ 00317 if (ec == ERR_MP3_OUT_OF_MEMORY) { 00318 break; 00319 } 00320 /* In case of too many errors move to idle state. */ 00321 if (++errcnt > MAX_PLAYERRORS) { 00322 break; 00323 } 00324 /* Avoid to get stuck on the same error. */ 00325 if (rbytes == 0) { 00326 rbytes = 1; 00327 } 00328 } 00329 } 00330 else { 00331 /* In case of too many sync errors move to idle state. */ 00332 printf("[SKIP %d]", rbytes); 00333 if (++errcnt > MAX_PLAYERRORS) { 00334 break; 00335 } 00336 } 00337 /* Adjust the read pointer and the number of bytes available. */ 00338 rip->ri_avail -= rbytes; 00339 rip->ri_rpos += rbytes; 00340 if (rip->ri_rpos >= MP3_BUFSIZ) { 00341 rip->ri_rpos -= MP3_BUFSIZ; 00342 } 00343 /* Inform the receiver, that we removed data from the buffer. */ 00344 NutEventPost(&rip->ri_wrbque); 00345 } 00346 #ifdef ENABLE_RESAMPLER 00347 if (hres) { 00348 printf("[RSREL]"); 00349 RAFreeResamplerHermite(hres); 00350 hres = NULL; 00351 if (rs_pcmbuf) { 00352 free(rs_pcmbuf); 00353 rs_pcmbuf = NULL; 00354 } 00355 } 00356 #endif 00357 if (Tlv320DacFlush()) { 00358 printf("\n[ERR DACFlush]"); 00359 } 00360 }
|
|
Create MP3 player instance. Called when creating a player instance.
Definition at line 371 of file mp3player.c. 00373 { 00374 /* Allocate local info structure. */ 00375 if ((pip->pi_bcast = malloc(sizeof(MP3PLAYERINFO))) != NULL) { 00376 memset(pip->pi_bcast, 0, sizeof(MP3PLAYERINFO)); 00377 00378 /* Start the player thread. */ 00379 if (NutThreadCreate("mp3play", Mp3PlayerThread, pip, MP3_THREAD_STACK)) { 00380 /* Success! */ 00381 return 0; 00382 } 00383 free(pip->pi_bcast); 00384 } 00385 /* Not enough memory. */ 00386 return -1; 00387
|
|
Setup MP3 player. Doesn't do anything right now.
Definition at line 396 of file mp3player.c.
|
|
Definition at line 70 of file mp3player.c. |
|
Definition at line 77 of file mp3player.c. |
|
Definition at line 78 of file mp3player.c. |
|
Initial value: MP3 player plug-in reference structure.Used by the application to link an MP3 player instance. Definition at line 406 of file mp3player.c. |