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.
ShoutcastConnector.cpp
- Committer:
- FrankWeissenborn
- Date:
- 2011-01-13
- Revision:
- 4:a3b7032f0776
- Parent:
- 3:87023c28aff5
- Child:
- 5:36d14584e42f
File content as of revision 4:a3b7032f0776:
#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; 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; ReadState=GET_RESPONSE; WriteState=PUT_HEADER; } int ShoutcastConnector::Connect(IpAddr address, int port) { if ((ReadState!=GET_RESPONSE)||(WriteState!=PUT_HEADER)) { Disconnect(); //wait wait_ms(500); } kb = 0; readed = 0; size = 0; metaint=0; // metadate interval play=false; for(int i=0; i< BUFFER_Z; i++) inbuf[i] = 0; // IP input buffer for(int i=0; i< 800; i++) sResponse[i] = 0; // IP input buffer Host server(address, port); // 128k mp3 IpAddr serverIp = server.getIp(); DEBUGOUT("ShoutcastConnector: 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) { DEBUGOUT("ShoutcastConnector: Error %d in sock.connect().\r\n", bindErr); return -1; } return 0; } int ShoutcastConnector::Disconnect() { TCPSocketErr err = sock.close(); if (TCPSOCKET_OK != err) { DEBUGOUT("ShoutcastConnector: Error %d in Disconnect().\r\n", err); return -1; } else { DEBUGOUT("ShoutcastConnector: disconnected"); } _mp3->stop(); ReadState=GET_RESPONSE; WriteState=PUT_HEADER; 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("ShoutcastConnector: TCP Socket Timeout\r\n"); ReadState=GET_RESPONSE; WriteState=PUT_HEADER; break; case TCPSOCKET_CONRST: DEBUGOUT("ShoutcastConnector: TCP Socket CONRST\r\n"); ReadState=GET_RESPONSE; WriteState=PUT_HEADER; break; case TCPSOCKET_CONABRT: DEBUGOUT("ShoutcastConnector: TCP Socket CONABRT\r\n"); DEBUGOUT("ShoutcastConnector: Maybe Server Down...\r\n"); ReadState=GET_RESPONSE; WriteState=PUT_HEADER; break; case TCPSOCKET_ERROR: DEBUGOUT("ShoutcastConnector: TCP Socket Error\r\n"); break; case TCPSOCKET_DISCONNECTED: //Close socket... DEBUGOUT("ShoutcastConnector: Disconnected\r\n"); sock.close(); break; }// switch(e) } void ShoutcastConnector::Writeable() { 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" "Icy-MetaData: 1\r\n" // send this if you want Metadata // "Connection: close\r\n" "\r\n" ; sock.send(str, strlen(str)); DEBUGOUT("\r\nShoutcastConnector: HEADER:\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("ShoutcastConnector: 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\nShoutcastConnector: metaint: %d\r\n\r\n",metaint); //debug // DEBUGOUT("ShoutcastConnector: HeaderLen:%d\r\n",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)) { kb += len; if (metaint > 0) { if (readed + len > metaint) { //XXX int startindex = metaint-readed; size = inbuf[startindex]; //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) { int start =-1; int length = -1; for (int i = startindex + 1; i < startindex + 1 + size*16; i++) { if (inbuf[i] == '\'') { if (start == -1) start = i+1-(startindex+1); else { if(inbuf[i+1] == ';') { length = (i - (startindex+1)) - start; //last indexs - first index break; } } } } _callback(&inbuf[startindex + 1], size*16, start ,length); //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("ShoutcastConnector: Muh") } } else { //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); } if (!play && _mp3->bufferCount() > 0.8 * _mp3->bufferLength()) { _mp3->play(); play = true; } if (play && _mp3->bufferCount() < 0.1 * _mp3->bufferLength()) { _mp3->pause(); play = false; } } // while (len=sock...) return; // get more strea } // switch (ReadState) }