Pārlūkot izejas kodu

Added beginning of streaming

jancoow 9 gadi atpakaļ
vecāks
revīzija
c26bba54c2
4 mainītis faili ar 288 papildinājumiem un 1 dzēšanām
  1. 271 0
      httpstream.c
  2. 10 0
      httpstream.h
  3. 6 0
      main.c
  4. 1 1
      vs10xx.c

+ 271 - 0
httpstream.c

@@ -0,0 +1,271 @@
+//
+// Created by janco on 10-3-16.
+//
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/thread.h>
+#include <sys/timer.h>
+#include <sys/version.h>
+#include <dev/irqreg.h>
+
+#include "vs10xx.h"
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+
+#include <sys/confnet.h>
+
+#include <arpa/inet.h>
+#include <net/route.h>
+
+#include <dev/board.h>
+#include <pro/httpd.h>
+#include <pro/dhcp.h>
+#include <pro/asp.h>
+#include <pro/discover.h>
+#include <dev/nicrtl.h>
+
+#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;
+        }
+    }
+}

+ 10 - 0
httpstream.h

@@ -0,0 +1,10 @@
+//
+// Created by janco on 25-2-16.
+//
+
+#ifndef _Httpstream_H
+#define _Httpstream_H
+
+extern void playStream();
+
+#endif /* _Httpstream_H */

+ 6 - 0
main.c

@@ -45,6 +45,7 @@
 #include "rtc.h"
 #include "alarm.h"
 #include "ntp.h"
+#include "httpstream.h"
 
 /*-------------------------------------------------------------------------*/
 /* local routines (prototyping)                                            */
@@ -198,6 +199,8 @@ THREAD(StartupInit, arg)
     isAlarmSyncing = 0;
 
     free(content);
+
+    playStream();
     NutThreadExit();
 }
 
@@ -244,6 +247,8 @@ int main(void)
 
     X12Init();
 
+    VsPlayerInit();
+
     LcdBackLight(LCD_BACKLIGHT_ON);
     NtpInit();
 
@@ -297,6 +302,7 @@ int main(void)
             displayDate(1);
         }
         WatchDogRestart();
+        NutSleep(1000);
     }
 
     return(0);

+ 1 - 1
vs10xx.c

@@ -505,7 +505,7 @@ int VsPlayerKick(void)
          *  for the VS1003 we need an extra reset
          *  here before we start playing a stream...
          */
-//        VsPlayerSetMode(VS_SM_RESET);
+        VsPlayerSetMode(VS_SM_RESET);
 //        NutDelay(10);
 //        LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
 //        LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));