summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-07-02 08:24:00 +0200
committerThomas Martitz <kugel@rockbox.org>2014-02-02 19:40:39 +0100
commitdac40fdd60872da55b60ae9912b31e6549f1cf4a (patch)
tree76a0571260eb097d8936bd33edf15120dd2ef158
parent57000b513bd54b9dba3b308b7734c88962b81ae3 (diff)
downloadrockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.zip
rockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.tar.gz
rockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.tar.bz2
rockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.tar.xz
talk: Add debug menu entry to view statistics about talk engine.
This engine includes voicefile, memory usage and cache hits/misses for TALK_PARTIAL_LOAD. Change-Id: I331981ddda39ea30c57b4b74504accb3c556c3b9
-rw-r--r--apps/debug_menu.c64
-rw-r--r--apps/talk.c61
-rw-r--r--apps/talk.h12
3 files changed, 135 insertions, 2 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 6f7de6d..7c39935 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -131,6 +131,8 @@
#include "rds.h"
#endif
+#include "talk.h"
+
/*---------------------------------------------------*/
/* SPECIAL DEBUG STUFF */
/*---------------------------------------------------*/
@@ -2130,6 +2132,67 @@ static bool dbg_scrollwheel(void)
}
#endif
+static const char* dbg_talk_get_name(int selected_item, void *data,
+ char *buffer, size_t buffer_len)
+{
+ struct talk_debug_data *talk_data = data;
+ switch(selected_item)
+ {
+ case 0:
+ if (talk_data)
+ snprintf(buffer, buffer_len, "Current voice file: %s",
+ talk_data->voicefile);
+ else
+ buffer = "No voice information available";
+ break;
+ case 1:
+ snprintf(buffer, buffer_len, "Number of (empty) clips in voice file: (%d) %d",
+ talk_data->num_empty_clips, talk_data->num_clips);
+ break;
+ case 2:
+ snprintf(buffer, buffer_len, "Min/Avg/Max size of clips: %d / %d / %d",
+ talk_data->min_clipsize, talk_data->avg_clipsize, talk_data->max_clipsize);
+ break;
+ case 3:
+ snprintf(buffer, buffer_len, "Memory allocated: %ld.%02ld KB",
+ talk_data->memory_allocated / 1024, talk_data->memory_allocated % 1024);
+ break;
+ case 4:
+ snprintf(buffer, buffer_len, "Memory used: %ld.%02ld KB",
+ talk_data->memory_used / 1024, talk_data->memory_used % 1024);
+ break;
+ case 5:
+ snprintf(buffer, buffer_len, "Number of clips in cache: %d",
+ talk_data->cached_clips);
+ break;
+ case 6:
+ snprintf(buffer, buffer_len, "Cache hits / misses: %d / %d",
+ talk_data->cache_hits, talk_data->cache_misses);
+ break;
+ default:
+ buffer = "TODO";
+ break;
+ }
+
+ return buffer;
+}
+
+static bool dbg_talk(void)
+{
+ struct simplelist_info list;
+ struct talk_debug_data data;
+ if (talk_get_debug_data(&data))
+ simplelist_info_init(&list, "Voice Information:", 7, &data);
+ else
+ simplelist_info_init(&list, "Voice Information:", 1, NULL);
+ list.scroll_all = true;
+ list.hide_selection = true;
+ list.timeout = HZ;
+ list.get_name = dbg_talk_get_name;
+
+ return simplelist_show_list(&list);
+}
+
#ifdef HAVE_USBSTACK
#if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
static bool toggle_usb_serial(void)
@@ -2361,6 +2424,7 @@ static const struct {
&& !defined(IPOD_MINI) && !defined(SIMULATOR))
{"Debug scrollwheel", dbg_scrollwheel },
#endif
+ {"Talk engine stats", dbg_talk },
};
static int menu_action_callback(int btn, struct gui_synclist *lists)
diff --git a/apps/talk.c b/apps/talk.c
index 88d9afa..0904e41 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -123,6 +123,7 @@ static uint8_t clip_age[QUEUE_SIZE];
#if QUEUE_SIZE > 255
# error clip_age[] type too small
#endif
+static int cache_hits, cache_misses;
#endif
/* Multiple thumbnails can be loaded back-to-back in this buffer. */
@@ -165,6 +166,7 @@ struct queue_entry /* one entry of the internal queue */
static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */
+#define DEFAULT_VOICE_LANG "english"
/***************** Private implementation *****************/
@@ -294,7 +296,7 @@ static struct buflib_callbacks index_ops = {
static int open_voicefile(void)
{
char buf[64];
- char* p_lang = "english"; /* default */
+ char* p_lang = DEFAULT_VOICE_LANG; /* default */
if ( global_settings.lang_file[0] &&
global_settings.lang_file[0] != 0xff )
@@ -344,6 +346,7 @@ static int get_clip(long id, long* p_size)
ssize_t ret;
int fd, idx = 0;
unsigned char *voicebuf;
+ cache_misses++;
if (id == VOICE_PAUSE) {
idx = QUEUE_SIZE; /* we keep VOICE_PAUSE loaded */
} else {
@@ -397,6 +400,7 @@ static int get_clip(long id, long* p_size)
else
{ /* clip is in memory already */
/* Find where it was loaded */
+ cache_hits++;
if (id == VOICE_PAUSE) {
retval = QUEUE_SIZE * max_clipsize;
} else {
@@ -583,7 +587,6 @@ load_err_free:
return false;
}
-
/* called in ISR context (on HWCODEC) if mp3 data got consumed */
static void mp3_callback(const void** start, size_t* size)
{
@@ -1456,3 +1459,57 @@ void talk_time(const struct tm *tm, bool enqueue)
}
#endif /* CONFIG_RTC */
+
+
+bool talk_get_debug_data(struct talk_debug_data *data)
+{
+ char* p_lang = DEFAULT_VOICE_LANG; /* default */
+
+ memset(data, 0, sizeof(*data));
+
+ if (!has_voicefile || index_handle <= 0)
+ return false;
+
+ if (global_settings.lang_file[0] && global_settings.lang_file[0] != 0xff)
+ p_lang = (char *)global_settings.lang_file;
+
+ struct clip_entry *clips = core_get_data(index_handle);
+#ifdef TALK_PARTIAL_LOAD
+ int cached = 0;
+#endif
+ int real_clips = 0;
+
+ strlcpy(data->voicefile, p_lang, sizeof(data->voicefile));
+ data->num_clips = voicefile.id1_max + voicefile.id2_max;
+ data->avg_clipsize = data->max_clipsize = 0;
+ data->min_clipsize = INT_MAX;
+ for(int i = 0; i < data->num_clips; i++)
+ {
+ int size = clips[i].size & (~LOADED_MASK);
+ if (!size) continue;
+ real_clips += 1;
+ if (size < data->min_clipsize)
+ data->min_clipsize = size;
+ if (size > data->max_clipsize)
+ data->max_clipsize = size;
+ data->avg_clipsize += size;
+#ifdef TALK_PARTIAL_LOAD
+ if (clips[i].size & LOADED_MASK)
+ cached++;
+#endif
+ }
+ data->avg_clipsize /= real_clips;
+ data->num_empty_clips = data->num_clips - real_clips;
+ data->memory_allocated = voicefile_size + size_for_thumbnail;
+ data->memory_used = voicefile_size + thumbnail_buf_used;
+#ifdef TALK_PARTIAL_LOAD
+ data->cached_clips = cached;
+ data->cache_hits = cache_hits;
+ data->cache_misses = cache_misses;
+#else
+ data->cached_clips = real_clips;
+ data->cache_hits = data->cache_misses = -1;
+#endif
+
+ return true;
+}
diff --git a/apps/talk.h b/apps/talk.h
index 4da3a61..5ffc9ae 100644
--- a/apps/talk.h
+++ b/apps/talk.h
@@ -162,4 +162,16 @@ int talk_idarray(const long *idarray, bool enqueue);
} \
}while(0)
+struct talk_debug_data {
+ char voicefile[32];
+ long memory_allocated, memory_used;
+ int num_clips, num_empty_clips;
+ int min_clipsize, avg_clipsize, max_clipsize;
+ int cached_clips;
+ int cache_hits;
+ int cache_misses;
+};
+
+bool talk_get_debug_data(struct talk_debug_data *data);
+
#endif /* __TALK_H__ */