diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/test_codec.c | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index af3fff7016..b8aa93d99b 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c | |||
@@ -99,6 +99,9 @@ struct wavinfo_t | |||
99 | static void* audiobuf; | 99 | static void* audiobuf; |
100 | static void* codec_mallocbuf; | 100 | static void* codec_mallocbuf; |
101 | static size_t audiosize; | 101 | static size_t audiosize; |
102 | static size_t audiobufsize; | ||
103 | static int offset; | ||
104 | static int fd; | ||
102 | 105 | ||
103 | /* Our local implementation of the codec API */ | 106 | /* Our local implementation of the codec API */ |
104 | static struct codec_api ci; | 107 | static struct codec_api ci; |
@@ -119,6 +122,7 @@ static uint32_t crc32; | |||
119 | static volatile unsigned int elapsed; | 122 | static volatile unsigned int elapsed; |
120 | static volatile bool codec_playing; | 123 | static volatile bool codec_playing; |
121 | static volatile long endtick; | 124 | static volatile long endtick; |
125 | static volatile long rebuffertick; | ||
122 | struct wavinfo_t wavinfo; | 126 | struct wavinfo_t wavinfo; |
123 | 127 | ||
124 | static unsigned char wav_header[44] = | 128 | static unsigned char wav_header[44] = |
@@ -261,6 +265,44 @@ static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count) | |||
261 | rb->reset_poweroff_timer(); | 265 | rb->reset_poweroff_timer(); |
262 | } | 266 | } |
263 | 267 | ||
268 | /* | ||
269 | * Helper function used when the file is larger then the available memory. | ||
270 | * Rebuffers the file by setting the start of the audio buffer to be | ||
271 | * new_offset and filling from there. | ||
272 | */ | ||
273 | static int fill_buffer(int new_offset){ | ||
274 | size_t n, bytestoread; | ||
275 | long temp = *rb->current_tick; | ||
276 | rb->lseek(fd,new_offset,SEEK_SET); | ||
277 | |||
278 | if(new_offset + audiobufsize <= track.filesize) | ||
279 | bytestoread = audiobufsize; | ||
280 | else | ||
281 | bytestoread = track.filesize-new_offset; | ||
282 | |||
283 | n = rb->read(fd, audiobuf,bytestoread); | ||
284 | |||
285 | if (n != bytestoread) | ||
286 | { | ||
287 | log_text("Read failed.",true); | ||
288 | DEBUGF("read fail: got %d bytes, expected %d\n", (int)n, (int)audiobufsize); | ||
289 | rb->backlight_on(); | ||
290 | |||
291 | if (fd >= 0) | ||
292 | { | ||
293 | rb->close(fd); | ||
294 | } | ||
295 | |||
296 | return -1; | ||
297 | } | ||
298 | offset = new_offset; | ||
299 | |||
300 | /*keep track of how much time we spent buffering*/ | ||
301 | rebuffertick += *rb->current_tick-temp; | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
264 | /* WAV output or calculate crc32 of output*/ | 306 | /* WAV output or calculate crc32 of output*/ |
265 | static void pcmbuf_insert_wav_checksum(const void *ch1, const void *ch2, int count) | 307 | static void pcmbuf_insert_wav_checksum(const void *ch1, const void *ch2, int count) |
266 | { | 308 | { |
@@ -387,10 +429,18 @@ static size_t read_filebuf(void *ptr, size_t size) | |||
387 | { | 429 | { |
388 | return 0; | 430 | return 0; |
389 | } else { | 431 | } else { |
390 | /* TODO: Don't read beyond end of buffer */ | 432 | size_t realsize = MIN(track.filesize-ci.curpos,size); |
391 | rb->memcpy(ptr, audiobuf + ci.curpos, size); | 433 | |
392 | ci.curpos += size; | 434 | /* check if we have enough bytes ready*/ |
393 | return size; | 435 | if(realsize >(audiobufsize - (ci.curpos-offset))) |
436 | { | ||
437 | /*rebuffer so that we start at ci.curpos*/ | ||
438 | fill_buffer(ci.curpos); | ||
439 | } | ||
440 | |||
441 | rb->memcpy(ptr, audiobuf + (ci.curpos-offset), realsize); | ||
442 | ci.curpos += realsize; | ||
443 | return realsize; | ||
394 | } | 444 | } |
395 | } | 445 | } |
396 | 446 | ||
@@ -403,10 +453,16 @@ static void* request_buffer(size_t *realsize, size_t reqsize) | |||
403 | { | 453 | { |
404 | *realsize = MIN(track.filesize-ci.curpos,reqsize); | 454 | *realsize = MIN(track.filesize-ci.curpos,reqsize); |
405 | 455 | ||
406 | return (audiobuf + ci.curpos); | 456 | /*check if we have enough bytes ready - requested > bufsize-currentbufpos*/ |
457 | if(*realsize>(audiobufsize - (ci.curpos-offset))) | ||
458 | { | ||
459 | /*rebuffer so that we start at ci.curpos*/ | ||
460 | fill_buffer(ci.curpos); | ||
461 | } | ||
462 | |||
463 | return (audiobuf + (ci.curpos-offset)); | ||
407 | } | 464 | } |
408 | 465 | ||
409 | |||
410 | /* Advance file buffer position by <amount> amount of bytes. */ | 466 | /* Advance file buffer position by <amount> amount of bytes. */ |
411 | static void advance_buffer(size_t amount) | 467 | static void advance_buffer(size_t amount) |
412 | { | 468 | { |
@@ -417,7 +473,7 @@ static void advance_buffer(size_t amount) | |||
417 | /* Advance file buffer to a pointer location inside file buffer. */ | 473 | /* Advance file buffer to a pointer location inside file buffer. */ |
418 | static void advance_buffer_loc(void *ptr) | 474 | static void advance_buffer_loc(void *ptr) |
419 | { | 475 | { |
420 | ci.curpos = ptr - audiobuf; | 476 | ci.curpos = ptr - (audiobuf - offset); |
421 | } | 477 | } |
422 | 478 | ||
423 | 479 | ||
@@ -575,14 +631,13 @@ static void codec_thread(void) | |||
575 | res = rb->codec_load_file(codecname,&ci); | 631 | res = rb->codec_load_file(codecname,&ci); |
576 | 632 | ||
577 | /* Signal to the main thread that we are done */ | 633 | /* Signal to the main thread that we are done */ |
578 | endtick = *rb->current_tick; | 634 | endtick = *rb->current_tick - rebuffertick; |
579 | codec_playing = false; | 635 | codec_playing = false; |
580 | } | 636 | } |
581 | 637 | ||
582 | static enum plugin_status test_track(const char* filename) | 638 | static enum plugin_status test_track(const char* filename) |
583 | { | 639 | { |
584 | size_t n; | 640 | size_t n; |
585 | int fd; | ||
586 | enum plugin_status res = PLUGIN_ERROR; | 641 | enum plugin_status res = PLUGIN_ERROR; |
587 | long starttick; | 642 | long starttick; |
588 | long ticks; | 643 | long ticks; |
@@ -590,6 +645,7 @@ static enum plugin_status test_track(const char* filename) | |||
590 | unsigned long duration; | 645 | unsigned long duration; |
591 | const char* ch; | 646 | const char* ch; |
592 | char str[MAX_PATH]; | 647 | char str[MAX_PATH]; |
648 | offset=0; | ||
593 | 649 | ||
594 | /* Display filename (excluding any path)*/ | 650 | /* Display filename (excluding any path)*/ |
595 | ch = rb->strrchr(filename, '/'); | 651 | ch = rb->strrchr(filename, '/'); |
@@ -620,20 +676,24 @@ static enum plugin_status test_track(const char* filename) | |||
620 | log_text("Cannot read metadata",true); | 676 | log_text("Cannot read metadata",true); |
621 | goto exit; | 677 | goto exit; |
622 | } | 678 | } |
623 | 679 | ||
624 | if (track.filesize > audiosize) | 680 | if (track.filesize > audiosize) |
625 | { | 681 | { |
626 | log_text("File too large",true); | 682 | audiobufsize=audiosize; |
627 | goto exit; | 683 | |
684 | } else | ||
685 | { | ||
686 | audiobufsize=track.filesize; | ||
628 | } | 687 | } |
629 | 688 | ||
630 | n = rb->read(fd, audiobuf, track.filesize); | 689 | n = rb->read(fd, audiobuf, audiobufsize); |
631 | 690 | ||
632 | if (n != track.filesize) | 691 | if (n != audiobufsize) |
633 | { | 692 | { |
634 | log_text("Read failed.",true); | 693 | log_text("Read failed.",true); |
635 | goto exit; | 694 | goto exit; |
636 | } | 695 | } |
696 | |||
637 | 697 | ||
638 | /* Initialise the function pointers in the codec API */ | 698 | /* Initialise the function pointers in the codec API */ |
639 | init_ci(); | 699 | init_ci(); |
@@ -653,6 +713,7 @@ static enum plugin_status test_track(const char* filename) | |||
653 | if (checksum) | 713 | if (checksum) |
654 | crc32 = 0xffffffff; | 714 | crc32 = 0xffffffff; |
655 | 715 | ||
716 | rebuffertick=0; | ||
656 | starttick = *rb->current_tick; | 717 | starttick = *rb->current_tick; |
657 | 718 | ||
658 | codec_playing = true; | 719 | codec_playing = true; |
@@ -670,7 +731,7 @@ static enum plugin_status test_track(const char* filename) | |||
670 | 731 | ||
671 | /* Be sure it is done */ | 732 | /* Be sure it is done */ |
672 | rb->codec_thread_do_callback(NULL, NULL); | 733 | rb->codec_thread_do_callback(NULL, NULL); |
673 | 734 | rb->backlight_on(); | |
674 | log_text(str,true); | 735 | log_text(str,true); |
675 | 736 | ||
676 | if (checksum) | 737 | if (checksum) |