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