This program plays an internet radio audio stream like Shoutcast.
Dependencies: EthernetNetIf mbed HTTPClient
Diff: main.cpp
- Revision:
- 0:37da71b87d96
diff -r 000000000000 -r 37da71b87d96 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 01 06:22:50 2011 +0000 @@ -0,0 +1,305 @@ + +#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(); + + } + +} \ No newline at end of file