Frank Weissenborn / ShoutCastConnector
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