From dac40fdd60872da55b60ae9912b31e6549f1cf4a Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Tue, 2 Jul 2013 08:24:00 +0200 Subject: 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 --- apps/debug_menu.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/talk.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- apps/talk.h | 12 +++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 6f7de6d54e..7c399350b2 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 88d9afab90..0904e41c3b 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 4da3a61f3b..5ffc9ae5e6 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__ */ -- cgit v1.2.3