summaryrefslogtreecommitdiffstats
path: root/apps/plugins/test_codec.c
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2010-07-06 00:11:30 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2010-07-06 00:11:30 +0000
commit35717ec06eee50ac8d81b3ec097f830d99dcba23 (patch)
treef7f144b7439a65571f4cb4815a660a7943e008c4 /apps/plugins/test_codec.c
parentd884af2b9992f12e98a3e8548aff76b232b5bfb3 (diff)
downloadrockbox-35717ec06eee50ac8d81b3ec097f830d99dcba23.tar.gz
rockbox-35717ec06eee50ac8d81b3ec097f830d99dcba23.zip
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
Diffstat (limited to 'apps/plugins/test_codec.c')
-rw-r--r--apps/plugins/test_codec.c91
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
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> 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)