// // Created by janco on 10-3-16. // #include #include #include #include #include #include #include "vs10xx.h" #include #include #include #include #include #include #include #include #include #include #include #define RADIO_URL "/3fm-bb-mp3" #define MAX_HEADERLINE 512 TCPSOCKET *sock; u_short mss = 1460; u_long rx_to = 3000; u_short tcpbufsiz = 8760; u_long radio_ip; FILE *stream; u_long metaint; void playStream(){ printf("Set volume %d", VsSetVolume(40, 40)); radio_ip = inet_addr("145.58.53.152"); ConnectStation(sock, radio_ip, 80, &metaint); if(stream) { PlayMp3Stream(stream, metaint); fclose(stream); } NutTcpCloseSocket(sock); } void ConnectStation(TCPSOCKET *sock, u_long ip, u_short port, u_long *metaint){ int rc; u_char *line; u_char *cp; /* * Connect the TCP server. */ if ((sock = NutTcpCreateSocket()) == 0) { printf("Probleem bij het creereen van tcp socket"); } if (NutTcpSetSockOpt(sock, TCP_MAXSEG, &mss, sizeof(mss))) printf("Probleem bij het creereen van tcp socket"); if (NutTcpSetSockOpt(sock, SO_RCVTIMEO, &rx_to, sizeof(rx_to))) printf("Probleem bij het creereen van tcp socket"); if (NutTcpSetSockOpt(sock, SO_RCVBUF, &tcpbufsiz, sizeof(tcpbufsiz))) printf("Probleem bij het creereen van tcp socket"); printf("Connecting %s:%u...", inet_ntoa(ip), port); if ((rc = NutTcpConnect(sock, ip, port))) { printf("Error: Connect failed with %d\n", ip); return 0; } puts("OK"); if ((stream = _fdopen((int) sock, "r+b")) == 0) { printf("Error: Can't create stream"); return 0; } /* * Send the HTTP request. */ printf("GET %s HTTP/1.0\n\n", RADIO_URL); fprintf(stream, "GET %s HTTP/1.0\r\n", RADIO_URL); fprintf(stream, "Host: %s\r\n", inet_ntoa(ip)); fprintf(stream, "User-Agent: Ethernut\r\n"); fprintf(stream, "Accept: */*\r\n"); fprintf(stream, "Icy-MetaData: 1\r\n"); fprintf(stream, "Connection: close\r\n"); fputs("\r\n", stream); fflush(stream); /* * Receive the HTTP header. */ line = malloc(MAX_HEADERLINE); while(fgets(line, MAX_HEADERLINE, stream)) { /* * Chop off the carriage return at the end of the line. If none * was found, then this line was probably too large for our buffer. */ cp = strchr(line, '\r'); if(cp == 0) { printf("Warning: Input buffer overflow"); continue; } *cp = 0; /* * The header is terminated by an empty line. */ if(*line == 0) { break; } if(strncmp(line, "icy-metaint:", 12) == 0) { *metaint = atol(line + 12); } printf("%s\n", line); } putchar('\n'); free(line); } int ProcessMetaData(FILE *stream) { u_char blks = 0; u_short cnt; int got; int rc = 0; u_char *mbuf; /* * Wait for the lenght byte. */ got = fread(&blks, 1, 1, stream); if(got != 1) { return -1; } if (blks) { if (blks > 32) { printf("Error: Metadata too large, %u blocks\n", blks); return -1; } cnt = blks * 16; if ((mbuf = malloc(cnt + 1)) == 0) { return -1; } /* * Receive the metadata block. */ for (;;) { if ((got = fread(mbuf + rc, 1, cnt, stream)) <= 0) { return -1; } if ((cnt -= got) == 0) { break; } rc += got; mbuf[rc] = 0; } printf("\nMeta='%s'\n", mbuf); free(mbuf); } return 0; } void PlayMp3Stream(FILE *stream, u_long metaint) { size_t rbytes; u_char *mp3buf; u_char ief; int got = 0; u_long last; u_long mp3left = metaint; /* * Initialize the MP3 buffer. The NutSegBuf routines provide a global * system buffer, which works with banked and non-banked systems. */ if (NutSegBufInit(8192) == 0) { puts("Error: MP3 buffer init failed"); return; } /* * Initialize the MP3 decoder hardware. */ if (VsPlayerReset(0)) { puts("Error: MP3 hardware init failed"); return; } /* * Reset the MP3 buffer. */ ief = VsPlayerInterrupts(0); NutSegBufReset(); VsPlayerInterrupts(ief); last = NutGetSeconds(); for (;;) { /* * Query number of byte available in MP3 buffer. */ ief = VsPlayerInterrupts(0); mp3buf = NutSegBufWriteRequest(&rbytes); VsPlayerInterrupts(ief); /* * If the player is not running, kick it. */ if (VsGetStatus() != VS_STATUS_RUNNING) { puts("Not running"); if(rbytes < 1024 || NutGetSeconds() - last > 4UL) { last = NutGetSeconds(); puts("Kick player"); VsPlayerKick(); } } /* * Do not read pass metadata. */ if (metaint && rbytes > mp3left) { rbytes = mp3left; } /* * Read data directly into the MP3 buffer. */ while (rbytes) { if ((got = fread(mp3buf, 1, rbytes, stream)) > 0) { ief = VsPlayerInterrupts(0); mp3buf = NutSegBufWriteCommit(got); VsPlayerInterrupts(ief); if (metaint) { mp3left -= got; if (mp3left == 0) { ProcessMetaData(stream); mp3left = metaint; } } if(got < rbytes && got < 512) { printf("%lu buffered\n", NutSegBufUsed()); NutSleep(250); } else { NutThreadYield(); } } else { break; } rbytes -= got; } if(got <= 0) { break; } } }