Stream Ripper This program will download MP3 data from SHOUTcast stream and save mp3 file in microSD card. Metadata also will be saved as another file when stream includes metadata.

Dependencies:   EthernetNetIf mbed SDFileSystem

Committer:
xshige
Date:
Mon Sep 20 06:47:33 2010 +0000
Revision:
0:5490b791ee3d

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xshige 0:5490b791ee3d 1
xshige 0:5490b791ee3d 2 // Stream Ripper
xshige 0:5490b791ee3d 3 //
xshige 0:5490b791ee3d 4 // This program will download MP3 data from SHOUTcast stream
xshige 0:5490b791ee3d 5 // and save mp3 file in microSD card.
xshige 0:5490b791ee3d 6 // Metadata also will be saved as another file
xshige 0:5490b791ee3d 7 // when stream includes metadata.
xshige 0:5490b791ee3d 8 //
xshige 0:5490b791ee3d 9 // written by: xshige
xshige 0:5490b791ee3d 10
xshige 0:5490b791ee3d 11 // 2010/9/20 version 0.5
xshige 0:5490b791ee3d 12
xshige 0:5490b791ee3d 13 // Set Recording Size for Downloading
xshige 0:5490b791ee3d 14 // 1MB means around 1 minutes play (assume 128kbps)
xshige 0:5490b791ee3d 15 #define RECSIZE (15*1000000)
xshige 0:5490b791ee3d 16
xshige 0:5490b791ee3d 17 // define this if you want metadata stream
xshige 0:5490b791ee3d 18 #define METADATA
xshige 0:5490b791ee3d 19
xshige 0:5490b791ee3d 20 #include "mbed.h"
xshige 0:5490b791ee3d 21 #include "EthernetNetIf.h"
xshige 0:5490b791ee3d 22 #include "TCPSocket.h"
xshige 0:5490b791ee3d 23 #include "NTPClient.h"
xshige 0:5490b791ee3d 24
xshige 0:5490b791ee3d 25 // define this if you use DHCP
xshige 0:5490b791ee3d 26 #define DHCP
xshige 0:5490b791ee3d 27
xshige 0:5490b791ee3d 28 // define this if you use time&date as output file name
xshige 0:5490b791ee3d 29 #define TDFILE
xshige 0:5490b791ee3d 30
xshige 0:5490b791ee3d 31 #define WRTFILE
xshige 0:5490b791ee3d 32 #ifdef WRTFILE
xshige 0:5490b791ee3d 33 #include "SDFileSystem.h"
xshige 0:5490b791ee3d 34 SDFileSystem sd(p5, p6, p7, p8, "sd");
xshige 0:5490b791ee3d 35 #endif
xshige 0:5490b791ee3d 36
xshige 0:5490b791ee3d 37
xshige 0:5490b791ee3d 38 // maybe we need 4KB at least
xshige 0:5490b791ee3d 39 #define SBUFSIZE (1024*4)
xshige 0:5490b791ee3d 40 //#define SBUFSIZE (1024*8)
xshige 0:5490b791ee3d 41 //#define SBUFSIZE (1024*16) //NG
xshige 0:5490b791ee3d 42 //#define SBUFSIZE (1024*10) //NG
xshige 0:5490b791ee3d 43
xshige 0:5490b791ee3d 44 //#define TICK_DRIVEN
xshige 0:5490b791ee3d 45
xshige 0:5490b791ee3d 46 NTPClient ntp;
xshige 0:5490b791ee3d 47 time_t ctTime;
xshige 0:5490b791ee3d 48
xshige 0:5490b791ee3d 49 /*
xshige 0:5490b791ee3d 50 ----------------
xshige 0:5490b791ee3d 51
xshige 0:5490b791ee3d 52 Message Smaples
xshige 0:5490b791ee3d 53
xshige 0:5490b791ee3d 54 */
xshige 0:5490b791ee3d 55
xshige 0:5490b791ee3d 56 // Client Side:
xshige 0:5490b791ee3d 57
xshige 0:5490b791ee3d 58 // GET /live HTTP/1.0
xshige 0:5490b791ee3d 59 // Host: gw
xshige 0:5490b791ee3d 60 // Accept: */*
xshige 0:5490b791ee3d 61 // User-Agent: mbed
xshige 0:5490b791ee3d 62 // Icy-MetaData: 1
xshige 0:5490b791ee3d 63 // Connection: close
xshige 0:5490b791ee3d 64
xshige 0:5490b791ee3d 65
xshige 0:5490b791ee3d 66 /*
xshige 0:5490b791ee3d 67
xshige 0:5490b791ee3d 68 Server#0 Resopose:
xshige 0:5490b791ee3d 69
xshige 0:5490b791ee3d 70 HTTP/1.0 200 OK
xshige 0:5490b791ee3d 71 Content-Type: audio/mpeg
xshige 0:5490b791ee3d 72 icy-br:96
xshige 0:5490b791ee3d 73 ice-audio-info: ice-samplerate=44100;ice-bitrate=96;ice-channels=2
xshige 0:5490b791ee3d 74 icy-br:96
xshige 0:5490b791ee3d 75 icy-description:www.SoloPianoRadio.com
xshige 0:5490b791ee3d 76 icy-genre:Classical
xshige 0:5490b791ee3d 77 icy-name:Whisperings: Solo Piano Radio
xshige 0:5490b791ee3d 78 icy-pub:1
xshige 0:5490b791ee3d 79 icy-url:http://www.solopianoradio.com
xshige 0:5490b791ee3d 80 Server: Icecast 2.3.1
xshige 0:5490b791ee3d 81 icy-metaint:16000
xshige 0:5490b791ee3d 82
xshige 0:5490b791ee3d 83
xshige 0:5490b791ee3d 84 Server#1 Resopose:
xshige 0:5490b791ee3d 85
xshige 0:5490b791ee3d 86 ICY 200 OK
xshige 0:5490b791ee3d 87 icy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR>
xshige 0:5490b791ee3d 88 icy-notice2:SHOUTcast Distributed Network Audio Server/Linux v1.9.8<BR>
xshige 0:5490b791ee3d 89 icy-name:SMOOTHJAZZ.COM - The Internet's Original Smooth Jazz Radio Station - Live from the Monterey Bay
xshige 0:5490b791ee3d 90 icy-genre:Smooth Jazz
xshige 0:5490b791ee3d 91 icy-url:http://www.smoothjazz.com
xshige 0:5490b791ee3d 92 content-type:audio/mpeg
xshige 0:5490b791ee3d 93 icy-pub:1
xshige 0:5490b791ee3d 94 icy-metaint:32768
xshige 0:5490b791ee3d 95 icy-br:128
xshige 0:5490b791ee3d 96
xshige 0:5490b791ee3d 97 ------------------------
xshige 0:5490b791ee3d 98 Notes:
xshige 0:5490b791ee3d 99
xshige 0:5490b791ee3d 100 * icy-metadata:1
xshige 0:5490b791ee3d 101 a client can request to have metadata
xshige 0:5490b791ee3d 102 (information about the music - ) included in the stream,
xshige 0:5490b791ee3d 103 by adding this.
xshige 0:5490b791ee3d 104
xshige 0:5490b791ee3d 105 * ICY [CODE]
xshige 0:5490b791ee3d 106 whereas code refers to http status code
xshige 0:5490b791ee3d 107 (200 - ok, 404 - resource not found, 401 - service unavailable, etc.).
xshige 0:5490b791ee3d 108
xshige 0:5490b791ee3d 109 * icy-pub
xshige 0:5490b791ee3d 110 - Not sure, believe it indicates if the stream is public or private
xshige 0:5490b791ee3d 111
xshige 0:5490b791ee3d 112 * icy-metaint
xshige 0:5490b791ee3d 113 - an interval (in bytes) that specifies how often metadata updates
xshige 0:5490b791ee3d 114 will be sent to the client.
xshige 0:5490b791ee3d 115
xshige 0:5490b791ee3d 116 * icy-br
xshige 0:5490b791ee3d 117 - BitRate, seems mostly informational as most clients
xshige 0:5490b791ee3d 118 encountered seem to support VBR (Variable BitRate).
xshige 0:5490b791ee3d 119
xshige 0:5490b791ee3d 120 -------------------------
xshige 0:5490b791ee3d 121 */
xshige 0:5490b791ee3d 122
xshige 0:5490b791ee3d 123 #ifdef DHCP
xshige 0:5490b791ee3d 124 EthernetNetIf eth;
xshige 0:5490b791ee3d 125 #else
xshige 0:5490b791ee3d 126 EthernetNetIf eth(
xshige 0:5490b791ee3d 127 IpAddr(192,168,0,25), //IP Address
xshige 0:5490b791ee3d 128 IpAddr(255,255,255,0), //Network Mask
xshige 0:5490b791ee3d 129 IpAddr(192,168,0,1), //Gateway
xshige 0:5490b791ee3d 130 IpAddr(192,168,0,1) //DNS
xshige 0:5490b791ee3d 131 );
xshige 0:5490b791ee3d 132 #endif
xshige 0:5490b791ee3d 133
xshige 0:5490b791ee3d 134 DigitalOut led1(LED1, "led1");
xshige 0:5490b791ee3d 135 DigitalOut led2(LED2, "led2");
xshige 0:5490b791ee3d 136 DigitalOut led3(LED3, "led3");
xshige 0:5490b791ee3d 137 DigitalOut led4(LED4, "led4");
xshige 0:5490b791ee3d 138
xshige 0:5490b791ee3d 139 TCPSocket sock;
xshige 0:5490b791ee3d 140 char inbuf[2048]; // IP input buffer
xshige 0:5490b791ee3d 141 char* cp;
xshige 0:5490b791ee3d 142
xshige 0:5490b791ee3d 143 // stream
xshige 0:5490b791ee3d 144 int slen; // stream length
xshige 0:5490b791ee3d 145 unsigned long int tlen=0; // total lenth of downloaded file
xshige 0:5490b791ee3d 146
xshige 0:5490b791ee3d 147
xshige 0:5490b791ee3d 148 //-------------------------------------------------
xshige 0:5490b791ee3d 149
xshige 0:5490b791ee3d 150 class RingBuffer
xshige 0:5490b791ee3d 151 {
xshige 0:5490b791ee3d 152 protected:
xshige 0:5490b791ee3d 153 unsigned char *buffer;
xshige 0:5490b791ee3d 154 int buffersize;
xshige 0:5490b791ee3d 155 int rp; // read index
xshige 0:5490b791ee3d 156 int wp; // write index
xshige 0:5490b791ee3d 157
xshige 0:5490b791ee3d 158 public:
xshige 0:5490b791ee3d 159 RingBuffer(int bufsiz)
xshige 0:5490b791ee3d 160 {
xshige 0:5490b791ee3d 161 buffersize = bufsiz;
xshige 0:5490b791ee3d 162
xshige 0:5490b791ee3d 163 buffer = new unsigned char[buffersize];
xshige 0:5490b791ee3d 164 // memset(buffer, 0, sizeof(char) * buffersize);
xshige 0:5490b791ee3d 165
xshige 0:5490b791ee3d 166 // reset pointer to make empty
xshige 0:5490b791ee3d 167 rp = 0;
xshige 0:5490b791ee3d 168 wp = 0;
xshige 0:5490b791ee3d 169 };
xshige 0:5490b791ee3d 170
xshige 0:5490b791ee3d 171 ~RingBuffer(void)
xshige 0:5490b791ee3d 172 {
xshige 0:5490b791ee3d 173 delete[] buffer;
xshige 0:5490b791ee3d 174 };
xshige 0:5490b791ee3d 175
xshige 0:5490b791ee3d 176 int GetByte(unsigned char *cp);
xshige 0:5490b791ee3d 177 int PutByte(unsigned char c);
xshige 0:5490b791ee3d 178 int IsEmpty(void);
xshige 0:5490b791ee3d 179 };
xshige 0:5490b791ee3d 180
xshige 0:5490b791ee3d 181
xshige 0:5490b791ee3d 182 int RingBuffer::GetByte(unsigned char *cp )
xshige 0:5490b791ee3d 183 {
xshige 0:5490b791ee3d 184 if( rp != wp ) { // not empty
xshige 0:5490b791ee3d 185 *cp = buffer[rp];
xshige 0:5490b791ee3d 186 rp = (rp + 1) % buffersize;
xshige 0:5490b791ee3d 187 return 0;
xshige 0:5490b791ee3d 188 } else { // empty
xshige 0:5490b791ee3d 189 return -1;
xshige 0:5490b791ee3d 190 }
xshige 0:5490b791ee3d 191 }
xshige 0:5490b791ee3d 192
xshige 0:5490b791ee3d 193
xshige 0:5490b791ee3d 194 int RingBuffer::PutByte(unsigned char c )
xshige 0:5490b791ee3d 195 {
xshige 0:5490b791ee3d 196 int next = (wp + 1) % buffersize;
xshige 0:5490b791ee3d 197 if( next == rp ) {
xshige 0:5490b791ee3d 198 printf("*** Buffer Full ***\r\n" );
xshige 0:5490b791ee3d 199 // printf("*");//debug
xshige 0:5490b791ee3d 200 return -1;
xshige 0:5490b791ee3d 201 }
xshige 0:5490b791ee3d 202 buffer[wp] = c;
xshige 0:5490b791ee3d 203 wp = next;
xshige 0:5490b791ee3d 204 return 0;
xshige 0:5490b791ee3d 205 }
xshige 0:5490b791ee3d 206
xshige 0:5490b791ee3d 207
xshige 0:5490b791ee3d 208 int RingBuffer::IsEmpty(void)
xshige 0:5490b791ee3d 209 {
xshige 0:5490b791ee3d 210 return (rp==wp)?(true):(false);
xshige 0:5490b791ee3d 211 }
xshige 0:5490b791ee3d 212
xshige 0:5490b791ee3d 213 //-----------------
xshige 0:5490b791ee3d 214
xshige 0:5490b791ee3d 215
xshige 0:5490b791ee3d 216 // create RingBuffer
xshige 0:5490b791ee3d 217 RingBuffer sbuf(SBUFSIZE); //
xshige 0:5490b791ee3d 218
xshige 0:5490b791ee3d 219
xshige 0:5490b791ee3d 220 char sResponse[800]; // keeps Stream Response
xshige 0:5490b791ee3d 221 char sMetadata[200]; // keeps Stream Metadata
xshige 0:5490b791ee3d 222 char sPrevMetadata[200]; // keeps Previous Stream Metadata
xshige 0:5490b791ee3d 223
xshige 0:5490b791ee3d 224 // client state
xshige 0:5490b791ee3d 225 enum wSTATE{NOP,PUT_HEADER} WriteState;
xshige 0:5490b791ee3d 226 enum rSTATE{GET_RESPONSE,GET_STREAM} ReadState;
xshige 0:5490b791ee3d 227
xshige 0:5490b791ee3d 228 // metadata
xshige 0:5490b791ee3d 229 char mbuf[512];
xshige 0:5490b791ee3d 230 int mbyte; // lenth byte, -1 means this value is not effective
xshige 0:5490b791ee3d 231 int mlen; // metadata length
xshige 0:5490b791ee3d 232 int metaint=0; // metadate interval
xshige 0:5490b791ee3d 233
xshige 0:5490b791ee3d 234 void initDec(void); // prototype
xshige 0:5490b791ee3d 235
xshige 0:5490b791ee3d 236
xshige 0:5490b791ee3d 237 void onTCPSocketEvent(TCPSocketEvent e) {
xshige 0:5490b791ee3d 238 int i,len;
xshige 0:5490b791ee3d 239 switch (e) {
xshige 0:5490b791ee3d 240 case TCPSOCKET_CONNECTED:
xshige 0:5490b791ee3d 241 printf("TCP Socket Connected\r\n"); // this printf disturb socket work correctly
xshige 0:5490b791ee3d 242 // break; // we must comment out ?
xshige 0:5490b791ee3d 243 case TCPSOCKET_WRITEABLE:
xshige 0:5490b791ee3d 244 //Can now write some data...
xshige 0:5490b791ee3d 245 // printf("TCP Socket Writable\r\n"); // debug
xshige 0:5490b791ee3d 246 switch(WriteState) {
xshige 0:5490b791ee3d 247 case PUT_HEADER:
xshige 0:5490b791ee3d 248 const char* str =
xshige 0:5490b791ee3d 249 // "GET /live HTTP/1.0\r\n" // use this if solopiano
xshige 0:5490b791ee3d 250 "GET / HTTP/1.0\r\n"
xshige 0:5490b791ee3d 251 "Host: gw\r\n"
xshige 0:5490b791ee3d 252 "Accept: */*\r\n"
xshige 0:5490b791ee3d 253 "User-Agent: mbed\r\n"
xshige 0:5490b791ee3d 254 #ifdef METADATA
xshige 0:5490b791ee3d 255 "Icy-MetaData: 1\r\n" // send this if you want Metadata
xshige 0:5490b791ee3d 256 #endif
xshige 0:5490b791ee3d 257 // "Connection: close\r\n"
xshige 0:5490b791ee3d 258 "\r\n"
xshige 0:5490b791ee3d 259 ;
xshige 0:5490b791ee3d 260 sock.send(str, strlen(str));
xshige 0:5490b791ee3d 261 printf("\r\nHEADER:\r\n%s\r\n", str); // display PUT_HEADER
xshige 0:5490b791ee3d 262 WriteState=NOP;
xshige 0:5490b791ee3d 263 ReadState=GET_RESPONSE;
xshige 0:5490b791ee3d 264 break;
xshige 0:5490b791ee3d 265 case NOP:
xshige 0:5490b791ee3d 266 break;
xshige 0:5490b791ee3d 267 } // switch(WriteState)
xshige 0:5490b791ee3d 268 break;
xshige 0:5490b791ee3d 269 case TCPSOCKET_READABLE:
xshige 0:5490b791ee3d 270 //Can now read some data...
xshige 0:5490b791ee3d 271 // printf("TCP Socket Readable\r\n"); // debug
xshige 0:5490b791ee3d 272 switch(ReadState) {
xshige 0:5490b791ee3d 273 case GET_RESPONSE:
xshige 0:5490b791ee3d 274 len=sock.recv(inbuf, sizeof inbuf);
xshige 0:5490b791ee3d 275 cp=strstr(inbuf,"\r\n\r\n");
xshige 0:5490b791ee3d 276 if (cp==NULL) {
xshige 0:5490b791ee3d 277 inbuf[len]=0;
xshige 0:5490b791ee3d 278 // printf("%s",inbuf); // debug
xshige 0:5490b791ee3d 279 sprintf(sResponse,"%s",inbuf);
xshige 0:5490b791ee3d 280 return; // still read response again
xshige 0:5490b791ee3d 281 }
xshige 0:5490b791ee3d 282 //
xshige 0:5490b791ee3d 283 *cp=0;
xshige 0:5490b791ee3d 284 sprintf(sResponse+strlen(sResponse),"%s\r\n\r\n",inbuf);
xshige 0:5490b791ee3d 285 printf("RESPONSE:\r\n%s",sResponse);
xshige 0:5490b791ee3d 286 // get metaint value
xshige 0:5490b791ee3d 287 cp=strstr(sResponse,"icy-metaint:");
xshige 0:5490b791ee3d 288 if (cp==NULL) metaint=0; else sscanf(cp+strlen("icy-metaint:"),"%d",&metaint);
xshige 0:5490b791ee3d 289 printf("\r\nmetaint: %d\r\n\r\n",metaint); //debug
xshige 0:5490b791ee3d 290 //
xshige 0:5490b791ee3d 291 i=strlen(inbuf)+4; // bump bitstream right after response
xshige 0:5490b791ee3d 292 ReadState=GET_STREAM;
xshige 0:5490b791ee3d 293 initDec();
xshige 0:5490b791ee3d 294 //
xshige 0:5490b791ee3d 295 while(i<len) {
xshige 0:5490b791ee3d 296 // write one bye
xshige 0:5490b791ee3d 297 sbuf.PutByte(inbuf[i]);i++;
xshige 0:5490b791ee3d 298 };
xshige 0:5490b791ee3d 299 return;
xshige 0:5490b791ee3d 300 break;
xshige 0:5490b791ee3d 301 //
xshige 0:5490b791ee3d 302 case GET_STREAM:
xshige 0:5490b791ee3d 303 // receive data ****repeatedly****
xshige 0:5490b791ee3d 304 while(len=sock.recv(inbuf, sizeof inbuf)) {
xshige 0:5490b791ee3d 305 i=0;
xshige 0:5490b791ee3d 306 // save len bytes
xshige 0:5490b791ee3d 307 while (i<len) {
xshige 0:5490b791ee3d 308 sbuf.PutByte(inbuf[i]);i++;
xshige 0:5490b791ee3d 309 }
xshige 0:5490b791ee3d 310 } // while (len=sock...)
xshige 0:5490b791ee3d 311 return; // get more stream
xshige 0:5490b791ee3d 312 break;
xshige 0:5490b791ee3d 313 //
xshige 0:5490b791ee3d 314 } // switch (ReadState)
xshige 0:5490b791ee3d 315 break;//
xshige 0:5490b791ee3d 316 case TCPSOCKET_CONTIMEOUT:
xshige 0:5490b791ee3d 317 printf("TCP Socket Timeout\r\n");
xshige 0:5490b791ee3d 318 break;
xshige 0:5490b791ee3d 319 case TCPSOCKET_CONRST:
xshige 0:5490b791ee3d 320 printf("TCP Socket CONRST\r\n");
xshige 0:5490b791ee3d 321 break;
xshige 0:5490b791ee3d 322 case TCPSOCKET_CONABRT:
xshige 0:5490b791ee3d 323 printf("TCP Socket CONABRT\r\n");
xshige 0:5490b791ee3d 324 printf("Maybe Server Down...\r\n");
xshige 0:5490b791ee3d 325 break;
xshige 0:5490b791ee3d 326 case TCPSOCKET_ERROR:
xshige 0:5490b791ee3d 327 printf("TCP Socket Error\r\n");
xshige 0:5490b791ee3d 328 break;
xshige 0:5490b791ee3d 329 case TCPSOCKET_DISCONNECTED:
xshige 0:5490b791ee3d 330 //Close socket...
xshige 0:5490b791ee3d 331 printf("TCP Socket Disconnected\r\n");
xshige 0:5490b791ee3d 332 sock.close();
xshige 0:5490b791ee3d 333 break;
xshige 0:5490b791ee3d 334 }// switch(e)
xshige 0:5490b791ee3d 335 }
xshige 0:5490b791ee3d 336
xshige 0:5490b791ee3d 337
xshige 0:5490b791ee3d 338 //--------------------------------
xshige 0:5490b791ee3d 339
xshige 0:5490b791ee3d 340
xshige 0:5490b791ee3d 341 #ifdef WRTFILE
xshige 0:5490b791ee3d 342 FILE *fp, *fp2;
xshige 0:5490b791ee3d 343 char outfile1[32];
xshige 0:5490b791ee3d 344 char outfile2[32];
xshige 0:5490b791ee3d 345 #endif
xshige 0:5490b791ee3d 346
xshige 0:5490b791ee3d 347 void initDec(void) {
xshige 0:5490b791ee3d 348 slen=0;mbyte=-1;mlen=0;
xshige 0:5490b791ee3d 349 #ifdef WRTFILE
xshige 0:5490b791ee3d 350 #ifdef TDFILE
xshige 0:5490b791ee3d 351 // char outfile[32];
xshige 0:5490b791ee3d 352 // make output file for MP3
xshige 0:5490b791ee3d 353 ctTime=time(NULL);
xshige 0:5490b791ee3d 354 struct tm *t=localtime(&ctTime);
xshige 0:5490b791ee3d 355 sprintf(outfile1,"/sd/%02d%02d%02d%02d.mp3",
xshige 0:5490b791ee3d 356 // t->tm_year+1900,
xshige 0:5490b791ee3d 357 t->tm_mon+1,
xshige 0:5490b791ee3d 358 t->tm_mday,
xshige 0:5490b791ee3d 359 t->tm_hour,
xshige 0:5490b791ee3d 360 t->tm_min);
xshige 0:5490b791ee3d 361 // printf("%s\r\n",outfile); //debug
xshige 0:5490b791ee3d 362 fp = fopen(outfile1, "wb");
xshige 0:5490b791ee3d 363 #else
xshige 0:5490b791ee3d 364 fp = fopen("/sd/stream.mp3", "wb");
xshige 0:5490b791ee3d 365 #endif
xshige 0:5490b791ee3d 366 if(fp == NULL) {
xshige 0:5490b791ee3d 367 error("Could not open file for download\n");
xshige 0:5490b791ee3d 368 }
xshige 0:5490b791ee3d 369 #ifdef METADATA
xshige 0:5490b791ee3d 370 #ifdef TDFILE
xshige 0:5490b791ee3d 371 // make output file for Metadata
xshige 0:5490b791ee3d 372 sprintf(outfile2,"/sd/%02d%02d%02d%02d.met",
xshige 0:5490b791ee3d 373 // t->tm_year+1900,
xshige 0:5490b791ee3d 374 t->tm_mon+1,
xshige 0:5490b791ee3d 375 t->tm_mday,
xshige 0:5490b791ee3d 376 t->tm_hour,
xshige 0:5490b791ee3d 377 t->tm_min);
xshige 0:5490b791ee3d 378 // printf("%s\r\n",outfile); //debug
xshige 0:5490b791ee3d 379 fp2 = fopen(outfile2, "w");
xshige 0:5490b791ee3d 380 #else
xshige 0:5490b791ee3d 381 fp2 = fopen("/sd/stream.met", "w");
xshige 0:5490b791ee3d 382 #endif
xshige 0:5490b791ee3d 383 if(fp2 == NULL) {
xshige 0:5490b791ee3d 384 error("Could not open file for metadata\n");
xshige 0:5490b791ee3d 385 }
xshige 0:5490b791ee3d 386 ctTime=time(NULL); // get seconds
xshige 0:5490b791ee3d 387 fprintf(fp2,"%s\n%s\n---------------\n",
xshige 0:5490b791ee3d 388 sResponse,ctime(&ctTime)); // write stream information on file
xshige 0:5490b791ee3d 389 #endif
xshige 0:5490b791ee3d 390 // display time&date
xshige 0:5490b791ee3d 391 ctTime = time(NULL); // get seconds
xshige 0:5490b791ee3d 392 printf("%s\r\n", ctime(&ctTime));
xshige 0:5490b791ee3d 393 //
xshige 0:5490b791ee3d 394 float edt=(RECSIZE)/1000000;
xshige 0:5490b791ee3d 395 if (metaint==0) {
xshige 0:5490b791ee3d 396 printf("Now Downloading(Metadata-less Stream)...\r\n");
xshige 0:5490b791ee3d 397 printf("Estimated Donwload Time: %3.2f minutes\r\n\r\n",edt);
xshige 0:5490b791ee3d 398 } else {
xshige 0:5490b791ee3d 399 printf("Now Downloading(Stream with Metadata)...\r\n");
xshige 0:5490b791ee3d 400 printf("Estimated Donwload Time: %3.2f minutes\r\n\r\n",edt);
xshige 0:5490b791ee3d 401 }
xshige 0:5490b791ee3d 402 #endif
xshige 0:5490b791ee3d 403 return;
xshige 0:5490b791ee3d 404 }
xshige 0:5490b791ee3d 405
xshige 0:5490b791ee3d 406 void sendDec(unsigned char sbyte) {
xshige 0:5490b791ee3d 407 unsigned char wc=sbyte;
xshige 0:5490b791ee3d 408 if (metaint==0) {
xshige 0:5490b791ee3d 409 // we have no metadata in a stream
xshige 0:5490b791ee3d 410 // put one byte to decoder
xshige 0:5490b791ee3d 411 #ifdef WRTFILE
xshige 0:5490b791ee3d 412 fwrite(&wc,1,1,fp);
xshige 0:5490b791ee3d 413 // fputc(sbyte,fp); /////
xshige 0:5490b791ee3d 414 tlen++;
xshige 0:5490b791ee3d 415 if (tlen==RECSIZE) {
xshige 0:5490b791ee3d 416 fclose(fp);
xshige 0:5490b791ee3d 417 printf("\r\n*** Download Complete.***\r\n");
xshige 0:5490b791ee3d 418 while(true); // dynamic stop
xshige 0:5490b791ee3d 419 }
xshige 0:5490b791ee3d 420 #endif
xshige 0:5490b791ee3d 421 return;
xshige 0:5490b791ee3d 422 }
xshige 0:5490b791ee3d 423 //
xshige 0:5490b791ee3d 424 if (slen==metaint) {
xshige 0:5490b791ee3d 425 mbyte=sbyte;
xshige 0:5490b791ee3d 426 mlen=0;
xshige 0:5490b791ee3d 427 slen++;
xshige 0:5490b791ee3d 428 return;
xshige 0:5490b791ee3d 429 }
xshige 0:5490b791ee3d 430 //
xshige 0:5490b791ee3d 431 if (mbyte==-1) {
xshige 0:5490b791ee3d 432 // put one byte to decoder
xshige 0:5490b791ee3d 433 #ifdef WRTFILE
xshige 0:5490b791ee3d 434 fwrite(&wc,1,1,fp);
xshige 0:5490b791ee3d 435 // fputc(sbyte,fp); /////
xshige 0:5490b791ee3d 436 #endif
xshige 0:5490b791ee3d 437 #if 1
xshige 0:5490b791ee3d 438 if (0!=strcmp(sMetadata,sPrevMetadata)) {
xshige 0:5490b791ee3d 439 printf("Metadata: %s\r\n",sMetadata); // display metadata
xshige 0:5490b791ee3d 440 // printf("mbyte:%d slen:%d tlen:%d\r\n\r\n",mbyte,slen,tlen); // debug
xshige 0:5490b791ee3d 441 printf("tlen:%d\r\n\r\n",tlen); // display total length
xshige 0:5490b791ee3d 442 sprintf(sPrevMetadata,"%s",sMetadata); // copy to previous
xshige 0:5490b791ee3d 443 ///// fclose(fp);fp=fopen(outfile1,"ab"); // switch append mode
xshige 0:5490b791ee3d 444 ///// fclose(fp2);fp2=fopen(outfile2,"a");
xshige 0:5490b791ee3d 445 fprintf(fp2,"%d\n%s\n",tlen,sMetadata); // save metadata on TXT file
xshige 0:5490b791ee3d 446
xshige 0:5490b791ee3d 447 }
xshige 0:5490b791ee3d 448 #endif
xshige 0:5490b791ee3d 449 slen++;
xshige 0:5490b791ee3d 450 tlen++;
xshige 0:5490b791ee3d 451 return;
xshige 0:5490b791ee3d 452 }
xshige 0:5490b791ee3d 453 //
xshige 0:5490b791ee3d 454 // comming here when we are in reading metadata
xshige 0:5490b791ee3d 455 if (slen==(metaint+16*mbyte+1)) {
xshige 0:5490b791ee3d 456 // we have all bytes for metadata
xshige 0:5490b791ee3d 457 mbuf[mlen]=0; // make terminator
xshige 0:5490b791ee3d 458 if (0<mbyte) {
xshige 0:5490b791ee3d 459 sprintf(sMetadata,"%s",mbuf); // coy new metadata
xshige 0:5490b791ee3d 460 }
xshige 0:5490b791ee3d 461 #ifdef WRTFILE
xshige 0:5490b791ee3d 462 fwrite(&wc,1,1,fp);
xshige 0:5490b791ee3d 463 // fputc(sbyte,fp); ////
xshige 0:5490b791ee3d 464 tlen++;
xshige 0:5490b791ee3d 465 if (tlen>RECSIZE) {
xshige 0:5490b791ee3d 466 printf("\r\n*** Download Complete.***\r\n");
xshige 0:5490b791ee3d 467 fclose(fp);fclose(fp2);
xshige 0:5490b791ee3d 468 // display time&date
xshige 0:5490b791ee3d 469 ctTime = time(NULL); // get seconds in UTC
xshige 0:5490b791ee3d 470 printf("%s\r\n", ctime(&ctTime));
xshige 0:5490b791ee3d 471 while(true); // dynamic stop
xshige 0:5490b791ee3d 472 }
xshige 0:5490b791ee3d 473 #endif
xshige 0:5490b791ee3d 474 // printf("metaint: %d slen:%d\r\n",metaint,slen); //debug
xshige 0:5490b791ee3d 475 mbyte=-1;mlen=0;
xshige 0:5490b791ee3d 476 slen=1; //OK
xshige 0:5490b791ee3d 477 return;
xshige 0:5490b791ee3d 478 } // if (slen==(metaint+16*mbyte+1))
xshige 0:5490b791ee3d 479 //
xshige 0:5490b791ee3d 480 // coming here still reading metadata
xshige 0:5490b791ee3d 481 // we still read one byte of metadata
xshige 0:5490b791ee3d 482 mbuf[mlen]=sbyte;mlen++; slen++;
xshige 0:5490b791ee3d 483 return;
xshige 0:5490b791ee3d 484 }
xshige 0:5490b791ee3d 485
xshige 0:5490b791ee3d 486
xshige 0:5490b791ee3d 487 #ifdef TICK_DRIVEN
xshige 0:5490b791ee3d 488 void TickProcess(void) {
xshige 0:5490b791ee3d 489 int x;
xshige 0:5490b791ee3d 490 for(x=0;x<(SBUFSIEZ/2);x++) {
xshige 0:5490b791ee3d 491 unsigned char sbyte;
xshige 0:5490b791ee3d 492 if (-1==sbuf.GetByte(&sbyte)) {
xshige 0:5490b791ee3d 493 // Net::poll();
xshige 0:5490b791ee3d 494 return;
xshige 0:5490b791ee3d 495 }
xshige 0:5490b791ee3d 496 sendDec(sbyte);
xshige 0:5490b791ee3d 497 }
xshige 0:5490b791ee3d 498 return;
xshige 0:5490b791ee3d 499 }
xshige 0:5490b791ee3d 500
xshige 0:5490b791ee3d 501 //-----------------------
xshige 0:5490b791ee3d 502
xshige 0:5490b791ee3d 503 Ticker tick;
xshige 0:5490b791ee3d 504 #endif
xshige 0:5490b791ee3d 505
xshige 0:5490b791ee3d 506 int main() {
xshige 0:5490b791ee3d 507
xshige 0:5490b791ee3d 508 // set_time();
xshige 0:5490b791ee3d 509
xshige 0:5490b791ee3d 510 // make debug port Fast
xshige 0:5490b791ee3d 511 Serial pc(USBTX, USBRX);
xshige 0:5490b791ee3d 512 // pc.baud(9600);
xshige 0:5490b791ee3d 513 pc.baud(115200);
xshige 0:5490b791ee3d 514 // pc.baud(230400);
xshige 0:5490b791ee3d 515
xshige 0:5490b791ee3d 516 // init string
xshige 0:5490b791ee3d 517 sprintf(sResponse,"");
xshige 0:5490b791ee3d 518
xshige 0:5490b791ee3d 519 // init medatadata string
xshige 0:5490b791ee3d 520 sprintf(sMetadata,"StreamTitle='Currently, Unknown';");
xshige 0:5490b791ee3d 521 sprintf(sPrevMetadata,"");
xshige 0:5490b791ee3d 522
xshige 0:5490b791ee3d 523
xshige 0:5490b791ee3d 524
xshige 0:5490b791ee3d 525 printf("\r\n");
xshige 0:5490b791ee3d 526 printf("Setting up...\r\n");
xshige 0:5490b791ee3d 527
xshige 0:5490b791ee3d 528 EthernetErr ethErr = eth.setup();
xshige 0:5490b791ee3d 529 if (ethErr) {
xshige 0:5490b791ee3d 530 printf("Error %d in setup.\r\n", ethErr);
xshige 0:5490b791ee3d 531 return -1;
xshige 0:5490b791ee3d 532 };
xshige 0:5490b791ee3d 533
xshige 0:5490b791ee3d 534 // Init State for Read/Write
xshige 0:5490b791ee3d 535 ReadState=GET_RESPONSE;
xshige 0:5490b791ee3d 536 WriteState=PUT_HEADER;
xshige 0:5490b791ee3d 537
xshige 0:5490b791ee3d 538
xshige 0:5490b791ee3d 539 //----------------------------------
xshige 0:5490b791ee3d 540 // setup clock for time stamp
xshige 0:5490b791ee3d 541 // NTPClient ntp;
xshige 0:5490b791ee3d 542 // time_t ctTime;
xshige 0:5490b791ee3d 543
xshige 0:5490b791ee3d 544 Host timeServer(IpAddr(), 123, "0.uk.pool.ntp.org");
xshige 0:5490b791ee3d 545 ntp.setTime(timeServer);
xshige 0:5490b791ee3d 546
xshige 0:5490b791ee3d 547 ctTime = time(NULL); // get seconds in UTC
xshige 0:5490b791ee3d 548 ctTime = ctTime+(3600*9); // convert JST (please change to fit your localtime)
xshige 0:5490b791ee3d 549 set_time(ctTime); // re-setup RTC
xshige 0:5490b791ee3d 550 printf("\r\nTime is setup now (JST): %s\r\n", ctime(&ctTime));
xshige 0:5490b791ee3d 551
xshige 0:5490b791ee3d 552 #if 0
xshige 0:5490b791ee3d 553 // test program for time
xshige 0:5490b791ee3d 554 ctTime=time(NULL);
xshige 0:5490b791ee3d 555 struct tm *t=localtime(&ctTime);
xshige 0:5490b791ee3d 556 printf("%4d %02d/%02d %02d:%02d:%02d\r\n\r\n",
xshige 0:5490b791ee3d 557 t->tm_year+1900,
xshige 0:5490b791ee3d 558 t->tm_mon+1,
xshige 0:5490b791ee3d 559 t->tm_mday,
xshige 0:5490b791ee3d 560 t->tm_hour,
xshige 0:5490b791ee3d 561 t->tm_min,
xshige 0:5490b791ee3d 562 t->tm_sec);
xshige 0:5490b791ee3d 563 #endif
xshige 0:5490b791ee3d 564
xshige 0:5490b791ee3d 565 //-----------------------------
xshige 0:5490b791ee3d 566
xshige 0:5490b791ee3d 567 printf("Setup OK\r\n");
xshige 0:5490b791ee3d 568
xshige 0:5490b791ee3d 569
xshige 0:5490b791ee3d 570 // ************** STATION DEFINITIONS **************
xshige 0:5490b791ee3d 571
xshige 0:5490b791ee3d 572 //// http://pianosolo.streamguys.net:80/live
xshige 0:5490b791ee3d 573 //Host server(IpAddr(216,246,105,11), 80); //solo piano
xshige 0:5490b791ee3d 574 //Host server(IpAddr(), 80,"pianosolo.streamguys.net"); //solo piano
xshige 0:5490b791ee3d 575
xshige 0:5490b791ee3d 576 // SMOOTHJAZZ.COM - The Internet's Original Smooth Jazz Radio Station
xshige 0:5490b791ee3d 577 // - Live from the Monterey Bay
xshige 0:5490b791ee3d 578 // Host server(IpAddr(67,213,217,212), 80); //smooth jazz
xshige 0:5490b791ee3d 579
xshige 0:5490b791ee3d 580 //Folk Alley (( All Folk. All The Time. ))
xshige 0:5490b791ee3d 581 // http://66.225.205.8:8000
xshige 0:5490b791ee3d 582 Host server(IpAddr(66,225,205,8), 8000);
xshige 0:5490b791ee3d 583
xshige 0:5490b791ee3d 584 // 1-ONE NATION FM.COM GOSPEL RADIO
xshige 0:5490b791ee3d 585 // http://208.85.240.2:8094
xshige 0:5490b791ee3d 586 // Host server(IpAddr(208,85,240,2), 8094);
xshige 0:5490b791ee3d 587
xshige 0:5490b791ee3d 588
xshige 0:5490b791ee3d 589 // GotRadio - Celti
xshige 0:5490b791ee3d 590 //http://64.62.164.211:3000
xshige 0:5490b791ee3d 591 // Host server(IpAddr(64,62,164,211), 3000);
xshige 0:5490b791ee3d 592
xshige 0:5490b791ee3d 593 // AnimeNfo Radio | Serving you the best Anime music!
xshige 0:5490b791ee3d 594 //http://216.18.227.252:8000
xshige 0:5490b791ee3d 595 // Host server(IpAddr(216,18,227,252), 8000);
xshige 0:5490b791ee3d 596
xshige 0:5490b791ee3d 597 // ************** end of STATION DEFINITIONS **************
xshige 0:5490b791ee3d 598
xshige 0:5490b791ee3d 599 // display IP address and port# of server
xshige 0:5490b791ee3d 600 IpAddr serverIp = server.getIp();
xshige 0:5490b791ee3d 601 int port = server.getPort();
xshige 0:5490b791ee3d 602 printf("Connecting... %d.%d.%d.%d:%d\r\n",
xshige 0:5490b791ee3d 603 serverIp[0],serverIp[1],serverIp[2],serverIp[3],port);
xshige 0:5490b791ee3d 604
xshige 0:5490b791ee3d 605
xshige 0:5490b791ee3d 606 TCPSocketErr bindErr = sock.connect(server);
xshige 0:5490b791ee3d 607
xshige 0:5490b791ee3d 608 sock.setOnEvent(&onTCPSocketEvent);
xshige 0:5490b791ee3d 609
xshige 0:5490b791ee3d 610 Timer tmr;
xshige 0:5490b791ee3d 611 tmr.start();
xshige 0:5490b791ee3d 612
xshige 0:5490b791ee3d 613 #ifdef TICK_DRIVEN
xshige 0:5490b791ee3d 614 tick.attach(&TickProcess,0.1); // 100ms tick, this interval depens on SBUFSIZE
xshige 0:5490b791ee3d 615 #endif
xshige 0:5490b791ee3d 616
xshige 0:5490b791ee3d 617 while (true) {
xshige 0:5490b791ee3d 618 Net::poll();
xshige 0:5490b791ee3d 619
xshige 0:5490b791ee3d 620 #ifndef TICK_DRIVEN
xshige 0:5490b791ee3d 621 int x;
xshige 0:5490b791ee3d 622 for(x=0;x<(SBUFSIZE/2);x++) {
xshige 0:5490b791ee3d 623 unsigned char sbyte;
xshige 0:5490b791ee3d 624 if (-1==sbuf.GetByte(&sbyte)) {
xshige 0:5490b791ee3d 625 // Net::poll();
xshige 0:5490b791ee3d 626 break;
xshige 0:5490b791ee3d 627 }
xshige 0:5490b791ee3d 628 sendDec(sbyte);
xshige 0:5490b791ee3d 629 }
xshige 0:5490b791ee3d 630 #endif
xshige 0:5490b791ee3d 631 if (tmr.read() > 0.05) {
xshige 0:5490b791ee3d 632 tmr.reset();
xshige 0:5490b791ee3d 633 if (metaint>0) {
xshige 0:5490b791ee3d 634 led4=!led4; //Show that we are alive
xshige 0:5490b791ee3d 635 if ((metaint/4)<slen) led3=1; else led3=0;
xshige 0:5490b791ee3d 636 if ((metaint*2/4)<slen) led2=1; else led2=0;
xshige 0:5490b791ee3d 637 if ((metaint*3/4)<slen) led1=1; else led1=0;
xshige 0:5490b791ee3d 638 } else {
xshige 0:5490b791ee3d 639 led1=!led1; // indicate no metadata
xshige 0:5490b791ee3d 640 led4=0;
xshige 0:5490b791ee3d 641 }
xshige 0:5490b791ee3d 642 }
xshige 0:5490b791ee3d 643 }
xshige 0:5490b791ee3d 644
xshige 0:5490b791ee3d 645 }