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 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <alloc.h>
00029 #include <assert.h>
00030 #include <mem.h>
00031 #include "clib/rtos.h"
00032 #include "vs1001.h"
00033 #include "mpbuf.h"
00034
00035
00036
00037 static char huge *bufPtr;
00038 static long bufSize;
00039
00040
00041
00042
00043
00044
00045
00046
00047 static volatile long bufHead, bufCount;
00048 static volatile int bufState;
00049 static long bufThreshold;
00050
00051
00058 void callback(void *param)
00059 {
00060 bufHead += (long)param;
00061 bufHead %= bufSize;
00062 bufCount -= (long)param;
00063
00064 if (bufState == BUF_STOPPING)
00065 bufState = BUF_STOPPED;
00066 if (bufState == BUF_PLAYING )
00067 BUF_Play();
00068 }
00069
00070
00076 long BUF_GetSize()
00077 {
00078 return bufSize;
00079 }
00080
00081
00086 long BUF_GetCount()
00087 {
00088 disable();
00089 long count = bufCount;
00090 enable();
00091 return count;
00092 }
00093
00094
00102 long BUF_GetFreeBytes()
00103 {
00104 return BUF_GetSize()-BUF_GetCount();
00105 }
00106
00107
00125 int BUF_GetState()
00126 {
00127 return bufState;
00128 }
00129
00130
00146 void BUF_SetThreshold(long threshold)
00147 {
00148 bufThreshold = threshold;
00149 }
00150
00151
00164 void BUF_GetPositions(long *playpos, long *writepos)
00165 {
00166 disable();
00167 if (playpos)
00168 *playpos = bufHead;
00169 if (writepos)
00170 *writepos = (bufHead+bufCount) % bufSize;
00171 enable();
00172 }
00173
00174
00202 void BUF_Lock(long offset, long length,
00203 char **buf1, long *len1,
00204 char **buf2, long *len2 )
00205 {
00206 if (offset == BUF_FROMWRITEPOS)
00207 BUF_GetPositions(NULL, &offset);
00208
00209 offset = offset % bufSize;
00210 if (length > bufSize)
00211 length = bufSize;
00212
00213 *buf1 = &bufPtr[offset];
00214 *len1 = min(length, bufSize-offset);
00215 if (buf2 && len2) {
00216 if (*len1 < length) {
00217 *buf2 = bufPtr;
00218 *len2 = length - *len1;
00219 } else {
00220 *buf2 = NULL;
00221 *len2 = 0;
00222 }
00223 }
00224 }
00225
00226
00237 void BUF_Unlock(long bytesWritten)
00238 {
00239 disable();
00240 bufCount += bytesWritten;
00241 bool ok = bufCount <= bufSize;
00242 enable();
00243 assert(ok);
00244
00245
00246
00247 if (bufState == BUF_STALLED &&
00248 bufCount >= bufThreshold)
00249 BUF_Play();
00250 }
00251
00252
00273 unsigned BUF_Write(char *src, unsigned length)
00274 {
00275 char *buf1, *buf2;
00276 long len1, len2;
00277
00278 length = min(length, BUF_GetFreeBytes());
00279
00280 BUF_Lock( BUF_FROMWRITEPOS, length,
00281 &buf1, &len1, &buf2, &len2);
00282
00283 memcpy(buf1, src, len1);
00284 if (buf2)
00285 memcpy(buf2, &src[len1], len2);
00286 BUF_Unlock(len1+len2);
00287
00288 return len1+len2;
00289 }
00290
00291
00306 void BUF_Play()
00307 {
00308 if (BUF_GetCount() == 0) {
00309 bufState = BUF_STALLED;
00310 } else if (VS_IsPlaying()) {
00311 bufState = BUF_PLAYING;
00312 } else {
00313 char *buf1;
00314 long len1 = BUF_GetCount();
00315
00316 if (len1 > VS_FIFOSIZE)
00317 len1 = VS_FIFOSIZE;
00318
00319 BUF_Lock(bufHead, len1, &buf1, &len1, NULL, NULL);
00320 VS_PlayMpegAsync(buf1, len1, callback, (void*)len1);
00321
00322 bufState = BUF_PLAYING;
00323 }
00324 }
00325
00326
00333 void BUF_Stop()
00334 {
00335 if (bufState == BUF_STALLED)
00336 bufState = BUF_STOPPED;
00337 else if (bufState == BUF_PLAYING)
00338 bufState = BUF_STOPPING;
00339 }
00340
00341
00346 void BUF_Flush()
00347 {
00348 BUF_Play();
00349 while (bufState != BUF_STALLED)
00350 RTX_Sleep_Time(10);
00351 BUF_Stop();
00352 }
00353
00354
00359 void BUF_Clear()
00360 {
00361 BUF_Stop();
00362 while (bufState != BUF_STOPPED) {};
00363
00364 bufCount = 0;
00365 bufHead = 0;
00366 }
00367
00368
00382 long BUF_Init(long minsize, long maxsize)
00383 {
00384 printf("BUF_Init: ");
00385
00386 bufSize = maxsize;
00387 while (bufSize >= minsize) {
00388 bufPtr = (char*)farmalloc(bufSize);
00389 if (bufPtr)
00390 break;
00391 bufSize -= 16*1024;
00392 }
00393
00394 if (bufPtr) {
00395 printf( "allocated %ldkb at %p.\n", bufSize>>10, bufPtr );
00396 } else {
00397 printf( "couldn't allocate at least %ld bytes.\n", minsize);
00398 bufSize = 0;
00399 }
00400
00401 bufState = BUF_STOPPED;
00402 bufHead = 0;
00403 bufCount = 0;
00404 bufThreshold = VS_FIFOSIZE;
00405 return bufSize;
00406 }
00407
00408
00413 void BUF_Done()
00414 {
00415 BUF_Stop();
00416 if (bufPtr)
00417 farfree(bufPtr);
00418 bufSize=0;
00419 }
00420