From 302cbe30d2aea0038146cd3c64d251c69d2bb7da Mon Sep 17 00:00:00 2001 From: saratoga Date: Tue, 6 Jul 2010 00:11:30 +0000 Subject: [PATCH] Commit FS#11458 by me. Fixes test_codec to work on files larger then the available audio buffer. Allows test_codec to work normally on the AMS Sansas as well as D2, etc. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27303 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/test_codec.c | 91 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index af3fff701..b8aa93d99 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -99,6 +99,9 @@ struct wavinfo_t static void* audiobuf; static void* codec_mallocbuf; static size_t audiosize; +static size_t audiobufsize; +static int offset; +static int fd; /* Our local implementation of the codec API */ static struct codec_api ci; @@ -119,6 +122,7 @@ static uint32_t crc32; static volatile unsigned int elapsed; static volatile bool codec_playing; static volatile long endtick; +static volatile long rebuffertick; struct wavinfo_t wavinfo; static unsigned char wav_header[44] = @@ -261,6 +265,44 @@ static void pcmbuf_insert_null(const void *ch1, const void *ch2, int count) rb->reset_poweroff_timer(); } +/* + * Helper function used when the file is larger then the available memory. + * Rebuffers the file by setting the start of the audio buffer to be + * new_offset and filling from there. + */ +static int fill_buffer(int new_offset){ + size_t n, bytestoread; + long temp = *rb->current_tick; + rb->lseek(fd,new_offset,SEEK_SET); + + if(new_offset + audiobufsize <= track.filesize) + bytestoread = audiobufsize; + else + bytestoread = track.filesize-new_offset; + + n = rb->read(fd, audiobuf,bytestoread); + + if (n != bytestoread) + { + log_text("Read failed.",true); + DEBUGF("read fail: got %d bytes, expected %d\n", (int)n, (int)audiobufsize); + rb->backlight_on(); + + if (fd >= 0) + { + rb->close(fd); + } + + return -1; + } + offset = new_offset; + + /*keep track of how much time we spent buffering*/ + rebuffertick += *rb->current_tick-temp; + + return 0; +} + /* WAV output or calculate crc32 of output*/ static void pcmbuf_insert_wav_checksum(const void *ch1, const void *ch2, int count) { @@ -387,10 +429,18 @@ static size_t read_filebuf(void *ptr, size_t size) { return 0; } else { - /* TODO: Don't read beyond end of buffer */ - rb->memcpy(ptr, audiobuf + ci.curpos, size); - ci.curpos += size; - return size; + size_t realsize = MIN(track.filesize-ci.curpos,size); + + /* check if we have enough bytes ready*/ + if(realsize >(audiobufsize - (ci.curpos-offset))) + { + /*rebuffer so that we start at ci.curpos*/ + fill_buffer(ci.curpos); + } + + rb->memcpy(ptr, audiobuf + (ci.curpos-offset), realsize); + ci.curpos += realsize; + return realsize; } } @@ -403,10 +453,16 @@ static void* request_buffer(size_t *realsize, size_t reqsize) { *realsize = MIN(track.filesize-ci.curpos,reqsize); - return (audiobuf + ci.curpos); + /*check if we have enough bytes ready - requested > bufsize-currentbufpos*/ + if(*realsize>(audiobufsize - (ci.curpos-offset))) + { + /*rebuffer so that we start at ci.curpos*/ + fill_buffer(ci.curpos); + } + + return (audiobuf + (ci.curpos-offset)); } - /* Advance file buffer position by amount of bytes. */ static void advance_buffer(size_t amount) { @@ -417,7 +473,7 @@ static void advance_buffer(size_t amount) /* Advance file buffer to a pointer location inside file buffer. */ static void advance_buffer_loc(void *ptr) { - ci.curpos = ptr - audiobuf; + ci.curpos = ptr - (audiobuf - offset); } @@ -575,14 +631,13 @@ static void codec_thread(void) res = rb->codec_load_file(codecname,&ci); /* Signal to the main thread that we are done */ - endtick = *rb->current_tick; + endtick = *rb->current_tick - rebuffertick; codec_playing = false; } static enum plugin_status test_track(const char* filename) { size_t n; - int fd; enum plugin_status res = PLUGIN_ERROR; long starttick; long ticks; @@ -590,6 +645,7 @@ static enum plugin_status test_track(const char* filename) unsigned long duration; const char* ch; char str[MAX_PATH]; + offset=0; /* Display filename (excluding any path)*/ ch = rb->strrchr(filename, '/'); @@ -620,20 +676,24 @@ static enum plugin_status test_track(const char* filename) log_text("Cannot read metadata",true); goto exit; } - + if (track.filesize > audiosize) { - log_text("File too large",true); - goto exit; + audiobufsize=audiosize; + + } else + { + audiobufsize=track.filesize; } - n = rb->read(fd, audiobuf, track.filesize); + n = rb->read(fd, audiobuf, audiobufsize); - if (n != track.filesize) + if (n != audiobufsize) { log_text("Read failed.",true); goto exit; } + /* Initialise the function pointers in the codec API */ init_ci(); @@ -653,6 +713,7 @@ static enum plugin_status test_track(const char* filename) if (checksum) crc32 = 0xffffffff; + rebuffertick=0; starttick = *rb->current_tick; codec_playing = true; @@ -670,7 +731,7 @@ static enum plugin_status test_track(const char* filename) /* Be sure it is done */ rb->codec_thread_do_callback(NULL, NULL); - + rb->backlight_on(); log_text(str,true); if (checksum) -- 2.11.4.GIT