Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: ShoutcastConnector.cpp
- Revision:
- 1:25ceaa587f6b
- Child:
- 2:9abcdc65c5b5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ShoutcastConnector.cpp Mon Jan 10 20:16:41 2011 +0000
@@ -0,0 +1,299 @@
+#include "ShoutcastConnector.h"
+
+
+enum wSTATE {NOP,PUT_HEADER} WriteState;
+enum rSTATE {GET_RESPONSE,GET_STREAM} ReadState;
+
+
+char inbuf[BUFFER_Z]; // IP input buffer
+char sResponse[800]; // keeps Stream Response
+bool play;
+
+
+
+void statisticsOutput();
+
+int kb = 0;
+int readed = 0;int size = 0;
+int metaint=0; // metadate interval
+
+
+
+
+ShoutcastConnector::ShoutcastConnector(VS1053* mp3, myCallBack_pfn callback)
+{
+ _mp3 = mp3;
+ _callback = callback;
+
+}
+
+int ShoutcastConnector::Connect(IpAddr address, int port)
+{
+ ReadState=GET_RESPONSE;
+ WriteState=PUT_HEADER;
+
+ kb = 0;
+ readed = 0;
+ size = 0;
+ metaint=0; // metadate interval
+ play=false;
+
+ Host server(address, port); // 128k mp3
+ IpAddr serverIp = server.getIp();
+
+ printf("Connecting... %d.%d.%d.%d:%d\r\n",
+ serverIp[0],serverIp[1],serverIp[2],serverIp[3],port);
+
+
+ sock.setOnEvent(this, &ShoutcastConnector::onTCPSocketEvent);
+ TCPSocketErr bindErr = sock.connect(server);
+
+ if (TCPSOCKET_OK != bindErr) {
+ printf("Error %d in sock.connect().\r\n", bindErr);
+ return -1;
+ }
+ return 0;
+}
+
+int ShoutcastConnector::Disconnect()
+{
+ TCPSocketErr err = sock.close();
+
+ if (TCPSOCKET_OK != err) {
+ printf("Error %d in ShoutcastConnector: Disconnect().\r\n", err);
+ return -1;
+ }
+ else {
+ printf("ShoutcastConnector disconnected");
+ }
+ return 0;
+}
+
+void ShoutcastConnector::onTCPSocketEvent(TCPSocketEvent e) {
+ switch (e) {
+ case TCPSOCKET_CONNECTED:
+ // DEBUGOUT("TCP Socket Connected\r\n"); // this printf disturb socket work correctly
+ Writeable();
+ break; // we must comment out ?
+ case TCPSOCKET_WRITEABLE:
+ // DEBUGOUT("TCP Socket Writeable\r\n");
+ break;
+ case TCPSOCKET_READABLE:
+ //Can now read some data...
+ // DEBUGOUT("TCP Socket Readable\r\n");
+ Readable();
+ break;//
+ case TCPSOCKET_CONTIMEOUT:
+ DEBUGOUT("TCP Socket Timeout\r\n");
+ break;
+ case TCPSOCKET_CONRST:
+ DEBUGOUT("TCP Socket CONRST\r\n");
+ break;
+ case TCPSOCKET_CONABRT:
+ DEBUGOUT("TCP Socket CONABRT\r\n");
+ DEBUGOUT("Maybe Server Down...\r\n");
+ break;
+ case TCPSOCKET_ERROR:
+ DEBUGOUT("TCP Socket Error\r\n");
+ break;
+ case TCPSOCKET_DISCONNECTED:
+ //Close socket...
+ DEBUGOUT("ShoutcastConnector Disconnected\r\n");
+ sock.close();
+ break;
+ }// switch(e)
+}
+
+void ShoutcastConnector::Writeable() {
+ //Can now write some data...
+// printf("TCP Socket Writable\r\n"); // debug
+ switch (WriteState) {
+ case PUT_HEADER:
+ const char* str =
+// "GET /live HTTP/1.0\r\n" // use this if solopiano
+ "GET / 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));
+ DEBUGOUT("\r\nHEADER:\r\n%s\r\n", str); // display PUT_HEADER
+ WriteState=NOP;
+ ReadState=GET_RESPONSE;
+ break;
+ case NOP:
+ break;
+ } // switch(WriteState)
+}
+
+
+void ShoutcastConnector::Readable() {
+ int len = 0, i=0;
+ char* cp;
+
+ switch (ReadState) {
+ case GET_RESPONSE:
+ len=sock.recv(inbuf, sizeof inbuf);
+ cp=strstr(inbuf,"\r\n\r\n");
+ if (cp==NULL) {
+ inbuf[len]=0;
+ DEBUGOUT("%s",inbuf); // debug
+ //sprintf(sResponse,"%s",inbuf);
+ return; // still read response again
+ }
+ //
+ *cp=0;
+ sprintf(sResponse+strlen(sResponse),"%s\r\n\r\n",inbuf);
+ DEBUGOUT("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);
+ DEBUGOUT("\r\nmetaint: %d\r\n\r\n",metaint); //debug
+ //
+
+ DEBUGOUT("HeaderLen:%d",len);
+
+ i=strlen(inbuf)+4; // bump bitstream right after response
+ ReadState=GET_STREAM;
+ //initDec();
+ //
+ while (i<len) {
+ // write one bye
+ // sbuf.PutByte(inbuf[i]);
+ i++;
+ readed++;
+ };
+ return;
+ //
+ case GET_STREAM:
+ // receive data ****repeatedly****
+ while (len=sock.recv(inbuf, sizeof inbuf)) {
+ //DEBUGOUT("in")
+ //DEBUGOUT("%d\r\n",len)
+
+ kb += len;
+
+
+ if(metaint > 0)
+ {
+ if(readed + len > metaint)
+ {
+ //XXX
+ int startindex = metaint-readed;
+ size = inbuf[startindex];
+ //DEBUGOUT("MetaData: %d,%d,%d\r\n",metaint,readed,len);
+ //DEBUGOUT("MetaData: %d\r\n",size);
+ //Send first part of data
+ while(_mp3->bufferFree() < startindex)
+ ; // wait
+ _mp3->bufferPutStream(inbuf, startindex);
+
+ if(size>0)
+ {
+ //1.Fall : (metaint-readed)+size <= len
+ //Text ausgeben
+ //rest an mp3 codec
+ if((metaint-readed)+size <= len)
+ {
+ for(i=0; i<size*16; i++)
+ DEBUGOUT("%c",inbuf[startindex + 1 + i]);
+ //Send last part of data
+ while(_mp3->bufferFree() < len-(startindex+1+size*16))
+ ; // wait
+ readed = len-(startindex+1+size*16);
+ _mp3->bufferPutStream(&inbuf[startindex+1+size*16], readed);
+ }
+ else
+ {
+ DEBUGOUT("Muh")
+ }
+ }
+ else
+ {
+ // DEBUGOUT("Title hasn't changed since the last metadata message\r\n");
+ //Send second part of data
+ //XXX
+ while(_mp3->bufferFree() < len-(startindex+1))
+ ; // wait
+ //XXX
+ readed = len-(startindex+1);
+ _mp3->bufferPutStream(&inbuf[startindex+1], len-(startindex+1));
+
+ }
+ }
+ else
+ {
+ readed += len;
+ while(_mp3->bufferFree() < len)
+ ; // wait
+ _mp3->bufferPutStream(inbuf, len);
+ }
+ }
+ else
+ {
+ while(_mp3->bufferFree() < len)
+ ; // wait
+ _mp3->bufferPutStream(inbuf, len);
+ }
+ // save len bytes
+
+
+
+ if(!play && _mp3->bufferCount() > 0.8 * BUFFER_SIZE){
+ _mp3->play();
+ play = true;
+ statisticsOutput();
+ }
+
+ if(play && _mp3->bufferCount() < 0.1 * BUFFER_SIZE)
+ {
+ _mp3->pause();
+ play = false;
+ statisticsOutput();
+ }
+
+
+ } // while (len=sock...)
+
+ /*len=sock.recv(inbuf, sizeof inbuf);
+ while (i<len) {
+ //sbuf.PutByte(inbuf[i]);i++;
+ mp3.bufferSetByte(inbuf[i]);
+ i++;
+ }
+ */
+ //DEBUGOUT("out\r\n");
+ /* i=0;
+ while (i<BUFFER_Z) {
+ // sbuf.PutByte(inbuf[i]);i++;
+ //DEBUGOUT("%d",inbuf[i]); //debug
+ while( == false) {
+ DEBUGOUT("false %d", i);
+ }
+ i++;
+ }//while
+ */
+ // if(mp3.bufferPutStream(&inbuf[0], BUFFER_Z) == false) {
+ // DEBUGOUT("false")
+ // }
+
+
+
+ return; // get more strea
+ //
+ } // switch (ReadState)
+}
+
+void statisticsOutput()
+{
+ printf("Statistics\r\n");
+ // printf("Buffer - Size: %i, Free: %i, Loaded: %i\r\n", BUFFER_SIZE, _mp3.bufferFree(), mp3.bufferCount());
+
+ //mp3.getAudioInfo();
+}
\ No newline at end of file