Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

mp3player.c

Go to the documentation of this file.
00001 
00044 #include <cfg/os.h>
00045 #include <cfg/clock.h>
00046 #include <dev/board.h>
00047 #include <sys/heap.h>
00048 #include <sys/timer.h>
00049 #include <sys/event.h>
00050 
00051 #include <stdlib.h>
00052 #include <string.h>
00053 
00054 #include <stdio.h>
00055 #include <io.h>
00056 
00057 #include "tlv320dac.h"
00058 #include "webradio.h"
00059 #include "utils.h"
00060 #include "userif.h"
00061 #include "mp3player.h"
00062 
00063 #ifndef MP3_THREAD_STACK
00064 #ifdef AT91SAM7X_EK
00065 #define MP3_THREAD_STACK  1024
00066 #else
00067 #define MP3_THREAD_STACK  2048
00068 #endif
00069 #endif
00070 
00071 static void *hres;
00072 
00073 #if defined (AT91SAM9260_EK)
00074 #define ENABLE_RESAMPLER
00075 #endif
00076 
00077 #ifdef ENABLE_RESAMPLER
00078 static int rs_maxout;
00079 static short *rs_pcmbuf;
00080 #endif
00081 
00087 static void Mp3PlayerBufferFill(PLAYERINFO *pip)
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());
00114 }
00115 
00121 THREAD(Mp3PlayerThread, arg)
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     }
00361 }
00362 
00372 int Mp3PlayerCreate(PLAYERINFO *pip)
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 
00388 }
00389 
00397 int Mp3PlayerSetup(PLAYERINFO *pip)
00398 {
00399     return 0;
00400 }
00401 
00407 PLAYERPLUGIN ppiMp3 = {
00408     Mp3PlayerCreate,    
00409     Mp3PlayerSetup      
00410 };

Generated on Fri Feb 23 17:28:49 2007 for SAM Internet Radio by  doxygen 1.4.4