Frank Weissenborn / ShoutCastConnector

ShoutcastConnector.cpp

Committer:
FrankWeissenborn
Date:
2011-01-10
Revision:
1:25ceaa587f6b
Child:
2:9abcdc65c5b5

File content as of revision 1:25ceaa587f6b:

#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();
}