summaryrefslogtreecommitdiff
path: root/apps/plugins/test_codec.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-06-19 00:25:36 +0000
committerDave Chapman <dave@dchapman.com>2007-06-19 00:25:36 +0000
commitf01b661116f7fb469197deb5de6fbdbd5d3daee2 (patch)
treecd5a3a6da3a89d3e0ef1103caa86fde3ab306bcf /apps/plugins/test_codec.c
parent5b25a6e2dfaa4a336a5690935db5b7eadba971c5 (diff)
downloadrockbox-f01b661116f7fb469197deb5de6fbdbd5d3daee2.zip
rockbox-f01b661116f7fb469197deb5de6fbdbd5d3daee2.tar.gz
rockbox-f01b661116f7fb469197deb5de6fbdbd5d3daee2.tar.bz2
rockbox-f01b661116f7fb469197deb5de6fbdbd5d3daee2.tar.xz
Add a "Speed test folder" option for batch testing. When this option is selected, all files in the same directory as the selected file will be tested, and the results written to a numbered log file in the root. Thanks to Jens for his screen+file logging functions I stole from test_disk.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13670 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/test_codec.c')
-rw-r--r--apps/plugins/test_codec.c332
1 files changed, 224 insertions, 108 deletions
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index de3746b..446bffb 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -30,6 +30,52 @@ PLUGIN_HEADER
static struct plugin_api* rb;
+/* Log functions copied from test_disk.c */
+static int line = 0;
+static int max_line = 0;
+static int log_fd = -1;
+static char logfilename[MAX_PATH];
+
+static bool log_init(bool use_logfile)
+{
+ int h;
+
+ rb->lcd_setmargins(0, 0);
+ rb->lcd_getstringsize("A", NULL, &h);
+ max_line = LCD_HEIGHT / h;
+ line = 0;
+ rb->lcd_clear_display();
+ rb->lcd_update();
+
+ if (use_logfile) {
+ rb->create_numbered_filename(logfilename, "/", "test_codec_log_", ".txt",
+ 2 IF_CNFN_NUM_(, NULL));
+ log_fd = rb->open(logfilename, O_RDWR|O_CREAT|O_TRUNC);
+ return log_fd >= 0;
+ }
+
+ return true;
+}
+
+static void log_text(char *text, bool advance)
+{
+ rb->lcd_puts(0, line, text);
+ rb->lcd_update();
+ if (advance)
+ {
+ if (++line >= max_line)
+ line = 0;
+ if (log_fd >= 0)
+ rb->fdprintf(log_fd, "%s\n", text);
+ }
+}
+
+static void log_close(void)
+{
+ if (log_fd >= 0)
+ rb->close(log_fd);
+}
+
struct wavinfo_t
{
int fd;
@@ -43,7 +89,7 @@ struct wavinfo_t
static void* audiobuf;
static void* codec_mallocbuf;
static size_t audiosize;
-static char str[40];
+static char str[MAX_PATH];
/* Our local implementation of the codec API */
static struct codec_api ci;
@@ -149,6 +195,9 @@ static bool pcmbuf_insert_null(const void *ch1, const void *ch2, int count)
(void)ch2;
(void)count;
+ /* Prevent idle poweroff */
+ rb->reset_poweroff_timer();
+
return true;
}
@@ -174,6 +223,9 @@ static bool pcmbuf_insert_wav(const void *ch1, const void *ch2, int count)
unsigned char* p = wavbuffer;
int scale = wavinfo.sampledepth - 15;
+ /* Prevent idle poweroff */
+ rb->reset_poweroff_timer();
+
if (wavinfo.sampledepth <= 16) {
data1_16 = ch1;
data2_16 = ch2;
@@ -445,127 +497,63 @@ static void codec_thread(void)
rb->remove_thread(NULL);
}
-/* plugin entry point */
-enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+static unsigned char* codec_stack;
+static size_t codec_stack_size;
+
+static enum plugin_status test_track(char* filename)
{
size_t n;
int fd;
- int i;
enum plugin_status res = PLUGIN_OK;
unsigned long starttick;
unsigned long ticks;
unsigned long speed;
unsigned long duration;
- unsigned char* codec_stack;
- unsigned char* codec_stack_copy;
- size_t codec_stack_size;
struct thread_entry* codecthread_id;
- int result, selection = 0;
char* ch;
- int line = 0;
-
- rb = api;
-
- if (parameter == NULL)
- {
- rb->splash(HZ*2, "No File");
- return PLUGIN_ERROR;
- }
-
-#ifdef SIMULATOR
- /* The simulator thread implementation doesn't have stack buffers */
- (void)i;
- codec_stack_size = 0;
-#else
- /* Borrow the codec thread's stack (in IRAM on most targets) */
- codec_stack = NULL;
- for (i = 0; i < MAXTHREADS; i++)
- {
- if (rb->strcmp(rb->threads[i].name,"codec")==0)
- {
- codec_stack = rb->threads[i].stack;
- codec_stack_size = rb->threads[i].stack_size;
- break;
- }
- }
- if (codec_stack == NULL)
- {
- rb->splash(HZ*2, "No codec thread!");
- return PLUGIN_ERROR;
- }
-#endif
+ /* Display filename (excluding any path)*/
+ ch = rb->strrchr(filename, '/');
+ if (ch==NULL)
+ ch = filename;
+ else
+ ch++;
- codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
- codec_stack_copy = codec_mallocbuf + 512*1024;
- audiobuf = codec_stack_copy + codec_stack_size;
- audiosize -= 512*1024 + codec_stack_size;
+ rb->snprintf(str,sizeof(str),"%s",ch);
+ log_text(str,true);
-#ifndef SIMULATOR
- /* Backup the codec thread's stack */
- rb->memcpy(codec_stack_copy,codec_stack,codec_stack_size);
-#endif
+ log_text("Loading...",false);
- fd = rb->open(parameter,O_RDONLY);
+ fd = rb->open(filename,O_RDONLY);
if (fd < 0)
{
- rb->splash(HZ*2, "Cannot open file");
+ log_text("Cannot open file",true);
return PLUGIN_ERROR;
}
track.filesize = rb->filesize(fd);
- if (!rb->get_metadata(&track, fd, parameter,
+ /* Clear the id3 struct */
+ rb->memset(&track.id3, 0, sizeof(struct mp3entry));
+
+ if (!rb->get_metadata(&track, fd, filename,
rb->global_settings->id3_v1_first))
{
- rb->splash(HZ*2, "Cannot read metadata");
+ log_text("Cannot read metadata",true);
return PLUGIN_ERROR;
}
if (track.filesize > audiosize)
{
- rb->splash(HZ*2, "File too large");
+ log_text("File too large",true);
return PLUGIN_ERROR;
}
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(true);
-#endif
- rb->lcd_clear_display();
- rb->lcd_update();
-
- MENUITEM_STRINGLIST(menu,"test_codec",NULL,"Speed test","Write WAV");
-
- rb->lcd_clear_display();
-
- result=rb->do_menu(&menu,&selection);
-
- if (result==0) {
- wavinfo.fd = -1;
- } else if (result==1) {
- init_wav("/test.wav");
- if (wavinfo.fd < 0) {
- rb->splash(HZ*2, "Cannot create /test.wav");
- res = PLUGIN_ERROR;
- goto exit;
- }
- } else if (result == MENU_ATTACHED_USB) {
- res = PLUGIN_USB_CONNECTED;
- goto exit;
- } else if (result < 0) {
- res = PLUGIN_OK;
- goto exit;
- }
-
- rb->lcd_clear_display();
- rb->splash(0, "Loading...");
- rb->lcd_clear_display();
-
n = rb->read(fd, audiobuf, track.filesize);
if (n != track.filesize)
{
- rb->splash(HZ*2, "Read failed.");
+ log_text("Read failed.",true);
res = PLUGIN_ERROR;
goto exit;
}
@@ -590,44 +578,34 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
(uint8_t*)codec_stack, codec_stack_size, "testcodec" IF_PRIO(,PRIORITY_PLAYBACK)
IF_COP(, CPU, false))) == NULL)
{
- rb->splash(HZ, "Cannot create codec thread!");
+ log_text("Cannot create codec thread!",true);
goto exit;
}
- /* Display filename (excluding any path)*/
- ch = rb->strrchr(parameter, '/');
- if (ch==NULL)
- ch = parameter;
- else
- ch++;
-
- rb->snprintf(str,sizeof(str),"%s",ch);
- rb->lcd_puts(0,line++,str);
-
/* Wait for codec thread to die */
while (codec_playing)
{
rb->sleep(HZ);
rb->snprintf(str,sizeof(str),"%d of %d",elapsed,(int)track.id3.length);
- rb->lcd_puts(0,line,str);
- rb->lcd_update();
+ log_text(str,false);
}
- line++;
+ /* Save the current time before we spin up the disk to access the log */
+ ticks = *rb->current_tick - starttick;
+
+ log_text(str,true);
/* Close WAV file (if there was one) */
if (wavinfo.fd >= 0) {
close_wav();
- rb->lcd_puts(0,line++,"Wrote /test.wav");
+ log_text("Wrote /test.wav",true);
} else {
/* Display benchmark information */
-
- ticks = *rb->current_tick - starttick;
rb->snprintf(str,sizeof(str),"Decode time - %d.%02ds",(int)ticks/100,(int)ticks%100);
- rb->lcd_puts(0,line++,str);
+ log_text(str,true);
duration = track.id3.length / 10;
rb->snprintf(str,sizeof(str),"File duration - %d.%02ds",(int)duration/100,(int)duration%100);
- rb->lcd_puts(0,line++,str);
+ log_text(str,true);
if (ticks > 0)
speed = duration * 10000 / ticks;
@@ -635,14 +613,152 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
speed = 0;
rb->snprintf(str,sizeof(str),"%d.%02d%% realtime",(int)speed/100,(int)speed%100);
- rb->lcd_puts(0,line++,str);
+ log_text(str,true);
+ }
+
+ /* Write an empty line to the log */
+ log_text("",true);
+
+exit:
+ return res;
+}
+
+/* plugin entry point */
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+ unsigned char* codec_stack_copy;
+ int result, selection = 0;
+ enum plugin_status res = PLUGIN_OK;
+ int scandir;
+ int i;
+ struct dirent *entry;
+ DIR* dir;
+ char* ch;
+ char dirpath[MAX_PATH];
+ char filename[MAX_PATH];
+
+ rb = api;
+ if (parameter == NULL)
+ {
+ rb->splash(HZ*2, "No File");
+ return PLUGIN_ERROR;
+ }
+
+#ifdef SIMULATOR
+ /* The simulator thread implementation doesn't have stack buffers */
+ (void)i;
+ codec_stack_size = 0;
+#else
+ /* Borrow the codec thread's stack (in IRAM on most targets) */
+ codec_stack = NULL;
+ for (i = 0; i < MAXTHREADS; i++)
+ {
+ if (rb->strcmp(rb->threads[i].name,"codec")==0)
+ {
+ codec_stack = rb->threads[i].stack;
+ codec_stack_size = rb->threads[i].stack_size;
+ break;
+ }
+ }
+
+ if (codec_stack == NULL)
+ {
+ rb->splash(HZ*2, "No codec thread!");
+ return PLUGIN_ERROR;
}
+#endif
+
+ codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
+ codec_stack_copy = codec_mallocbuf + 512*1024;
+ audiobuf = codec_stack_copy + codec_stack_size;
+ audiosize -= 512*1024 + codec_stack_size;
+
+#ifndef SIMULATOR
+ /* Backup the codec thread's stack */
+ rb->memcpy(codec_stack_copy,codec_stack,codec_stack_size);
+#endif
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+#endif
+ rb->lcd_clear_display();
rb->lcd_update();
- while (rb->button_get(true) != TESTCODEC_EXITBUTTON);
+ MENUITEM_STRINGLIST(
+ menu, "test_codec", NULL,
+ "Speed test",
+ "Speed test folder",
+ "Write WAV",
+ );
+
+ rb->lcd_clear_display();
+
+ result=rb->do_menu(&menu,&selection);
+
+ scandir = 0;
+
+ if (result==0) {
+ wavinfo.fd = -1;
+ log_init(false);
+ } else if (result==1) {
+ wavinfo.fd = -1;
+ scandir = 1;
+
+ /* Only create a log file when we are testing a folder */
+ if (!log_init(true)) {
+ rb->splash(HZ*2, "Cannot create logfile");
+ res = PLUGIN_ERROR;
+ goto exit;
+ }
+ } else if (result==2) {
+ log_init(false);
+ init_wav("/test.wav");
+ if (wavinfo.fd < 0) {
+ rb->splash(HZ*2, "Cannot create /test.wav");
+ res = PLUGIN_ERROR;
+ goto exit;
+ }
+ } else if (result == MENU_ATTACHED_USB) {
+ res = PLUGIN_USB_CONNECTED;
+ goto exit;
+ } else if (result < 0) {
+ res = PLUGIN_OK;
+ goto exit;
+ }
+
+ if (scandir) {
+ /* Test all files in the same directory as the file selected by the
+ user */
+
+ rb->strncpy(dirpath,parameter,sizeof(dirpath));
+ ch = rb->strrchr(dirpath,'/');
+ ch[1]=0;
+
+ DEBUGF("Scanning directory \"%s\"\n",dirpath);
+ dir = rb->opendir(dirpath);
+ if (dir) {
+ entry = rb->readdir(dir);
+ while (entry) {
+ if (!(entry->attribute & ATTR_DIRECTORY)) {
+ rb->snprintf(filename,sizeof(filename),"%s%s",dirpath,entry->d_name);
+ test_track(filename);
+ }
+
+ /* Read next entry */
+ entry = rb->readdir(dir);
+ }
+ }
+ } else {
+ /* Just test the file */
+ res = test_track(parameter);
+
+ while (rb->button_get(true) != TESTCODEC_EXITBUTTON);
+ }
exit:
+ log_close();
+
#ifndef SIMULATOR
/* Restore the codec thread's stack */
rb->memcpy(codec_stack, codec_stack_copy, codec_stack_size);