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