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