Procházet zdrojové kódy

Httpstream

# Conflicts:
#	main.c

Most things working. Still backlight sometimes buggie..
jancoow před 9 roky
rodič
revize
012f54cfd4
5 změnil soubory, kde provedl 318 přidání a 18 odebrání
  1. 285 0
      httpstream.c
  2. 13 0
      httpstream.h
  3. 19 14
      main.c
  4. 0 3
      network.c
  5. 1 1
      vs10xx.c

+ 285 - 0
httpstream.c

@@ -0,0 +1,285 @@
+//
+// 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>
+
+#include "ntp.h"
+#include "httpstream.h"
+
+#define MAX_HEADERLINE 512
+
+bool isStreaming;
+
+TCPSOCKET *sock;
+u_short mss = 1460;
+u_long rx_to = 3000;
+u_short tcpbufsiz = 8760;
+FILE *stream;
+u_long metaint;
+
+THREAD(Stream, args)
+{
+    if(stream) {
+        PlayMp3Stream(stream, metaint);
+    }
+    stopStream();
+    NutThreadExit();
+}
+
+void playStream(char *ipaddr, u_short port, char *radiourl){
+    if(isStreaming != true){
+        isStreaming = true;
+        ConnectStation(sock, inet_addr(ipaddr), port, radiourl, &metaint);
+        NutThreadCreate("Stream", Stream, NULL, 1024);
+    }
+}
+
+void stopStream(){
+    isStreaming = false;
+    fclose(stream);
+    NutTcpCloseSocket(sock);
+}
+
+bool HttpIsStreaming(){
+    return isStreaming;
+}
+
+void ConnectStation(TCPSOCKET *sock, u_long ip, u_short port, char *radiourl, 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", radiourl);
+    fprintf(stream, "GET %s HTTP/1.0\r\n", radiourl);
+    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();
+
+    while (isStreaming == true) {
+        /*
+         * 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 && (isStreaming == true)) {
+            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;
+        }
+    }
+}

+ 13 - 0
httpstream.h

@@ -0,0 +1,13 @@
+//
+// Created by janco on 25-2-16.
+//
+
+#ifndef _Httpstream_H
+#define _Httpstream_H
+
+extern bool HttpIsStreaming();
+extern void playStream(char *ipaddr, u_short port, char *radiourl);
+extern void stopStream();
+
+
+#endif /* _Httpstream_H */

+ 19 - 14
main.c

@@ -40,11 +40,14 @@
 #include "flash.h"
 #include "spidrv.h"
 #include "network.h"
+#include "typedefs.h"
+
 
 #include <time.h>
 #include "rtc.h"
 #include "alarm.h"
 #include "ntp.h"
+#include "httpstream.h"
 
 /*-------------------------------------------------------------------------*/
 /* local routines (prototyping)                                            */
@@ -257,7 +260,6 @@ int main(void)
 	initialized = 0;
     int VOL2;
     time_t start;
-    time_t startVolumeTime;
 	int idx = 0;
 
 	int running;
@@ -282,6 +284,8 @@ int main(void)
 
     X12Init();
 
+    VsPlayerInit();
+
     LcdBackLight(LCD_BACKLIGHT_ON);
     NtpInit();
 
@@ -304,16 +308,18 @@ int main(void)
 	/* Enable global interrupts */
 	sei();
 
-    //struct _tm tm;
-	//tm = GetRTCTime();
-	//tm.tm_sec += 10;
-    //setAlarm(tm,"    test1234      ", "0.0.0.0", 8001,1,0,0);
-	//tm.tm_sec +=20;
-	//setAlarm(tm,"    test5678      ", "0.0.0.0", 8001,1,0,1);
+   /* struct _tm tm;
+	tm = GetRTCTime();
+	tm.tm_sec += 10;
+    setAlarm(tm,"    test1234      ", "0.0.0.0", 8001,1,0,0);
+	tm.tm_sec +=20;
+	setAlarm(tm,"    test5678      ", "0.0.0.0", 8001,1,0,1);*/
 
+/*    if(hasNetworkConnection() == true){
+        playStream("145.58.53.152", 80, "/3fm-bb-mp3");
+    }*/
     start = time(0) - 10;
     unsigned char VOL = 64;
-    startVolumeTime = time(0) - 5;
 
     running = 1;
 
@@ -338,8 +344,8 @@ int main(void)
         if(KbGetKey() == KEY_DOWN)
         {
             NutSleep(150);
-            startVolumeTime = time(0);
-            if(VOL > 1){
+            start = time(0);
+            if(VOL > 8){
                 VOL -= 8;
                 VsSetVolume (128-VOL, 128-VOL);
                 displayVolume(VOL/8);
@@ -348,15 +354,14 @@ int main(void)
         else if(KbGetKey() == KEY_UP)
         {
             NutSleep(150);
-            startVolumeTime = time(0);
+            start = time(0);
             if(VOL < 128) {
                 VOL += 8;
                 VsSetVolume(128-VOL, 128-VOL);
                 displayVolume(VOL/8);
-
             }
         }
-        else if(timer(startVolumeTime) >= 5 && checkAlarms() == 1)
+        else if(timer(start) >= 5 && checkAlarms() == 1)
         {
 			for (idx = 0; idx < 3; idx++){
 				if (getState(idx) == 1){
@@ -370,7 +375,7 @@ int main(void)
 				}
 			}
 		}
-		else if (timer(startVolumeTime) >= 5){
+		else if (timer(start) >= 5){
             displayTime(0);
             displayDate(1);
 		}

+ 0 - 3
network.c

@@ -29,9 +29,6 @@
 
 bool isReceiving;
 bool hasNetwork;
-u_short mss = 1460;
-u_long rx_to = 3000;
-u_short tcpbufsiz = 1500;
 
 void NetworkInit() {
     hasNetwork = false;

+ 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));