diff options
author | Thomas Martitz <kugel@rockbox.org> | 2013-07-02 08:24:00 +0200 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2014-02-02 19:40:39 +0100 |
commit | dac40fdd60872da55b60ae9912b31e6549f1cf4a (patch) | |
tree | 76a0571260eb097d8936bd33edf15120dd2ef158 | |
parent | 57000b513bd54b9dba3b308b7734c88962b81ae3 (diff) | |
download | rockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.tar.gz rockbox-dac40fdd60872da55b60ae9912b31e6549f1cf4a.zip |
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.c | 64 | ||||
-rw-r--r-- | apps/talk.c | 61 | ||||
-rw-r--r-- | 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 @@ | |||
131 | #include "rds.h" | 131 | #include "rds.h" |
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | #include "talk.h" | ||
135 | |||
134 | /*---------------------------------------------------*/ | 136 | /*---------------------------------------------------*/ |
135 | /* SPECIAL DEBUG STUFF */ | 137 | /* SPECIAL DEBUG STUFF */ |
136 | /*---------------------------------------------------*/ | 138 | /*---------------------------------------------------*/ |
@@ -2130,6 +2132,67 @@ static bool dbg_scrollwheel(void) | |||
2130 | } | 2132 | } |
2131 | #endif | 2133 | #endif |
2132 | 2134 | ||
2135 | static const char* dbg_talk_get_name(int selected_item, void *data, | ||
2136 | char *buffer, size_t buffer_len) | ||
2137 | { | ||
2138 | struct talk_debug_data *talk_data = data; | ||
2139 | switch(selected_item) | ||
2140 | { | ||
2141 | case 0: | ||
2142 | if (talk_data) | ||
2143 | snprintf(buffer, buffer_len, "Current voice file: %s", | ||
2144 | talk_data->voicefile); | ||
2145 | else | ||
2146 | buffer = "No voice information available"; | ||
2147 | break; | ||
2148 | case 1: | ||
2149 | snprintf(buffer, buffer_len, "Number of (empty) clips in voice file: (%d) %d", | ||
2150 | talk_data->num_empty_clips, talk_data->num_clips); | ||
2151 | break; | ||
2152 | case 2: | ||
2153 | snprintf(buffer, buffer_len, "Min/Avg/Max size of clips: %d / %d / %d", | ||
2154 | talk_data->min_clipsize, talk_data->avg_clipsize, talk_data->max_clipsize); | ||
2155 | break; | ||
2156 | case 3: | ||
2157 | snprintf(buffer, buffer_len, "Memory allocated: %ld.%02ld KB", | ||
2158 | talk_data->memory_allocated / 1024, talk_data->memory_allocated % 1024); | ||
2159 | break; | ||
2160 | case 4: | ||
2161 | snprintf(buffer, buffer_len, "Memory used: %ld.%02ld KB", | ||
2162 | talk_data->memory_used / 1024, talk_data->memory_used % 1024); | ||
2163 | break; | ||
2164 | case 5: | ||
2165 | snprintf(buffer, buffer_len, "Number of clips in cache: %d", | ||
2166 | talk_data->cached_clips); | ||
2167 | break; | ||
2168 | case 6: | ||
2169 | snprintf(buffer, buffer_len, "Cache hits / misses: %d / %d", | ||
2170 | talk_data->cache_hits, talk_data->cache_misses); | ||
2171 | break; | ||
2172 | default: | ||
2173 | buffer = "TODO"; | ||
2174 | break; | ||
2175 | } | ||
2176 | |||
2177 | return buffer; | ||
2178 | } | ||
2179 | |||
2180 | static bool dbg_talk(void) | ||
2181 | { | ||
2182 | struct simplelist_info list; | ||
2183 | struct talk_debug_data data; | ||
2184 | if (talk_get_debug_data(&data)) | ||
2185 | simplelist_info_init(&list, "Voice Information:", 7, &data); | ||
2186 | else | ||
2187 | simplelist_info_init(&list, "Voice Information:", 1, NULL); | ||
2188 | list.scroll_all = true; | ||
2189 | list.hide_selection = true; | ||
2190 | list.timeout = HZ; | ||
2191 | list.get_name = dbg_talk_get_name; | ||
2192 | |||
2193 | return simplelist_show_list(&list); | ||
2194 | } | ||
2195 | |||
2133 | #ifdef HAVE_USBSTACK | 2196 | #ifdef HAVE_USBSTACK |
2134 | #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL) | 2197 | #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL) |
2135 | static bool toggle_usb_serial(void) | 2198 | static bool toggle_usb_serial(void) |
@@ -2361,6 +2424,7 @@ static const struct { | |||
2361 | && !defined(IPOD_MINI) && !defined(SIMULATOR)) | 2424 | && !defined(IPOD_MINI) && !defined(SIMULATOR)) |
2362 | {"Debug scrollwheel", dbg_scrollwheel }, | 2425 | {"Debug scrollwheel", dbg_scrollwheel }, |
2363 | #endif | 2426 | #endif |
2427 | {"Talk engine stats", dbg_talk }, | ||
2364 | }; | 2428 | }; |
2365 | 2429 | ||
2366 | static int menu_action_callback(int btn, struct gui_synclist *lists) | 2430 | 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]; | |||
123 | #if QUEUE_SIZE > 255 | 123 | #if QUEUE_SIZE > 255 |
124 | # error clip_age[] type too small | 124 | # error clip_age[] type too small |
125 | #endif | 125 | #endif |
126 | static int cache_hits, cache_misses; | ||
126 | #endif | 127 | #endif |
127 | 128 | ||
128 | /* Multiple thumbnails can be loaded back-to-back in this buffer. */ | 129 | /* Multiple thumbnails can be loaded back-to-back in this buffer. */ |
@@ -165,6 +166,7 @@ struct queue_entry /* one entry of the internal queue */ | |||
165 | 166 | ||
166 | static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ | 167 | static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ |
167 | 168 | ||
169 | #define DEFAULT_VOICE_LANG "english" | ||
168 | 170 | ||
169 | /***************** Private implementation *****************/ | 171 | /***************** Private implementation *****************/ |
170 | 172 | ||
@@ -294,7 +296,7 @@ static struct buflib_callbacks index_ops = { | |||
294 | static int open_voicefile(void) | 296 | static int open_voicefile(void) |
295 | { | 297 | { |
296 | char buf[64]; | 298 | char buf[64]; |
297 | char* p_lang = "english"; /* default */ | 299 | char* p_lang = DEFAULT_VOICE_LANG; /* default */ |
298 | 300 | ||
299 | if ( global_settings.lang_file[0] && | 301 | if ( global_settings.lang_file[0] && |
300 | global_settings.lang_file[0] != 0xff ) | 302 | global_settings.lang_file[0] != 0xff ) |
@@ -344,6 +346,7 @@ static int get_clip(long id, long* p_size) | |||
344 | ssize_t ret; | 346 | ssize_t ret; |
345 | int fd, idx = 0; | 347 | int fd, idx = 0; |
346 | unsigned char *voicebuf; | 348 | unsigned char *voicebuf; |
349 | cache_misses++; | ||
347 | if (id == VOICE_PAUSE) { | 350 | if (id == VOICE_PAUSE) { |
348 | idx = QUEUE_SIZE; /* we keep VOICE_PAUSE loaded */ | 351 | idx = QUEUE_SIZE; /* we keep VOICE_PAUSE loaded */ |
349 | } else { | 352 | } else { |
@@ -397,6 +400,7 @@ static int get_clip(long id, long* p_size) | |||
397 | else | 400 | else |
398 | { /* clip is in memory already */ | 401 | { /* clip is in memory already */ |
399 | /* Find where it was loaded */ | 402 | /* Find where it was loaded */ |
403 | cache_hits++; | ||
400 | if (id == VOICE_PAUSE) { | 404 | if (id == VOICE_PAUSE) { |
401 | retval = QUEUE_SIZE * max_clipsize; | 405 | retval = QUEUE_SIZE * max_clipsize; |
402 | } else { | 406 | } else { |
@@ -583,7 +587,6 @@ load_err_free: | |||
583 | return false; | 587 | return false; |
584 | } | 588 | } |
585 | 589 | ||
586 | |||
587 | /* called in ISR context (on HWCODEC) if mp3 data got consumed */ | 590 | /* called in ISR context (on HWCODEC) if mp3 data got consumed */ |
588 | static void mp3_callback(const void** start, size_t* size) | 591 | static void mp3_callback(const void** start, size_t* size) |
589 | { | 592 | { |
@@ -1456,3 +1459,57 @@ void talk_time(const struct tm *tm, bool enqueue) | |||
1456 | } | 1459 | } |
1457 | 1460 | ||
1458 | #endif /* CONFIG_RTC */ | 1461 | #endif /* CONFIG_RTC */ |
1462 | |||
1463 | |||
1464 | bool talk_get_debug_data(struct talk_debug_data *data) | ||
1465 | { | ||
1466 | char* p_lang = DEFAULT_VOICE_LANG; /* default */ | ||
1467 | |||
1468 | memset(data, 0, sizeof(*data)); | ||
1469 | |||
1470 | if (!has_voicefile || index_handle <= 0) | ||
1471 | return false; | ||
1472 | |||
1473 | if (global_settings.lang_file[0] && global_settings.lang_file[0] != 0xff) | ||
1474 | p_lang = (char *)global_settings.lang_file; | ||
1475 | |||
1476 | struct clip_entry *clips = core_get_data(index_handle); | ||
1477 | #ifdef TALK_PARTIAL_LOAD | ||
1478 | int cached = 0; | ||
1479 | #endif | ||
1480 | int real_clips = 0; | ||
1481 | |||
1482 | strlcpy(data->voicefile, p_lang, sizeof(data->voicefile)); | ||
1483 | data->num_clips = voicefile.id1_max + voicefile.id2_max; | ||
1484 | data->avg_clipsize = data->max_clipsize = 0; | ||
1485 | data->min_clipsize = INT_MAX; | ||
1486 | for(int i = 0; i < data->num_clips; i++) | ||
1487 | { | ||
1488 | int size = clips[i].size & (~LOADED_MASK); | ||
1489 | if (!size) continue; | ||
1490 | real_clips += 1; | ||
1491 | if (size < data->min_clipsize) | ||
1492 | data->min_clipsize = size; | ||
1493 | if (size > data->max_clipsize) | ||
1494 | data->max_clipsize = size; | ||
1495 | data->avg_clipsize += size; | ||
1496 | #ifdef TALK_PARTIAL_LOAD | ||
1497 | if (clips[i].size & LOADED_MASK) | ||
1498 | cached++; | ||
1499 | #endif | ||
1500 | } | ||
1501 | data->avg_clipsize /= real_clips; | ||
1502 | data->num_empty_clips = data->num_clips - real_clips; | ||
1503 | data->memory_allocated = voicefile_size + size_for_thumbnail; | ||
1504 | data->memory_used = voicefile_size + thumbnail_buf_used; | ||
1505 | #ifdef TALK_PARTIAL_LOAD | ||
1506 | data->cached_clips = cached; | ||
1507 | data->cache_hits = cache_hits; | ||
1508 | data->cache_misses = cache_misses; | ||
1509 | #else | ||
1510 | data->cached_clips = real_clips; | ||
1511 | data->cache_hits = data->cache_misses = -1; | ||
1512 | #endif | ||
1513 | |||
1514 | return true; | ||
1515 | } | ||
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); | |||
162 | } \ | 162 | } \ |
163 | }while(0) | 163 | }while(0) |
164 | 164 | ||
165 | struct talk_debug_data { | ||
166 | char voicefile[32]; | ||
167 | long memory_allocated, memory_used; | ||
168 | int num_clips, num_empty_clips; | ||
169 | int min_clipsize, avg_clipsize, max_clipsize; | ||
170 | int cached_clips; | ||
171 | int cache_hits; | ||
172 | int cache_misses; | ||
173 | }; | ||
174 | |||
175 | bool talk_get_debug_data(struct talk_debug_data *data); | ||
176 | |||
165 | #endif /* __TALK_H__ */ | 177 | #endif /* __TALK_H__ */ |