diff options
author | Nils Wallménius <nils@rockbox.org> | 2007-08-06 13:08:36 +0000 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2007-08-06 13:08:36 +0000 |
commit | 5b76936a44de3c7ecd568300f26b5e6421901285 (patch) | |
tree | 504d9cf371d8f64c70a7bb40469a3a6f05a1b7cd /apps/talk.c | |
parent | d755c283caef258ae5d81278d324f907fcf402c8 (diff) | |
download | rockbox-5b76936a44de3c7ecd568300f26b5e6421901285.tar.gz rockbox-5b76936a44de3c7ecd568300f26b5e6421901285.zip |
Accept FS#6159 'Add voice to roughly 100 splash screens and yes-no menus' by Stephane Doyon with some minor tweaks by me. Rerun 'configure' and do a 'make clean' before rebuilding your voice files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14213 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/talk.c')
-rw-r--r-- | apps/talk.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/apps/talk.c b/apps/talk.c index 89ab3901c4..3b7ab2a03f 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -117,6 +117,8 @@ static long size_for_thumbnail; /* leftover buffer size for it */ | |||
117 | static struct voicefile* p_voicefile; /* loaded voicefile */ | 117 | static struct voicefile* p_voicefile; /* loaded voicefile */ |
118 | static bool has_voicefile; /* a voicefile file is present */ | 118 | static bool has_voicefile; /* a voicefile file is present */ |
119 | static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ | 119 | static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ |
120 | /* enqueue next utterance even if enqueue is false. */ | ||
121 | static bool force_enqueue_next; | ||
120 | static int queue_write; /* write index of queue, by application */ | 122 | static int queue_write; /* write index of queue, by application */ |
121 | static int queue_read; /* read index of queue, by ISR context */ | 123 | static int queue_read; /* read index of queue, by ISR context */ |
122 | static int sent; /* how many bytes handed over to playback, owned by ISR */ | 124 | static int sent; /* how many bytes handed over to playback, owned by ISR */ |
@@ -134,7 +136,6 @@ static int talk_menu_disable; /* if non-zero, temporarily disable voice UI (not | |||
134 | 136 | ||
135 | static void load_voicefile(void); | 137 | static void load_voicefile(void); |
136 | static void mp3_callback(unsigned char** start, size_t* size); | 138 | static void mp3_callback(unsigned char** start, size_t* size); |
137 | static int shutup(void); | ||
138 | static int queue_clip(unsigned char* buf, long size, bool enqueue); | 139 | static int queue_clip(unsigned char* buf, long size, bool enqueue); |
139 | static int open_voicefile(void); | 140 | static int open_voicefile(void); |
140 | static unsigned char* get_clip(long id, long* p_size); | 141 | static unsigned char* get_clip(long id, long* p_size); |
@@ -267,6 +268,13 @@ load_err: | |||
267 | } | 268 | } |
268 | 269 | ||
269 | 270 | ||
271 | /* Are more voice clips queued and waiting? */ | ||
272 | bool is_voice_queued() | ||
273 | { | ||
274 | return !!QUEUE_LEVEL; | ||
275 | } | ||
276 | |||
277 | |||
270 | /* called in ISR context if mp3 data got consumed */ | 278 | /* called in ISR context if mp3 data got consumed */ |
271 | static void mp3_callback(unsigned char** start, size_t* size) | 279 | static void mp3_callback(unsigned char** start, size_t* size) |
272 | { | 280 | { |
@@ -321,7 +329,7 @@ re_check: | |||
321 | } | 329 | } |
322 | 330 | ||
323 | /* stop the playback and the pending clips */ | 331 | /* stop the playback and the pending clips */ |
324 | static int shutup(void) | 332 | static int do_shutup(void) |
325 | { | 333 | { |
326 | #if CONFIG_CODEC != SWCODEC | 334 | #if CONFIG_CODEC != SWCODEC |
327 | unsigned char* pos; | 335 | unsigned char* pos; |
@@ -387,6 +395,13 @@ static int shutup(void) | |||
387 | return 0; | 395 | return 0; |
388 | } | 396 | } |
389 | 397 | ||
398 | /* Shutup the voice, except if force_enqueue_next is set. */ | ||
399 | static int shutup(void) | ||
400 | { | ||
401 | if (!force_enqueue_next) | ||
402 | return do_shutup(); | ||
403 | return 0; | ||
404 | } | ||
390 | 405 | ||
391 | /* schedule a clip, at the end or discard the existing queue */ | 406 | /* schedule a clip, at the end or discard the existing queue */ |
392 | static int queue_clip(unsigned char* buf, long size, bool enqueue) | 407 | static int queue_clip(unsigned char* buf, long size, bool enqueue) |
@@ -395,6 +410,9 @@ static int queue_clip(unsigned char* buf, long size, bool enqueue) | |||
395 | 410 | ||
396 | if (!enqueue) | 411 | if (!enqueue) |
397 | shutup(); /* cut off all the pending stuff */ | 412 | shutup(); /* cut off all the pending stuff */ |
413 | /* Something is being enqueued, force_enqueue_next override is no | ||
414 | longer in effect. */ | ||
415 | force_enqueue_next = false; | ||
398 | 416 | ||
399 | if (!size) | 417 | if (!size) |
400 | return 0; /* safety check */ | 418 | return 0; /* safety check */ |
@@ -617,6 +635,26 @@ int talk_id(long id, bool enqueue) | |||
617 | return 0; | 635 | return 0; |
618 | } | 636 | } |
619 | 637 | ||
638 | /* Speaks zero or more IDs (from an array). */ | ||
639 | int talk_idarray(long *ids, bool enqueue) | ||
640 | { | ||
641 | int r; | ||
642 | if(!ids) | ||
643 | return 0; | ||
644 | while(*ids != TALK_FINAL_ID) | ||
645 | { | ||
646 | if((r = talk_id(*ids++, enqueue)) <0) | ||
647 | return r; | ||
648 | enqueue = true; | ||
649 | } | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | /* Make sure the current utterance is not interrupted by the next one. */ | ||
654 | void talk_force_enqueue_next(void) | ||
655 | { | ||
656 | force_enqueue_next = true; | ||
657 | } | ||
620 | 658 | ||
621 | /* play a thumbnail from file */ | 659 | /* play a thumbnail from file */ |
622 | int talk_file(const char* filename, bool enqueue) | 660 | int talk_file(const char* filename, bool enqueue) |