This program plays an internet radio audio stream like Shoutcast.

Dependencies:   EthernetNetIf mbed HTTPClient

Committer:
parik
Date:
Tue Mar 01 06:22:50 2011 +0000
Revision:
0:37da71b87d96

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
parik 0:37da71b87d96 1
parik 0:37da71b87d96 2 #include "mbed.h"
parik 0:37da71b87d96 3 #include "VS1002.h"
parik 0:37da71b87d96 4 #include "EthernetNetIf.h"
parik 0:37da71b87d96 5 #include "HTTPClient.h"
parik 0:37da71b87d96 6 #include "TCPSocket.h"
parik 0:37da71b87d96 7 #include "MSCFileSystem.h"
parik 0:37da71b87d96 8
parik 0:37da71b87d96 9 #define SBUFSIZE (1024*4)
parik 0:37da71b87d96 10 //Select the time to play 1000 k of data in this case
parik 0:37da71b87d96 11 #define MAXSIZE (250*1000)
parik 0:37da71b87d96 12
parik 0:37da71b87d96 13 // PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst,
parik 0:37da71b87d96 14 // PinName dreq, PinName dcs, PinName vol)
parik 0:37da71b87d96 15 VS1002 mp3(p11, p12, p13, p14, p15,p16, p17, p20);
parik 0:37da71b87d96 16
parik 0:37da71b87d96 17 //Print or debug on the serail port/hyperterminal
parik 0:37da71b87d96 18 Serial pc(USBTX,USBRX);
parik 0:37da71b87d96 19 EthernetNetIf eth;
parik 0:37da71b87d96 20
parik 0:37da71b87d96 21 //TCP socket to connectto server,receive data
parik 0:37da71b87d96 22 TCPSocket sock;
parik 0:37da71b87d96 23
parik 0:37da71b87d96 24
parik 0:37da71b87d96 25 char sResponse[800]; // keeps Stream Response
parik 0:37da71b87d96 26 char sMetadata[200]; // keeps Stream Metadata
parik 0:37da71b87d96 27 char sPrevMetadata[200]; // keeps Previous Stream Metadata
parik 0:37da71b87d96 28 int metaint=0; // metadate interval
parik 0:37da71b87d96 29
parik 0:37da71b87d96 30 // client state
parik 0:37da71b87d96 31 enum wSTATE{NOP,PUT_HEADER} WriteState;
parik 0:37da71b87d96 32 enum rSTATE{GET_RESPONSE,GET_STREAM} ReadState;
parik 0:37da71b87d96 33
parik 0:37da71b87d96 34 char inbuf[2048]; // IP input buffer
parik 0:37da71b87d96 35 char* cp;
parik 0:37da71b87d96 36 // stream
parik 0:37da71b87d96 37 int slen; // stream length
parik 0:37da71b87d96 38 unsigned long int tlen=0; // total lenth of downloaded file
parik 0:37da71b87d96 39
parik 0:37da71b87d96 40
parik 0:37da71b87d96 41 //Buffer the data to a file on flash drive
parik 0:37da71b87d96 42 FILE *fp;
parik 0:37da71b87d96 43 MSCFileSystem msc("msc");
parik 0:37da71b87d96 44
parik 0:37da71b87d96 45 //Create a file on the flash drive for writing
parik 0:37da71b87d96 46 void CreateFile ()
parik 0:37da71b87d96 47 {
parik 0:37da71b87d96 48 fp = fopen("/msc/stream.mp3", "wb");
parik 0:37da71b87d96 49 }
parik 0:37da71b87d96 50
parik 0:37da71b87d96 51 //Write the mp3 data to the file created
parik 0:37da71b87d96 52 void WriteFile(unsigned char sbyte)
parik 0:37da71b87d96 53 {
parik 0:37da71b87d96 54 unsigned char wc=sbyte;
parik 0:37da71b87d96 55 fwrite(&wc,1,1,fp);
parik 0:37da71b87d96 56 tlen++;
parik 0:37da71b87d96 57 if (tlen==MAXSIZE)
parik 0:37da71b87d96 58 {
parik 0:37da71b87d96 59 fclose(fp);
parik 0:37da71b87d96 60 //Play the file
parik 0:37da71b87d96 61 mp3.play_song();
parik 0:37da71b87d96 62 //Loop and read the next stream of data
parik 0:37da71b87d96 63 tlen=0;
parik 0:37da71b87d96 64 CreateFile();
parik 0:37da71b87d96 65 }
parik 0:37da71b87d96 66 }
parik 0:37da71b87d96 67
parik 0:37da71b87d96 68 class RingBuffer
parik 0:37da71b87d96 69 {
parik 0:37da71b87d96 70 protected:
parik 0:37da71b87d96 71 unsigned char *buffer;
parik 0:37da71b87d96 72 int buffersize;
parik 0:37da71b87d96 73 int rp; // read index
parik 0:37da71b87d96 74 int wp; // write index
parik 0:37da71b87d96 75
parik 0:37da71b87d96 76
parik 0:37da71b87d96 77 public:
parik 0:37da71b87d96 78 RingBuffer(int bufsiz)
parik 0:37da71b87d96 79 {
parik 0:37da71b87d96 80 buffersize = bufsiz;
parik 0:37da71b87d96 81
parik 0:37da71b87d96 82 buffer = new unsigned char[buffersize];
parik 0:37da71b87d96 83 // memset(buffer, 0, sizeof(char) * buffersize);
parik 0:37da71b87d96 84 // reset pointer to make empty
parik 0:37da71b87d96 85 rp = 0;
parik 0:37da71b87d96 86 wp = 0;
parik 0:37da71b87d96 87 };
parik 0:37da71b87d96 88
parik 0:37da71b87d96 89 ~RingBuffer(void)
parik 0:37da71b87d96 90 {
parik 0:37da71b87d96 91 delete[] buffer;
parik 0:37da71b87d96 92 };
parik 0:37da71b87d96 93
parik 0:37da71b87d96 94 int GetByte(unsigned char *cp);
parik 0:37da71b87d96 95 int PutByte(unsigned char c);
parik 0:37da71b87d96 96 int IsEmpty(void);
parik 0:37da71b87d96 97 };
parik 0:37da71b87d96 98
parik 0:37da71b87d96 99
parik 0:37da71b87d96 100 int RingBuffer::GetByte(unsigned char *cp )
parik 0:37da71b87d96 101 {
parik 0:37da71b87d96 102 if( rp != wp ) { // not empty
parik 0:37da71b87d96 103 *cp = buffer[rp];
parik 0:37da71b87d96 104 rp = (rp + 1) % buffersize;
parik 0:37da71b87d96 105 return 0;
parik 0:37da71b87d96 106 } else { // empty
parik 0:37da71b87d96 107 return -1;
parik 0:37da71b87d96 108 }
parik 0:37da71b87d96 109 }
parik 0:37da71b87d96 110
parik 0:37da71b87d96 111 int RingBuffer::PutByte(unsigned char c )
parik 0:37da71b87d96 112 {
parik 0:37da71b87d96 113 int next = (wp + 1) % buffersize;
parik 0:37da71b87d96 114 if( next == rp ) {
parik 0:37da71b87d96 115 pc.printf("*** Buffer Full ***\r\n" );
parik 0:37da71b87d96 116 // printf("*");//debug
parik 0:37da71b87d96 117 return -1;
parik 0:37da71b87d96 118 }
parik 0:37da71b87d96 119 buffer[wp] = c;
parik 0:37da71b87d96 120 wp = next;
parik 0:37da71b87d96 121 return 0;
parik 0:37da71b87d96 122 }
parik 0:37da71b87d96 123
parik 0:37da71b87d96 124 int RingBuffer::IsEmpty(void)
parik 0:37da71b87d96 125 {
parik 0:37da71b87d96 126 return (rp==wp)?(true):(false);
parik 0:37da71b87d96 127 }
parik 0:37da71b87d96 128
parik 0:37da71b87d96 129 RingBuffer sbuf(SBUFSIZE);
parik 0:37da71b87d96 130
parik 0:37da71b87d96 131
parik 0:37da71b87d96 132 //Check for appropriate event by polling network stack and handle
parik 0:37da71b87d96 133 void onTCPSocketEvent(TCPSocketEvent e)
parik 0:37da71b87d96 134 {
parik 0:37da71b87d96 135 int i,len;
parik 0:37da71b87d96 136 switch (e)
parik 0:37da71b87d96 137 {
parik 0:37da71b87d96 138 case TCPSOCKET_CONNECTED:
parik 0:37da71b87d96 139 pc.printf("TCP Socket Connected\r\n"); // this printf disturb socket work correctly
parik 0:37da71b87d96 140 // break; // we must comment out ?
parik 0:37da71b87d96 141 case TCPSOCKET_WRITEABLE:
parik 0:37da71b87d96 142 switch (WriteState)
parik 0:37da71b87d96 143 {
parik 0:37da71b87d96 144 case PUT_HEADER:
parik 0:37da71b87d96 145 //Can now write some data...
parik 0:37da71b87d96 146 const char* str =
parik 0:37da71b87d96 147 "GET /stream/1074 HTTP/1.0\r\n"
parik 0:37da71b87d96 148 "Host: gw\r\n"
parik 0:37da71b87d96 149 "Accept: */*\r\n"
parik 0:37da71b87d96 150 "User-Agent: mbed\r\n"
parik 0:37da71b87d96 151 #ifdef METADATA
parik 0:37da71b87d96 152 "Icy-MetaData: 1\r\n" // send this if you want Metadata
parik 0:37da71b87d96 153 #endif
parik 0:37da71b87d96 154 //"Connection: close\r\n"
parik 0:37da71b87d96 155 "\r\n"
parik 0:37da71b87d96 156 ;
parik 0:37da71b87d96 157 sock.send(str, strlen(str));
parik 0:37da71b87d96 158 pc.printf("\r\nHEADER:\r\n%s\r\n", str); // display PUT_HEADER
parik 0:37da71b87d96 159 WriteState=NOP;
parik 0:37da71b87d96 160 ReadState=GET_RESPONSE;
parik 0:37da71b87d96 161 break;
parik 0:37da71b87d96 162 case NOP:
parik 0:37da71b87d96 163 break;
parik 0:37da71b87d96 164 }
parik 0:37da71b87d96 165 break;
parik 0:37da71b87d96 166 case TCPSOCKET_READABLE:
parik 0:37da71b87d96 167 //Can now read some data...
parik 0:37da71b87d96 168 switch(ReadState)
parik 0:37da71b87d96 169 {
parik 0:37da71b87d96 170 case GET_RESPONSE:
parik 0:37da71b87d96 171 len=sock.recv(inbuf, sizeof inbuf);
parik 0:37da71b87d96 172 cp=strstr(inbuf,"\r\n\r\n");
parik 0:37da71b87d96 173 if (cp==NULL)
parik 0:37da71b87d96 174 {
parik 0:37da71b87d96 175 inbuf[len]=0;
parik 0:37da71b87d96 176 // printf("%s",inbuf); // debug
parik 0:37da71b87d96 177 sprintf(sResponse,"%s",inbuf);
parik 0:37da71b87d96 178 return; // still read response again
parik 0:37da71b87d96 179 }
parik 0:37da71b87d96 180 //
parik 0:37da71b87d96 181 *cp=0;
parik 0:37da71b87d96 182 sprintf(sResponse+strlen(sResponse),"%s\r\n\r\n",inbuf);
parik 0:37da71b87d96 183 pc.printf("RESPONSE:\r\n%s",sResponse);
parik 0:37da71b87d96 184 // get metaint value
parik 0:37da71b87d96 185 cp=strstr(sResponse,"icy-metaint:");
parik 0:37da71b87d96 186 if (cp==NULL) metaint=0; else sscanf(cp+strlen("icy-metaint:"),"%d",&metaint);
parik 0:37da71b87d96 187 pc.printf("\r\nmetaint: %d\r\n\r\n",metaint); //debug
parik 0:37da71b87d96 188 //
parik 0:37da71b87d96 189 i=strlen(inbuf)+4; // bump bitstream right after response
parik 0:37da71b87d96 190 ReadState=GET_STREAM;
parik 0:37da71b87d96 191 CreateFile();
parik 0:37da71b87d96 192
parik 0:37da71b87d96 193 //
parik 0:37da71b87d96 194 while(i<len) {
parik 0:37da71b87d96 195 // write one bye
parik 0:37da71b87d96 196 sbuf.PutByte(inbuf[i]);i++;
parik 0:37da71b87d96 197 };
parik 0:37da71b87d96 198 return;
parik 0:37da71b87d96 199 break;
parik 0:37da71b87d96 200
parik 0:37da71b87d96 201 case GET_STREAM:
parik 0:37da71b87d96 202 // receive data ****repeatedly****
parik 0:37da71b87d96 203 //pc.printf("Stream receiving\n");
parik 0:37da71b87d96 204 while(len=sock.recv(inbuf, sizeof inbuf)) {
parik 0:37da71b87d96 205 i=0;
parik 0:37da71b87d96 206 // save len bytes
parik 0:37da71b87d96 207 while (i<len) {
parik 0:37da71b87d96 208
parik 0:37da71b87d96 209 WriteFile(inbuf[i]);
parik 0:37da71b87d96 210 i++;
parik 0:37da71b87d96 211 }
parik 0:37da71b87d96 212
parik 0:37da71b87d96 213 //pc.printf("%s\n",inbuf);
parik 0:37da71b87d96 214
parik 0:37da71b87d96 215 } // while (len=sock...)
parik 0:37da71b87d96 216 return; // get more stream
parik 0:37da71b87d96 217 break;
parik 0:37da71b87d96 218 //
parik 0:37da71b87d96 219 } // switch (ReadState)
parik 0:37da71b87d96 220 break;//
parik 0:37da71b87d96 221 case TCPSOCKET_CONTIMEOUT:
parik 0:37da71b87d96 222 pc.printf("TCP Socket Timeout\r\n");
parik 0:37da71b87d96 223 break;
parik 0:37da71b87d96 224 case TCPSOCKET_CONRST:
parik 0:37da71b87d96 225 pc.printf("TCP Socket CONRST\r\n");
parik 0:37da71b87d96 226 break;
parik 0:37da71b87d96 227 case TCPSOCKET_CONABRT:
parik 0:37da71b87d96 228 pc.printf("TCP Socket CONABRT\r\n");
parik 0:37da71b87d96 229 pc.printf("Maybe Server Down...\r\n");
parik 0:37da71b87d96 230 break;
parik 0:37da71b87d96 231 case TCPSOCKET_ERROR:
parik 0:37da71b87d96 232 pc.printf("TCP Socket Error\r\n");
parik 0:37da71b87d96 233 break;
parik 0:37da71b87d96 234 case TCPSOCKET_DISCONNECTED:
parik 0:37da71b87d96 235 //Close socket...
parik 0:37da71b87d96 236 pc.printf("TCP Socket Disconnected\r\n");
parik 0:37da71b87d96 237 sock.close();
parik 0:37da71b87d96 238 break;
parik 0:37da71b87d96 239 }// switch(e)
parik 0:37da71b87d96 240 }
parik 0:37da71b87d96 241
parik 0:37da71b87d96 242
parik 0:37da71b87d96 243
parik 0:37da71b87d96 244 int main () {
parik 0:37da71b87d96 245
parik 0:37da71b87d96 246
parik 0:37da71b87d96 247 /*============================================================
parik 0:37da71b87d96 248 * MP3 Initialising
parik 0:37da71b87d96 249 *==========================================================*/
parik 0:37da71b87d96 250 #ifndef FS_ONLY
parik 0:37da71b87d96 251 mp3._RST = 1;
parik 0:37da71b87d96 252 mp3.cs_high(); //chip disabled
parik 0:37da71b87d96 253 mp3.sci_initialise(); //initialise MBED
parik 0:37da71b87d96 254 mp3.sci_write(0x00,(SM_SDINEW+SM_STREAM+SM_DIFF));
parik 0:37da71b87d96 255 mp3.sci_write(0x03, 0x9800);
parik 0:37da71b87d96 256 mp3.sdi_initialise();
parik 0:37da71b87d96 257 #endif
parik 0:37da71b87d96 258
parik 0:37da71b87d96 259 /*================================================================
parik 0:37da71b87d96 260 Networking setup
parik 0:37da71b87d96 261 ==================================================================*/
parik 0:37da71b87d96 262
parik 0:37da71b87d96 263 pc.printf("Start\n");
parik 0:37da71b87d96 264
parik 0:37da71b87d96 265 pc.printf("Setting up...\n");
parik 0:37da71b87d96 266 EthernetErr ethErr = eth.setup();
parik 0:37da71b87d96 267 if(ethErr)
parik 0:37da71b87d96 268 {
parik 0:37da71b87d96 269 pc.printf("Error %d in setup.\n", ethErr);
parik 0:37da71b87d96 270 return -1;
parik 0:37da71b87d96 271 }
parik 0:37da71b87d96 272 pc.printf("Setup OK\n");
parik 0:37da71b87d96 273
parik 0:37da71b87d96 274 sprintf(sMetadata,"StreamTitle='Currently, Unknown';");
parik 0:37da71b87d96 275 sprintf(sPrevMetadata,"");
parik 0:37da71b87d96 276
parik 0:37da71b87d96 277 // Init State for Read/Write
parik 0:37da71b87d96 278 ReadState=GET_RESPONSE;
parik 0:37da71b87d96 279 WriteState=PUT_HEADER;
parik 0:37da71b87d96 280
parik 0:37da71b87d96 281 //Host server(IpAddr(208,80,55,219), 10012);
parik 0:37da71b87d96 282 //208.80.55.219
parik 0:37da71b87d96 283
parik 0:37da71b87d96 284 Host server(IpAddr(205,188,234,1),80); //IP 205.188.234.1 ,Port 80
parik 0:37da71b87d96 285 //http://scfire-dtc-aa01.stream.aol.com:80/stream/1074 (205,188,234,1)
parik 0:37da71b87d96 286
parik 0:37da71b87d96 287
parik 0:37da71b87d96 288 // display IP address and port# of server
parik 0:37da71b87d96 289 IpAddr serverIp = server.getIp();
parik 0:37da71b87d96 290 int port = server.getPort();
parik 0:37da71b87d96 291
parik 0:37da71b87d96 292 pc.printf("Connecting... %d.%d.%d.%d:%d\r\n", serverIp[0],serverIp[1],serverIp[2],serverIp[3],port);
parik 0:37da71b87d96 293 TCPSocketErr bindErr = sock.connect(server);
parik 0:37da71b87d96 294 pc.printf("Connected\n");
parik 0:37da71b87d96 295 sock.setOnEvent(&onTCPSocketEvent);
parik 0:37da71b87d96 296
parik 0:37da71b87d96 297
parik 0:37da71b87d96 298 //Poll the networking stack
parik 0:37da71b87d96 299 while (true)
parik 0:37da71b87d96 300 {
parik 0:37da71b87d96 301 Net::poll();
parik 0:37da71b87d96 302
parik 0:37da71b87d96 303 }
parik 0:37da71b87d96 304
parik 0:37da71b87d96 305 }