This program plays an internet radio audio stream like Shoutcast.

Dependencies:   EthernetNetIf mbed HTTPClient

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 #include "mbed.h"
00003 #include "VS1002.h"
00004 #include "EthernetNetIf.h"
00005 #include "HTTPClient.h"
00006 #include "TCPSocket.h"
00007 #include "MSCFileSystem.h"
00008 
00009 #define SBUFSIZE (1024*4)
00010 //Select the time to play 1000 k of data in this case
00011 #define MAXSIZE (250*1000)
00012 
00013 //         PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
00014 //         PinName dreq, PinName dcs, PinName vol)
00015 VS1002 mp3(p11, p12, p13, p14, p15,p16, p17, p20); 
00016 
00017 //Print or debug on the serail port/hyperterminal
00018 Serial pc(USBTX,USBRX);
00019 EthernetNetIf eth; 
00020 
00021 //TCP socket to connectto server,receive data
00022 TCPSocket sock;
00023 
00024 
00025 char sResponse[800]; // keeps Stream Response
00026 char sMetadata[200]; // keeps Stream Metadata
00027 char sPrevMetadata[200]; // keeps Previous Stream Metadata
00028 int metaint=0; // metadate interval
00029 
00030 // client state
00031  enum wSTATE{NOP,PUT_HEADER} WriteState;
00032  enum rSTATE{GET_RESPONSE,GET_STREAM} ReadState;
00033 
00034 char inbuf[2048]; // IP input buffer
00035 char* cp; 
00036 // stream
00037 int slen; // stream length
00038 unsigned long int tlen=0; // total lenth of downloaded file
00039 
00040 
00041 //Buffer the data to a file on flash drive
00042 FILE *fp;
00043 MSCFileSystem msc("msc");
00044 
00045 //Create a file on the flash drive for writing
00046 void CreateFile ()
00047 {
00048 fp = fopen("/msc/stream.mp3", "wb");
00049 }
00050 
00051 //Write the mp3 data to the file created
00052 void WriteFile(unsigned char sbyte)
00053 {
00054 unsigned char wc=sbyte;
00055 fwrite(&wc,1,1,fp);
00056 tlen++;
00057 if (tlen==MAXSIZE)
00058 {
00059 fclose(fp);
00060 //Play the file
00061 mp3.play_song();
00062 //Loop and read the next stream of data 
00063 tlen=0;
00064 CreateFile();
00065 }
00066 }
00067 
00068 class RingBuffer
00069 {
00070      protected:
00071          unsigned char *buffer;
00072          int buffersize;
00073          int rp; // read index
00074          int wp; // write index
00075      
00076 
00077      public:
00078          RingBuffer(int bufsiz)
00079          {
00080              buffersize = bufsiz;
00081       
00082              buffer = new unsigned char[buffersize];
00083          //    memset(buffer, 0, sizeof(char) * buffersize);  
00084              // reset pointer to make empty
00085              rp = 0;
00086              wp = 0;
00087          };
00088   
00089          ~RingBuffer(void)
00090          {
00091              delete[] buffer;
00092          };
00093   
00094          int GetByte(unsigned char *cp);
00095          int PutByte(unsigned char c);
00096          int IsEmpty(void); 
00097  };
00098 
00099 
00100  int RingBuffer::GetByte(unsigned char *cp )
00101  {
00102     if( rp != wp ) {    // not empty
00103        *cp = buffer[rp];
00104        rp = (rp + 1) % buffersize;
00105        return 0;
00106     } else {            // empty
00107        return -1;
00108     }
00109  }
00110 
00111 int RingBuffer::PutByte(unsigned char c )
00112  {
00113     int next = (wp + 1) % buffersize;
00114     if( next == rp ) {
00115        pc.printf("*** Buffer Full ***\r\n" );
00116  //        printf("*");//debug
00117         return -1;
00118     }
00119     buffer[wp] = c;
00120     wp = next;
00121     return 0;
00122  }
00123 
00124 int RingBuffer::IsEmpty(void)
00125  {
00126     return  (rp==wp)?(true):(false);
00127  }
00128 
00129 RingBuffer  sbuf(SBUFSIZE);
00130 
00131 
00132 //Check for appropriate event by polling network stack and handle
00133 void onTCPSocketEvent(TCPSocketEvent e) 
00134 {
00135  int i,len;
00136   switch (e) 
00137    {
00138      case TCPSOCKET_CONNECTED:
00139                   pc.printf("TCP Socket Connected\r\n"); // this printf disturb socket work correctly
00140 //        break; // we must comment out ?
00141      case TCPSOCKET_WRITEABLE:
00142        switch (WriteState)
00143         {
00144          case PUT_HEADER:
00145      //Can now write some data...
00146           const char* str =
00147                   "GET /stream/1074 HTTP/1.0\r\n"
00148                   "Host: gw\r\n"
00149                   "Accept: */*\r\n"
00150                   "User-Agent: mbed\r\n"
00151  #ifdef METADATA
00152                   "Icy-MetaData: 1\r\n"   // send this if you want Metadata
00153  #endif
00154                   //"Connection: close\r\n"
00155                   "\r\n"
00156                      ;
00157                    sock.send(str, strlen(str));
00158                    pc.printf("\r\nHEADER:\r\n%s\r\n", str); // display PUT_HEADER
00159                    WriteState=NOP;
00160                    ReadState=GET_RESPONSE;
00161                    break;
00162              case NOP:
00163                    break;
00164                }
00165                break;    
00166       case TCPSOCKET_READABLE:
00167       //Can now read some data...
00168             switch(ReadState)
00169              {
00170                case GET_RESPONSE:
00171                  len=sock.recv(inbuf, sizeof inbuf);
00172                  cp=strstr(inbuf,"\r\n\r\n");
00173                  if (cp==NULL) 
00174                   {
00175                    inbuf[len]=0;
00176                     // printf("%s",inbuf); // debug
00177                    sprintf(sResponse,"%s",inbuf);
00178                    return;  // still read response again
00179                   }
00180                      //
00181                      *cp=0;
00182                      sprintf(sResponse+strlen(sResponse),"%s\r\n\r\n",inbuf);
00183                      pc.printf("RESPONSE:\r\n%s",sResponse);
00184                      // get metaint value
00185                      cp=strstr(sResponse,"icy-metaint:");
00186                      if (cp==NULL) metaint=0; else sscanf(cp+strlen("icy-metaint:"),"%d",&metaint);
00187                      pc.printf("\r\nmetaint: %d\r\n\r\n",metaint); //debug
00188                      //
00189                      i=strlen(inbuf)+4; // bump bitstream right after response
00190                      ReadState=GET_STREAM;
00191                      CreateFile();
00192                      
00193                      //
00194                      while(i<len) {
00195                              // write one bye
00196                              sbuf.PutByte(inbuf[i]);i++;
00197                      };
00198                      return;
00199                      break;
00200                   
00201                  case GET_STREAM:
00202                      // receive data ****repeatedly****                                          
00203                      //pc.printf("Stream receiving\n");
00204                      while(len=sock.recv(inbuf, sizeof inbuf)) {
00205                          i=0;                    
00206                          // save len bytes
00207                         while (i<len) {
00208                                                          
00209                              WriteFile(inbuf[i]);                            
00210                              i++;
00211                          } 
00212                         
00213                          //pc.printf("%s\n",inbuf);
00214                         
00215                      } // while (len=sock...)
00216                      return; // get more stream
00217                      break;           
00218                      //
00219                  } // switch (ReadState)
00220                  break;//
00221       case TCPSOCKET_CONTIMEOUT:
00222                  pc.printf("TCP Socket Timeout\r\n");
00223                  break;
00224       case TCPSOCKET_CONRST:
00225                 pc.printf("TCP Socket CONRST\r\n");
00226                 break;
00227       case TCPSOCKET_CONABRT:
00228                 pc.printf("TCP Socket CONABRT\r\n");
00229                 pc.printf("Maybe Server Down...\r\n");
00230                 break;
00231       case TCPSOCKET_ERROR:
00232                 pc.printf("TCP Socket Error\r\n");
00233                 break;
00234       case TCPSOCKET_DISCONNECTED:
00235              //Close socket...
00236                 pc.printf("TCP Socket Disconnected\r\n");
00237                 sock.close();
00238                 break;
00239      }// switch(e)
00240  }
00241 
00242 
00243 
00244 int main () {
00245 
00246 
00247     /*============================================================
00248      * MP3 Initialising
00249      *==========================================================*/
00250 #ifndef FS_ONLY
00251     mp3._RST = 1;
00252     mp3.cs_high();                                   //chip disabled
00253     mp3.sci_initialise();                            //initialise MBED
00254     mp3.sci_write(0x00,(SM_SDINEW+SM_STREAM+SM_DIFF));
00255     mp3.sci_write(0x03, 0x9800);
00256     mp3.sdi_initialise();
00257 #endif
00258 
00259    /*================================================================
00260       Networking setup
00261    ==================================================================*/
00262 
00263   pc.printf("Start\n");
00264 
00265   pc.printf("Setting up...\n");
00266   EthernetErr ethErr = eth.setup();
00267   if(ethErr)
00268   {
00269     pc.printf("Error %d in setup.\n", ethErr);
00270     return -1;
00271   }
00272   pc.printf("Setup OK\n");
00273   
00274   sprintf(sMetadata,"StreamTitle='Currently, Unknown';");
00275   sprintf(sPrevMetadata,"");
00276 
00277 // Init State for Read/Write
00278   ReadState=GET_RESPONSE;
00279   WriteState=PUT_HEADER;
00280 
00281   //Host server(IpAddr(208,80,55,219), 10012);
00282   //208.80.55.219
00283   
00284   Host server(IpAddr(205,188,234,1),80);   //IP 205.188.234.1 ,Port 80
00285   //http://scfire-dtc-aa01.stream.aol.com:80/stream/1074 (205,188,234,1)
00286   
00287   
00288   // display IP address and port# of server
00289   IpAddr serverIp = server.getIp();
00290   int port = server.getPort();   
00291 
00292   pc.printf("Connecting... %d.%d.%d.%d:%d\r\n", serverIp[0],serverIp[1],serverIp[2],serverIp[3],port);
00293   TCPSocketErr bindErr = sock.connect(server);
00294   pc.printf("Connected\n");
00295   sock.setOnEvent(&onTCPSocketEvent);
00296 
00297 
00298 //Poll the networking stack     
00299     while (true)
00300     {    
00301       Net::poll();
00302          
00303     }
00304 
00305 }