summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-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 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
2135static 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
2180static 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)
2135static bool toggle_usb_serial(void) 2198static 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
2366static int menu_action_callback(int btn, struct gui_synclist *lists) 2430static 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
126static 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
166static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ 167static 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 = {
294static int open_voicefile(void) 296static 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 */
588static void mp3_callback(const void** start, size_t* size) 591static 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
1464bool 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
165struct 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
175bool talk_get_debug_data(struct talk_debug_data *data);
176
165#endif /* __TALK_H__ */ 177#endif /* __TALK_H__ */