00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00056 #include <sys/heap.h>
00057 #include <sys/event.h>
00058 #include <sys/timer.h>
00059 #include <sys/thread.h>
00060
00061 #include <dev/vs1001k.h>
00062
00063 #include <stdlib.h>
00064 #include <string.h>
00065 #include <stdio.h>
00066
00067 #include "player.h"
00068 #include <sys/bankmem.h>
00069
00070 #define MAX_WAITSTREAM 20
00071 #define BIGBUF_WATERMARK 65535UL
00072
00073
00074 PLAYERINFO player;
00075
00076 #if defined(__AVR__)
00077
00078
00079
00080
00081 static void ClearMetaData(void)
00082 {
00083 if (player.psi_metatitle) {
00084 free(player.psi_metatitle);
00085 player.psi_metatitle = 0;
00086 }
00087 if (player.psi_metaurl) {
00088 free(player.psi_metaurl);
00089 player.psi_metaurl = 0;
00090 }
00091 }
00092
00093
00094
00095
00096 static int ProcessMetaData(void)
00097 {
00098 u_char blks = 0;
00099 u_short cnt;
00100 int got;
00101 int rc = 0;
00102 u_char to_cnt = 0;
00103 char *mbuf;
00104 char *mn1;
00105 char *mn2;
00106 char *md1;
00107 char *md2;
00108
00109
00110
00111
00112 while (player.psi_status == PSI_RUNNING) {
00113 if ((got = NutTcpReceive(player.psi_sock, &blks, 1)) == 1)
00114 break;
00115 if (got < 0 || to_cnt++ > MAX_WAITSTREAM) {
00116 printf("[NoLen]");
00117 return -1;
00118 }
00119 }
00120 if (blks) {
00121 if (blks > 32) {
00122 printf("[Blks=%u]", blks);
00123 return -1;
00124 }
00125
00126 cnt = blks * 16;
00127 if ((mbuf = malloc(cnt + 1)) == 0) {
00128 printf("[NoMem]");
00129 return -1;
00130 }
00131
00132
00133
00134
00135 while (player.psi_status == PSI_RUNNING) {
00136 if ((got = NutTcpReceive(player.psi_sock, mbuf + rc, cnt)) < 0) {
00137 printf("[RxFail]");
00138 return -1;
00139 }
00140 if (got) {
00141 to_cnt = 0;
00142 if ((cnt -= got) == 0)
00143 break;
00144 rc += got;
00145 mbuf[rc] = 0;
00146 } else if (to_cnt++ > MAX_WAITSTREAM) {
00147 printf("[RxTo]");
00148 return -1;
00149 }
00150 }
00151
00152 ClearMetaData();
00153 printf("\nMeta='%s'\n", mbuf);
00154 mn1 = mbuf;
00155 while (mn1) {
00156 if ((mn2 = strchr(mn1, ';')) != 0)
00157 *mn2++ = 0;
00158 if ((md1 = strchr(mn1, '=')) != 0) {
00159 *md1++ = 0;
00160 while (*md1 == ' ' || *md1 == '\'')
00161 md1++;
00162 if ((md2 = strrchr(md1, '\'')) != 0)
00163 *md2 = 0;
00164 if (strcasecmp(mn1, "StreamTitle") == 0 && player.psi_metatitle == 0) {
00165 player.psi_metatitle = malloc(strlen(md1) + 1);
00166 strcpy(player.psi_metatitle, md1);
00167 } else if (strcasecmp(mn1, "StreamUrl") == 0 && player.psi_metaurl == 0) {
00168 player.psi_metaurl = malloc(strlen(md1) + 1);
00169 strcpy(player.psi_metaurl, md1);
00170 }
00171 }
00172 mn1 = mn2;
00173 }
00174 free(mbuf);
00175 player.psi_metaupdate = 1;
00176 }
00177 return 0;
00178 }
00179
00180
00181
00182
00183
00184 THREAD(Player, arg)
00185 {
00186 size_t rbytes;
00187 char *mp3buf;
00188 u_char to_cnt = 0;
00189 int got;
00190 u_char ief;
00191
00192
00193
00194
00195 for (;;) {
00196
00197
00198
00199 for (;;) {
00200
00201 printf("[IDLE]");
00202 ClearMetaData();
00203 player.psi_status = PSI_IDLE;
00204 NutEventBroadcast(&player.psi_stsevt);
00205
00206
00207 NutEventWait(&player.psi_cmdevt, 0);
00208 printf("[EVT%u]", player.psi_status);
00209 if (player.psi_status == PSI_START)
00210 break;
00211 }
00212
00213
00214 printf("[RUN]");
00215 player.psi_status = PSI_RUNNING;
00216 player.psi_mp3left = player.psi_metaint;
00217 NutEventBroadcast(&player.psi_stsevt);
00218
00219
00220 ief = VsPlayerInterrupts(0);
00221 NutSegBufReset();
00222 VsPlayerInterrupts(ief);
00223
00224
00225
00226
00227 while (player.psi_status == PSI_RUNNING) {
00228
00229
00230
00231
00232
00233 ief = VsPlayerInterrupts(0);
00234 mp3buf = NutSegBufWriteRequest(&rbytes);
00235 VsPlayerInterrupts(ief);
00236 if (rbytes < 1024) {
00237 if (VsGetStatus() != VS_STATUS_RUNNING)
00238 VsPlayerKick();
00239 if (rbytes == 0) {
00240 NutSleep(125);
00241 continue;
00242 }
00243 }
00244
00245
00246 if (player.psi_metaint && rbytes > player.psi_mp3left)
00247 rbytes = player.psi_mp3left;
00248
00249
00250
00251
00252 while (rbytes) {
00253
00254
00255 if ((got = NutTcpReceive(player.psi_sock, mp3buf, rbytes)) < 0) {
00256
00257 printf("[RXFAIL]");
00258 player.psi_status = PSI_IDLE;
00259 break;
00260 }
00261
00262
00263
00264
00265 if (got) {
00266
00267 ief = VsPlayerInterrupts(0);
00268 mp3buf = NutSegBufWriteCommit(got);
00269 VsPlayerInterrupts(ief);
00270
00271
00272 to_cnt = 0;
00273 rbytes -= got;
00274
00275
00276 if (player.psi_metaint) {
00277 player.psi_mp3left -= got;
00278 if (player.psi_mp3left == 0) {
00279 if (ProcessMetaData()) {
00280 printf("[METAFAIL]");
00281
00282
00283 }
00284 player.psi_mp3left = player.psi_metaint;
00285 }
00286 }
00287
00288
00289 if (VsGetStatus() != VS_STATUS_RUNNING) {
00290 ief = VsPlayerInterrupts(0);
00291 if ((NutSegBufUsed() > 2048 && player.psi_start) ||
00292 (NutSegBufUsed() > BIGBUF_WATERMARK && NutSegBufAvailable() < BIGBUF_WATERMARK))
00293 VsPlayerKick();
00294 else
00295 VsPlayerInterrupts(ief);
00296 }
00297 player.psi_start = 0;
00298 }
00299
00300
00301
00302
00303 else {
00304 printf("[T%u, %u]", to_cnt, NutHeapAvailable());
00305 NutSleep(100);
00306 if (to_cnt++ > MAX_WAITSTREAM) {
00307
00308 printf("[RXTO]");
00309 player.psi_status = PSI_IDLE;
00310 break;
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319 NutThreadYield();
00320 }
00321
00322
00323
00324 NutThreadYield();
00325 }
00326
00327 printf("[FLUSH]");
00328 VsPlayerFlush();
00329 while (VsGetStatus() == VS_STATUS_RUNNING) {
00330 NutSleep(63);
00331 }
00332
00333
00334 printf("[RESET]");
00335 VsPlayerReset(0);
00336 }
00337 }
00338
00345 int PlayerInit(void)
00346 {
00347
00348 if (VsPlayerInit() || VsPlayerReset(0))
00349 return -1;
00350
00351
00352 if (NutThreadCreate("player", Player, 0, 512) == 0)
00353 return -1;
00354
00355 return 0;
00356 }
00357
00363 int PlayerStop(u_long tmo)
00364 {
00365 while (player.psi_status != PSI_IDLE) {
00366 printf("[STOP]");
00367 player.psi_status = PSI_STOP;
00368 NutEventPost(&player.psi_cmdevt);
00369 if (NutEventWait(&player.psi_stsevt, tmo)) {
00370 printf("[TOP]");
00371 return -1;
00372 }
00373 }
00374 printf("[STOPPED]");
00375 return 0;
00376 }
00377
00383 int PlayerStart(TCPSOCKET * sock, u_long metaint, u_long tmo)
00384 {
00385 if (PlayerStop(tmo))
00386 return -1;
00387
00388
00389 NutEventBroadcast(&player.psi_stsevt);
00390 printf("[START]");
00391 player.psi_status = PSI_START;
00392 player.psi_sock = sock;
00393 player.psi_metaint = metaint;
00394 NutEventPost(&player.psi_cmdevt);
00395
00396
00397 if (NutEventWait(&player.psi_stsevt, tmo) || player.psi_status != PSI_RUNNING) {
00398 printf("[TOS]");
00399 return -1;
00400 }
00401 return 0;
00402 }
00403
00404 #endif