This program plays an internet radio audio stream like Shoutcast.

Dependencies:   EthernetNetIf mbed HTTPClient

main.cpp

Committer:
parik
Date:
2011-03-01
Revision:
0:37da71b87d96

File content as of revision 0:37da71b87d96:


#include "mbed.h"
#include "VS1002.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#include "TCPSocket.h"
#include "MSCFileSystem.h"

#define SBUFSIZE (1024*4)
//Select the time to play 1000 k of data in this case
#define MAXSIZE (250*1000)

//         PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
//         PinName dreq, PinName dcs, PinName vol)
VS1002 mp3(p11, p12, p13, p14, p15,p16, p17, p20); 

//Print or debug on the serail port/hyperterminal
Serial pc(USBTX,USBRX);
EthernetNetIf eth; 

//TCP socket to connectto server,receive data
TCPSocket sock;


char sResponse[800]; // keeps Stream Response
char sMetadata[200]; // keeps Stream Metadata
char sPrevMetadata[200]; // keeps Previous Stream Metadata
int metaint=0; // metadate interval

// client state
 enum wSTATE{NOP,PUT_HEADER} WriteState;
 enum rSTATE{GET_RESPONSE,GET_STREAM} ReadState;

char inbuf[2048]; // IP input buffer
char* cp; 
// stream
int slen; // stream length
unsigned long int tlen=0; // total lenth of downloaded file


//Buffer the data to a file on flash drive
FILE *fp;
MSCFileSystem msc("msc");

//Create a file on the flash drive for writing
void CreateFile ()
{
fp = fopen("/msc/stream.mp3", "wb");
}

//Write the mp3 data to the file created
void WriteFile(unsigned char sbyte)
{
unsigned char wc=sbyte;
fwrite(&wc,1,1,fp);
tlen++;
if (tlen==MAXSIZE)
{
fclose(fp);
//Play the file
mp3.play_song();
//Loop and read the next stream of data 
tlen=0;
CreateFile();
}
}

class RingBuffer
{
     protected:
         unsigned char *buffer;
         int buffersize;
         int rp; // read index
         int wp; // write index
     

     public:
         RingBuffer(int bufsiz)
         {
             buffersize = bufsiz;
      
             buffer = new unsigned char[buffersize];
         //    memset(buffer, 0, sizeof(char) * buffersize);  
             // reset pointer to make empty
             rp = 0;
             wp = 0;
         };
  
         ~RingBuffer(void)
         {
             delete[] buffer;
         };
  
         int GetByte(unsigned char *cp);
         int PutByte(unsigned char c);
         int IsEmpty(void); 
 };


 int RingBuffer::GetByte(unsigned char *cp )
 {
    if( rp != wp ) {    // not empty
       *cp = buffer[rp];
       rp = (rp + 1) % buffersize;
       return 0;
    } else {            // empty
       return -1;
    }
 }

int RingBuffer::PutByte(unsigned char c )
 {
    int next = (wp + 1) % buffersize;
    if( next == rp ) {
       pc.printf("*** Buffer Full ***\r\n" );
 //        printf("*");//debug
        return -1;
    }
    buffer[wp] = c;
    wp = next;
    return 0;
 }

int RingBuffer::IsEmpty(void)
 {
    return  (rp==wp)?(true):(false);
 }

RingBuffer  sbuf(SBUFSIZE);


//Check for appropriate event by polling network stack and handle
void onTCPSocketEvent(TCPSocketEvent e) 
{
 int i,len;
  switch (e) 
   {
     case TCPSOCKET_CONNECTED:
                  pc.printf("TCP Socket Connected\r\n"); // this printf disturb socket work correctly
//        break; // we must comment out ?
     case TCPSOCKET_WRITEABLE:
       switch (WriteState)
        {
         case PUT_HEADER:
     //Can now write some data...
          const char* str =
                  "GET /stream/1074 HTTP/1.0\r\n"
                  "Host: gw\r\n"
                  "Accept: */*\r\n"
                  "User-Agent: mbed\r\n"
 #ifdef METADATA
                  "Icy-MetaData: 1\r\n"   // send this if you want Metadata
 #endif
                  //"Connection: close\r\n"
                  "\r\n"
                     ;
                   sock.send(str, strlen(str));
                   pc.printf("\r\nHEADER:\r\n%s\r\n", str); // display PUT_HEADER
                   WriteState=NOP;
                   ReadState=GET_RESPONSE;
                   break;
             case NOP:
                   break;
               }
               break;    
      case TCPSOCKET_READABLE:
      //Can now read some data...
            switch(ReadState)
             {
               case GET_RESPONSE:
                 len=sock.recv(inbuf, sizeof inbuf);
                 cp=strstr(inbuf,"\r\n\r\n");
                 if (cp==NULL) 
                  {
                   inbuf[len]=0;
                    // printf("%s",inbuf); // debug
                   sprintf(sResponse,"%s",inbuf);
                   return;  // still read response again
                  }
                     //
                     *cp=0;
                     sprintf(sResponse+strlen(sResponse),"%s\r\n\r\n",inbuf);
                     pc.printf("RESPONSE:\r\n%s",sResponse);
                     // get metaint value
                     cp=strstr(sResponse,"icy-metaint:");
                     if (cp==NULL) metaint=0; else sscanf(cp+strlen("icy-metaint:"),"%d",&metaint);
                     pc.printf("\r\nmetaint: %d\r\n\r\n",metaint); //debug
                     //
                     i=strlen(inbuf)+4; // bump bitstream right after response
                     ReadState=GET_STREAM;
                     CreateFile();
                     
                     //
                     while(i<len) {
                             // write one bye
                             sbuf.PutByte(inbuf[i]);i++;
                     };
                     return;
                     break;
                  
                 case GET_STREAM:
                     // receive data ****repeatedly****                                          
                     //pc.printf("Stream receiving\n");
                     while(len=sock.recv(inbuf, sizeof inbuf)) {
                         i=0;                    
                         // save len bytes
                        while (i<len) {
                                                         
                             WriteFile(inbuf[i]);                            
                             i++;
                         } 
                        
                         //pc.printf("%s\n",inbuf);
                        
                     } // while (len=sock...)
                     return; // get more stream
                     break;           
                     //
                 } // switch (ReadState)
                 break;//
      case TCPSOCKET_CONTIMEOUT:
                 pc.printf("TCP Socket Timeout\r\n");
                 break;
      case TCPSOCKET_CONRST:
                pc.printf("TCP Socket CONRST\r\n");
                break;
      case TCPSOCKET_CONABRT:
                pc.printf("TCP Socket CONABRT\r\n");
                pc.printf("Maybe Server Down...\r\n");
                break;
      case TCPSOCKET_ERROR:
                pc.printf("TCP Socket Error\r\n");
                break;
      case TCPSOCKET_DISCONNECTED:
             //Close socket...
                pc.printf("TCP Socket Disconnected\r\n");
                sock.close();
                break;
     }// switch(e)
 }



int main () {


    /*============================================================
     * MP3 Initialising
     *==========================================================*/
#ifndef FS_ONLY
    mp3._RST = 1;
    mp3.cs_high();                                   //chip disabled
    mp3.sci_initialise();                            //initialise MBED
    mp3.sci_write(0x00,(SM_SDINEW+SM_STREAM+SM_DIFF));
    mp3.sci_write(0x03, 0x9800);
    mp3.sdi_initialise();
#endif

   /*================================================================
      Networking setup
   ==================================================================*/

  pc.printf("Start\n");

  pc.printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    pc.printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  pc.printf("Setup OK\n");
  
  sprintf(sMetadata,"StreamTitle='Currently, Unknown';");
  sprintf(sPrevMetadata,"");

// Init State for Read/Write
  ReadState=GET_RESPONSE;
  WriteState=PUT_HEADER;

  //Host server(IpAddr(208,80,55,219), 10012);
  //208.80.55.219
  
  Host server(IpAddr(205,188,234,1),80);   //IP 205.188.234.1 ,Port 80
  //http://scfire-dtc-aa01.stream.aol.com:80/stream/1074 (205,188,234,1)
  
  
  // display IP address and port# of server
  IpAddr serverIp = server.getIp();
  int port = server.getPort();   

  pc.printf("Connecting... %d.%d.%d.%d:%d\r\n", serverIp[0],serverIp[1],serverIp[2],serverIp[3],port);
  TCPSocketErr bindErr = sock.connect(server);
  pc.printf("Connected\n");
  sock.setOnEvent(&onTCPSocketEvent);


//Poll the networking stack     
    while (true)
    {    
      Net::poll();
         
    }

}