Index: rockbox-devel/apps/talk.h =================================================================== --- rockbox-devel.orig/apps/talk.h +++ rockbox-devel/apps/talk.h @@ -63,10 +63,46 @@ void talk_init(void); bool talk_voice_required(void); /* returns true if voice codec required */ int talk_get_bufsize(void); /* get the loaded voice file size */ int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ +int shutup(void); /* Interrupt voice, as when enqueue is false. */ +int do_shutup(void); /* kill voice unconditionally */ +bool is_voice_queued(void); /* Are there more voice clips to be spoken? */ int talk_id(long id, bool enqueue); /* play a voice ID from voicefont */ int talk_file(const char* filename, bool enqueue); /* play a thumbnail from file */ int talk_number(long n, bool enqueue); /* say a number */ int talk_value(long n, int unit, bool enqueue); /* say a numeric value */ int talk_spell(const char* spell, bool enqueue); /* spell a string */ +/* Enqueue next utterance even if enqueue parameter is false: don't + interrupt the current utterance. */ +void talk_force_enqueue_next(void); + +/* speaks one or more IDs (from an array)). */ +int talk_idarray(long *idarray, bool enqueue); +/* This (otherwise invalid) ID signals the end of the array. */ +#define TALK_FINAL_ID LANG_LAST_INDEX_IN_ARRAY +/* This makes an initializer for the array of IDs and takes care to + put the final sentinel element at the end. */ +#define TALK_IDARRAY(ids...) ((long[]){ids,TALK_FINAL_ID}) +/* And this handy macro makes it look like a variadic function. */ +#define talk_ids(enqueue, ids...) talk_idarray(TALK_IDARRAY(ids), enqueue) +/* This version talks only if talking menus are enabled, and does not + enqueue the initial id. */ +#define cond_talk_ids(ids...) do { \ + if (global_settings.talk_menu) \ + talk_ids(false, ids); \ + } while(0) +/* And a version that takes the array parameter... */ +#define cond_talk_idarray(idarray) do { \ + if (global_settings.talk_menu) \ + talk_idarray(idarray, false); \ + } while(0) +/* Convenience macro to conditionally speak something and not have + it interrupted. */ +#define cond_talk_ids_fq(ids...) do { \ + if (global_settings.talk_menu) { \ + talk_ids(false, ids); \ + talk_force_enqueue_next(); \ + } \ + }while(0) + #endif /* __TALK_H__ */ Index: rockbox-devel/apps/talk.c =================================================================== --- rockbox-devel.orig/apps/talk.c +++ rockbox-devel/apps/talk.c @@ -111,6 +111,8 @@ static long size_for_thumbnail; /* lefto static struct voicefile* p_voicefile; /* loaded voicefile */ static bool has_voicefile; /* a voicefile file is present */ static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ +/* enqueue next utterance even if enqueue is false. */ +static bool force_enqueue_next; static int queue_write; /* write index of queue, by application */ static int queue_read; /* read index of queue, by ISR context */ static int sent; /* how many bytes handed over to playback, owned by ISR */ @@ -127,7 +129,6 @@ static bool talk_initialized; /* true if static void load_voicefile(void); static void mp3_callback(unsigned char** start, int* size); -static int shutup(void); static int queue_clip(unsigned char* buf, long size, bool enqueue); static int open_voicefile(void); static unsigned char* get_clip(long id, long* p_size); @@ -265,6 +266,13 @@ load_err: } +/* Are more voice clips queued and waiting? */ +bool is_voice_queued() +{ + return !!QUEUE_LEVEL; +} + + /* called in ISR context if mp3 data got consumed */ static void mp3_callback(unsigned char** start, int* size) { @@ -319,7 +327,7 @@ re_check: } /* stop the playback and the pending clips */ -static int shutup(void) +int do_shutup(void) { #if CONFIG_CODEC != SWCODEC unsigned char* pos; @@ -385,6 +393,13 @@ static int shutup(void) return 0; } +/* Shutup the voice, except if force_enqueue_next is set. */ +int shutup(void) +{ + if (!force_enqueue_next) + return do_shutup(); + return 0; +} /* schedule a clip, at the end or discard the existing queue */ static int queue_clip(unsigned char* buf, long size, bool enqueue) @@ -393,6 +408,9 @@ static int queue_clip(unsigned char* buf if (!enqueue) shutup(); /* cut off all the pending stuff */ + /* Something is being enqueued, force_enqueue_next override is no + longer in effect. */ + force_enqueue_next = false; if (!size) return 0; /* safety check */ @@ -613,6 +631,26 @@ int talk_id(long id, bool enqueue) return 0; } +/* Speaks zero or more IDs (from an array). */ +int talk_idarray(long *ids, bool enqueue) +{ + int r; + if(!ids) + return 0; + while(*ids != TALK_FINAL_ID) + { + if((r = talk_id(*ids++, enqueue)) <0) + return r; + enqueue = true; + } + return 0; +} + +/* Make sure the current utterance is not interrupted by the next one. */ +void talk_force_enqueue_next(void) +{ + force_enqueue_next = true; +} /* play a thumbnail from file */ int talk_file(const char* filename, bool enqueue) Index: rockbox-devel/apps/gui/splash.c =================================================================== --- rockbox-devel.orig/apps/gui/splash.c +++ rockbox-devel/apps/gui/splash.c @@ -22,6 +22,9 @@ #include "stdio.h" #include "kernel.h" #include "screen_access.h" +#include "lang.h" +#include "settings.h" +#include "talk.h" #ifndef MAX #define MAX(a, b) (((a)>(b))?(a):(b)) @@ -211,6 +214,15 @@ void gui_syncsplash(int ticks, bool cent { va_list ap; int i; + long id; + /* fmt may be a so called virtual pointer. See settings.h. */ + if((id = P2ID(fmt)) >= 0) + /* If fmt specifies a voicefont ID, and voice menus are + enabled, then speak it. */ + cond_talk_ids_fq(id); + /* If fmt is a lang ID then get the corresponding string (which + still might contain % place holders). */ + fmt = P2STR(fmt); va_start( ap, fmt ); FOR_NB_SCREENS(i) splash(&(screens[i]), center, fmt, ap); Index: rockbox-devel/apps/gui/yesno.c =================================================================== --- rockbox-devel.orig/apps/gui/yesno.c +++ rockbox-devel/apps/gui/yesno.c @@ -4,6 +4,7 @@ #include "misc.h" #include "lang.h" #include "action.h" +#include "talk.h" void gui_yesno_init(struct gui_yesno * yn, struct text_message * main_message, @@ -55,7 +56,28 @@ bool gui_yesno_draw_result(struct gui_ye gui_textarea_put_message(yn->display, message, 0); return(true); } + #include "debug.h" + +/* Processes a text_message whose lines may be virtual pointers + representing language / voicefont IDs (see settings.h). Copies out + the IDs to the ids array, which is of length maxlen, and replaces + the pointers in the text_message with the actual language strings. + The ids array is terminated with the TALK_FINAL_ID sentinel + element. */ +static void extract_talk_ids(struct text_message *m, long *ids, int maxlen) +{ + int line, i=0; + if(m) + for(line=0; linenb_lines; line++) { + long id = P2ID((unsigned char *)m->message_lines[line]); + if(id>=0 && imessage_lines[line] = (char *)P2STR((unsigned char *)m->message_lines[line]); + } + ids[i] = TALK_FINAL_ID; +} + enum yesno_res gui_syncyesno_run(struct text_message * main_message, struct text_message * yes_message, struct text_message * no_message) @@ -65,6 +87,13 @@ enum yesno_res gui_syncyesno_run(struct int result=-1; bool result_displayed; struct gui_yesno yn[NB_SCREENS]; + long voice_ids[5]; + long talked_tick = 0; + /* The text messages may contain virtual pointers to IDs (see + settings.h) instead of plain strings. Copy the IDs out so we + can speak them, and unwrap the actual language strings. */ + extract_talk_ids(main_message, voice_ids, + sizeof(voice_ids)/sizeof(voice_ids[0])); FOR_NB_SCREENS(i) { gui_yesno_init(&(yn[i]), main_message, yes_message, no_message); @@ -74,7 +103,14 @@ enum yesno_res gui_syncyesno_run(struct action_signalscreenchange(); while (result==-1) { - button = get_action(CONTEXT_YESNOSCREEN,TIMEOUT_BLOCK); + /* Repeat the question every 5secs (more or less) */ + if (global_settings.talk_menu + && (talked_tick==0 || TIME_AFTER(current_tick, talked_tick+HZ*5))) + { + talked_tick = current_tick; + talk_idarray(voice_ids, false); + } + button = get_action(CONTEXT_YESNOSCREEN, HZ*5); switch (button) { case ACTION_YESNO_ACCEPT: @@ -91,6 +127,13 @@ enum yesno_res gui_syncyesno_run(struct action_signalscreenchange(); FOR_NB_SCREENS(i) result_displayed=gui_yesno_draw_result(&(yn[i]), result); + extract_talk_ids((result == YESNO_YES) ? yes_message : no_message, + voice_ids, sizeof(voice_ids)/sizeof(voice_ids[0])); + if (global_settings.talk_menu) + { + talk_idarray(voice_ids, false); + talk_force_enqueue_next(); + } if(result_displayed) sleep(HZ); return(result); Index: rockbox-devel/apps/playback.h =================================================================== --- rockbox-devel.orig/apps/playback.h +++ rockbox-devel/apps/playback.h @@ -66,6 +66,8 @@ void audio_set_track_unbuffer_event(void bool last_track)); void voice_init(void); void voice_stop(void); +bool is_voice_speaking(void); +void voice_wait(void); #if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */ extern void audio_next_dir(void); Index: rockbox-devel/apps/playback.c =================================================================== --- rockbox-devel.orig/apps/playback.c +++ rockbox-devel/apps/playback.c @@ -814,7 +814,22 @@ void voice_stop(void) #endif } /* voice_stop */ +/* Is voice still speaking */ +/* Unfortunately only reliable when music is not also playing. */ +bool is_voice_speaking(void) +{ + return is_voice_queued() + || voice_is_playing + || (!playing && pcm_is_playing()); +} +/* Wait for voice to finish speaking. */ +/* Also only reliable when music is not also playing. */ +void voice_wait(void) +{ + while (is_voice_speaking()) + sleep(1); +} /* --- Routines called from multiple threads --- */ Index: rockbox-devel/apps/lang/english.lang =================================================================== --- rockbox-devel.orig/apps/lang/english.lang +++ rockbox-devel/apps/lang/english.lang @@ -152,7 +152,7 @@ *: "Shutting down..." - *: "" + *: "Shutting down" @@ -194,7 +194,7 @@ *: "Cancelled" - *: "" + *: "Canceled" @@ -208,7 +208,7 @@ *: "Failed" - *: "" + *: "Failed" @@ -852,7 +852,7 @@ *: "Are You Sure?" - *: "" + *: "Are You Sure?" @@ -910,7 +910,7 @@ *: "Cleared" - *: "" + *: "Settings cleared" @@ -924,7 +924,7 @@ *: "Cancelled" - *: "" + *: "Canceled" @@ -980,7 +980,7 @@ *: "Save Failed" - *: "" + *: "Save Failed" @@ -1166,17 +1166,17 @@ - id: LANG_EQUALIZER_BAND_PEAK + id: LANG_EQUALIZER_BAND_PEAK1 desc: in the equalizer settings menu user: - *: "Peak Filter %d" + *: "Peak Filter 1" - *: "Peak Filter %d" + *: "Peak Filter 1" - *: "Peak filter" + *: "Peak filter 1" @@ -1750,7 +1750,7 @@ *: "Updating in background" - *: "" + *: "Updating in background" @@ -3878,7 +3878,7 @@ *: "" - *: "" + *: "Please reboot to enable the cache" @@ -4116,7 +4116,7 @@ *: "File/directory exists. Overwrite?" - *: "" + *: "File or directory exists. Overwrite?" @@ -4172,7 +4172,7 @@ *: "Delete?" - *: "" + *: "Really delete?" @@ -4186,7 +4186,7 @@ *: "Deleted" - *: "" + *: "Deleted" @@ -4808,7 +4808,7 @@ *: "Load Last Bookmark?" - *: "" + *: "Load Last Bookmark?" @@ -4822,7 +4822,7 @@ *: "Create a Bookmark?" - *: "" + *: "Create a Bookmark?" @@ -4836,7 +4836,7 @@ *: "Bookmark Created" - *: "" + *: "Bookmark Created" @@ -4850,7 +4850,7 @@ *: "Bookmark Failed!" - *: "" + *: "Bookmark Failed!" @@ -4864,7 +4864,7 @@ *: "Bookmark Empty" - *: "" + *: "Bookmark Empty" @@ -7222,7 +7222,7 @@ *: "Playlist Buffer Full" - *: "" + *: "Playlist Buffer Full" @@ -7250,7 +7250,7 @@ *: "End of Song List" - *: "" + *: "End of Song List" @@ -7278,7 +7278,7 @@ *: "Inserted %d tracks (%s)" - *: "" + *: "Inserted tracks so far" @@ -7292,7 +7292,7 @@ *: "Queued %d tracks (%s)" - *: "" + *: "Queued tracks so far" @@ -7306,7 +7306,7 @@ *: "Saved %d tracks (%s)" - *: "" + *: "Tracks saved" @@ -7320,7 +7320,7 @@ *: "Recursively?" - *: "" + *: "Recursively?" @@ -7334,7 +7334,7 @@ *: "Erase dynamic playlist?" - *: "" + *: "Erase dynamic playlist?" @@ -7348,7 +7348,7 @@ *: "Nothing to resume" - *: "" + *: "Nothing to resume" @@ -7362,7 +7362,7 @@ *: "Error updating playlist control file" - *: "" + *: "Error updating playlist control file" @@ -7376,7 +7376,7 @@ *: "Error accessing playlist file" - *: "" + *: "Error accessing playlist file" @@ -7390,7 +7390,7 @@ *: "Error accessing playlist control file" - *: "" + *: "Error accessing playlist control file" @@ -7404,7 +7404,7 @@ *: "Error accessing directory" - *: "" + *: "Error accessing directory" @@ -7418,7 +7418,7 @@ *: "Playlist control file is invalid" - *: "" + *: "Playlist control file is invalid" @@ -7782,7 +7782,7 @@ *: "Dir Buffer is Full!" - *: "" + *: "Directory Buffer is Full!" @@ -7796,7 +7796,7 @@ *: "New Language" - *: "" + *: "New Language" @@ -7810,7 +7810,7 @@ *: "Settings Loaded" - *: "" + *: "Settings Loaded" @@ -7824,7 +7824,7 @@ *: "Settings Saved" - *: "" + *: "Settings Saved" @@ -7896,7 +7896,7 @@ *: "No files" - *: "" + *: "No files" @@ -7938,7 +7938,7 @@ *: "New Keyboard" - *: "" + *: "New Keyboard" @@ -8064,7 +8064,7 @@ *: "Found %d matches" - *: "" + *: "Matches" @@ -8106,7 +8106,7 @@ *: "Move Failed" - *: "" + *: "Move Failed" @@ -8274,7 +8274,7 @@ *: "Extension array full" - *: "" + *: "Extension array full" @@ -8288,7 +8288,7 @@ *: "Filetype array full" - *: "" + *: "Filetype array full" @@ -8302,7 +8302,7 @@ *: "Plugin name too long" - *: "" + *: "Plugin name too long" @@ -8316,7 +8316,7 @@ *: "Filetype string buffer empty" - *: "" + *: "Filetype string buffer empty" @@ -8661,7 +8661,7 @@ *: "%s doesn't exist" - *: "" + *: "Playlist directory doesn't exist" @@ -8675,7 +8675,7 @@ *: "No playlists" - *: "" + *: "No playlists" @@ -10207,7 +10207,7 @@ *: "WARNING! Low Battery!" - *: "" + *: "WARNING! Low Battery!" @@ -10221,6 +10221,34 @@ *: "Battery empty! RECHARGE!" - *: "" + *: "Battery empty! RECHARGE!" + + + + id: LANG_EQUALIZER_BAND_PEAK2 + desc: in the equalizer settings menu + user: + + *: "Peak Filter 2" + + + *: "Peak Filter 2" + + + *: "Peak filter 2" + + + + id: LANG_EQUALIZER_BAND_PEAK3 + desc: in the equalizer settings menu + user: + + *: "Peak Filter 3" + + + *: "Peak Filter 3" + + + *: "Peak filter 3" Index: rockbox-devel/apps/bookmark.c =================================================================== --- rockbox-devel.orig/apps/bookmark.c +++ rockbox-devel/apps/bookmark.c @@ -211,10 +211,10 @@ bool bookmark_autobookmark(void) return write_bookmark(false); } #ifdef HAVE_LCD_BITMAP - unsigned char *lines[]={str(LANG_AUTO_BOOKMARK_QUERY)}; + unsigned char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)}; struct text_message message={(char **)lines, 1}; #else - unsigned char *lines[]={str(LANG_AUTO_BOOKMARK_QUERY), + unsigned char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY), str(LANG_RESUME_CONFIRM_PLAYER)}; struct text_message message={(char **)lines, 2}; #endif @@ -267,9 +267,9 @@ static bool write_bookmark(bool create_b } if (success) - gui_syncsplash(HZ, true, str(LANG_BOOKMARK_CREATE_SUCCESS)); + gui_syncsplash(HZ, true, ID2P(LANG_BOOKMARK_CREATE_SUCCESS)); else - gui_syncsplash(HZ, true, str(LANG_BOOKMARK_CREATE_FAILURE)); + gui_syncsplash(HZ, true, ID2P(LANG_BOOKMARK_CREATE_FAILURE)); return true; } @@ -453,6 +453,7 @@ bool bookmark_autoload(const char* file) screens[i].puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER)); #endif } + cond_talk_ids(LANG_BOOKMARK_AUTOLOAD_QUERY); /* Wait for a key to be pushed */ key = get_action(CONTEXT_BOOKMARKSCREEN,TIMEOUT_BLOCK); @@ -592,7 +593,7 @@ static char* select_bookmark(const char* /* if there were no bookmarks in the file, delete the file and exit. */ if(bookmark_id <= 0) { - gui_syncsplash(HZ, true, str(LANG_BOOKMARK_LOAD_EMPTY)); + gui_syncsplash(HZ, true, ID2P(LANG_BOOKMARK_LOAD_EMPTY)); remove(bookmark_file_name); action_signalscreenchange(); return NULL; Index: rockbox-devel/apps/filetree.c =================================================================== --- rockbox-devel.orig/apps/filetree.c +++ rockbox-devel/apps/filetree.c @@ -359,21 +359,21 @@ int ft_enter(struct tree_context* c) switch ( file->attr & TREE_ATTR_MASK ) { case TREE_ATTR_M3U: if (global_settings.party_mode) { - gui_syncsplash(HZ, true, str(LANG_PARTY_MODE)); + gui_syncsplash(HZ, true, ID2P(LANG_PARTY_MODE)); break; } if (bookmark_autoload(buf)) break; - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); /* about to create a new current playlist... allow user to cancel the operation */ if (global_settings.warnon_erase_dynplaylist && playlist_modified(NULL)) { - char *lines[]={str(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; + char *lines[]={ID2P(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; struct text_message message={lines, 1}; if(gui_syncyesno_run(&message, NULL, NULL) != YESNO_YES) @@ -394,7 +394,7 @@ int ft_enter(struct tree_context* c) if (bookmark_autoload(c->currdir)) break; - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); /* about to create a new current playlist... allow user to cancel the operation */ @@ -402,7 +402,7 @@ int ft_enter(struct tree_context* c) !global_settings.party_mode && playlist_modified(NULL)) { - char *lines[]={str(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; + char *lines[]={ID2P(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; struct text_message message={lines, 1}; if(gui_syncyesno_run(&message, NULL, NULL) != YESNO_YES) @@ -413,7 +413,7 @@ int ft_enter(struct tree_context* c) { playlist_insert_track(NULL, buf, PLAYLIST_INSERT_LAST, true, true); - gui_syncsplash(HZ, true, str(LANG_QUEUE_LAST)); + gui_syncsplash(HZ, true, ID2P(LANG_QUEUE_LAST)); } else if (playlist_create(c->currdir, NULL) != -1) { @@ -438,7 +438,7 @@ int ft_enter(struct tree_context* c) /* fmr preset file */ case TREE_ATTR_FMR: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); /* Preset inside the default folder. */ if(!strncasecmp(FMPRESET_PATH, buf, strlen(FMPRESET_PATH))) @@ -465,7 +465,7 @@ int ft_enter(struct tree_context* c) /* wps config file */ case TREE_ATTR_WPS: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); #if LCD_DEPTH > 1 unload_wps_backdrop(); #endif @@ -477,7 +477,7 @@ int ft_enter(struct tree_context* c) #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) /* remote-wps config file */ case TREE_ATTR_RWPS: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); wps_data_load(gui_wps[1].data, buf, true); set_file(buf, (char *)global_settings.rwps_file, MAX_FILENAME); @@ -485,39 +485,39 @@ int ft_enter(struct tree_context* c) #endif case TREE_ATTR_CFG: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if (!settings_load_config(buf)) break; - gui_syncsplash(HZ, true, str(LANG_SETTINGS_LOADED)); + gui_syncsplash(HZ, true, ID2P(LANG_SETTINGS_LOADED)); break; case TREE_ATTR_BMARK: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); bookmark_load(buf, false); reload_dir = true; break; case TREE_ATTR_LNG: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if(!lang_load(buf)) { set_file(buf, (char *)global_settings.lang_file, MAX_FILENAME); talk_init(); /* use voice of same language */ - gui_syncsplash(HZ, true, str(LANG_LANGUAGE_LOADED)); + gui_syncsplash(HZ, true, ID2P(LANG_LANGUAGE_LOADED)); } break; #ifdef HAVE_LCD_BITMAP case TREE_ATTR_FONT: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); font_load(buf); set_file(buf, (char *)global_settings.font_file, MAX_FILENAME); break; case TREE_ATTR_KBD: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if (!load_kbd(buf)) - gui_syncsplash(HZ, true, str(LANG_KEYBOARD_LOADED)); + gui_syncsplash(HZ, true, ID2P(LANG_KEYBOARD_LOADED)); set_file(buf, (char *)global_settings.kbd_file, MAX_FILENAME); break; #endif @@ -525,7 +525,7 @@ int ft_enter(struct tree_context* c) #ifndef SIMULATOR /* firmware file */ case TREE_ATTR_MOD: - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); rolo_load(buf); break; #endif @@ -533,11 +533,11 @@ int ft_enter(struct tree_context* c) /* plugin file */ case TREE_ATTR_ROCK: if (global_settings.party_mode) { - gui_syncsplash(HZ, true, str(LANG_PARTY_MODE)); + gui_syncsplash(HZ, true, ID2P(LANG_PARTY_MODE)); break; } - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if (plugin_load(buf,NULL) == PLUGIN_USB_CONNECTED) { @@ -555,7 +555,7 @@ int ft_enter(struct tree_context* c) char* plugin; if (global_settings.party_mode) { - gui_syncsplash(HZ, true, str(LANG_PARTY_MODE)); + gui_syncsplash(HZ, true, ID2P(LANG_PARTY_MODE)); break; } Index: rockbox-devel/apps/onplay.c =================================================================== --- rockbox-devel.orig/apps/onplay.c +++ rockbox-devel/apps/onplay.c @@ -169,12 +169,12 @@ static bool add_to_playlist(int position { bool new_playlist = !(audio_status() & AUDIO_STATUS_PLAY); char *lines[] = { - (char *)str(LANG_RECURSE_DIRECTORY_QUESTION), + ID2P(LANG_RECURSE_DIRECTORY_QUESTION), selected_file }; struct text_message message={lines, 2}; - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if (new_playlist) playlist_create(NULL, NULL); @@ -454,11 +454,11 @@ static int remove_dir(char* dirname, int static bool delete_handler(bool is_dir) { char *lines[]={ - (char *)str(LANG_REALLY_DELETE), + ID2P(LANG_REALLY_DELETE), selected_file }; char *yes_lines[]={ - (char *)str(LANG_DELETED), + ID2P(LANG_DELETED), selected_file }; @@ -522,6 +522,7 @@ static bool rename_file(void) lcd_puts(0,0,str(LANG_RENAME)); lcd_puts(0,1,str(LANG_FAILED)); lcd_update(); + cond_talk_ids_fq(LANG_RENAME, LANG_FAILED); sleep(HZ*2); } else @@ -551,6 +552,7 @@ bool create_dir(void) rc = mkdir(dirname, 0); if (rc < 0) { + cond_talk_ids_fq(LANG_CREATE_DIR, LANG_FAILED); gui_syncsplash(HZ, true, (unsigned char *)"%s %s", str(LANG_CREATE_DIR), str(LANG_FAILED)); } else { @@ -762,7 +764,7 @@ static bool clipboard_paste(void) bool success; int target_fd; - unsigned char *lines[]={str(LANG_REALLY_OVERWRITE)}; + unsigned char *lines[]={ID2P(LANG_REALLY_OVERWRITE)}; struct text_message message={(char **)lines, 1}; /* Get the name of the current directory */ @@ -809,6 +811,7 @@ static bool clipboard_paste(void) /* Force reload of the current directory */ onplay_result = ONPLAY_RELOAD_DIR; } else { + cond_talk_ids_fq(LANG_PASTE, LANG_FAILED); gui_syncsplash(HZ, true, (unsigned char *)"%s %s", str(LANG_PASTE), str(LANG_FAILED)); } Index: rockbox-devel/apps/playlist.c =================================================================== --- rockbox-devel.orig/apps/playlist.c +++ rockbox-devel/apps/playlist.c @@ -286,6 +286,7 @@ static void create_control(struct playli { if (check_rockboxdir()) { + cond_talk_ids_fq(LANG_PLAYLIST_CONTROL_ACCESS_ERROR); gui_syncsplash(HZ*2, true, (unsigned char *)"%s (%d)", str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR), playlist->control_fd); @@ -478,6 +479,7 @@ static int add_indices_to_playlist(struc lcd_setmargins(0, 0); #endif + cond_talk_ids(LANG_WAIT); gui_syncsplash(0, true, str(LANG_PLAYLIST_LOAD)); if (!buffer) @@ -728,9 +730,9 @@ static int directory_search_callback(cha unsigned char* count_str; if (c->queue) - count_str = str(LANG_PLAYLIST_QUEUE_COUNT); + count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); else - count_str = str(LANG_PLAYLIST_INSERT_COUNT); + count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); display_playlist_count(c->count, count_str); @@ -1276,9 +1278,9 @@ static int get_filename(struct playlist_ if (max < 0) { if (control_file) - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); else - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); return max; } @@ -1368,7 +1370,7 @@ static int get_next_dir(char *dir, bool if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); exit = true; result = -1; break; @@ -1453,7 +1455,7 @@ static int check_subdir_for_music(char * if (ft_load(tc, dir) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); return -2; } @@ -1506,8 +1508,7 @@ static int check_subdir_for_music(char * /* we now need to reload our current directory */ if(ft_load(tc, dir) < 0) - gui_syncsplash(HZ*2, true, - str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); } return result; @@ -1582,6 +1583,20 @@ static int format_track_path(char *dest, */ static void display_playlist_count(int count, const unsigned char *fmt) { + static long talked_tick = 0; + if(count && (talked_tick == 0 + || TIME_AFTER(current_tick, talked_tick+5*HZ))) + { + talked_tick = current_tick; + long id = P2ID(fmt); + if(id>=0) + { + talk_number(count, false); + talk_id(id, true); + } + } + fmt = P2STR(fmt); + lcd_clear_display(); #ifdef HAVE_LCD_BITMAP @@ -1605,7 +1620,7 @@ static void display_playlist_count(int c */ static void display_buffer_full(void) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_BUFFER_FULL)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_BUFFER_FULL)); } /* @@ -1684,7 +1699,7 @@ static int flush_cached_control(struct p else { result = -1; - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); } return result; @@ -1870,11 +1885,11 @@ int playlist_resume(void) empty_playlist(playlist, true); - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); playlist->control_fd = open(playlist->control_filename, O_RDWR); if (playlist->control_fd < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } playlist->control_created = true; @@ -1882,7 +1897,7 @@ int playlist_resume(void) control_file_size = filesize(playlist->control_fd); if (control_file_size <= 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } @@ -1891,7 +1906,7 @@ int playlist_resume(void) PLAYLIST_COMMAND_SIZE= control_file_size) { /* no newline at end of control file */ - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_INVALID)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_INVALID)); return -1; } @@ -2294,6 +2309,7 @@ int playlist_shuffle(int random_seed, in start_current = true; } + cond_talk_ids(LANG_WAIT); gui_syncsplash(0, true, str(LANG_PLAYLIST_SHUFFLE)); randomise_playlist(playlist, random_seed, start_current, true); @@ -2786,7 +2802,7 @@ int playlist_insert_track(struct playlis if (check_control(playlist) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } @@ -2817,14 +2833,14 @@ int playlist_insert_directory(struct pla if (check_control(playlist) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } if (queue) - count_str = str(LANG_PLAYLIST_QUEUE_COUNT); + count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); else - count_str = str(LANG_PLAYLIST_INSERT_COUNT); + count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); display_playlist_count(0, count_str); @@ -2875,14 +2891,14 @@ int playlist_insert_playlist(struct play if (check_control(playlist) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } fd = open(filename, O_RDONLY); if (fd < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); return -1; } @@ -2896,9 +2912,9 @@ int playlist_insert_playlist(struct play dir = "/"; if (queue) - count_str = str(LANG_PLAYLIST_QUEUE_COUNT); + count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); else - count_str = str(LANG_PLAYLIST_INSERT_COUNT); + count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); display_playlist_count(count, count_str); @@ -2988,7 +3004,7 @@ int playlist_delete(struct playlist_info if (check_control(playlist) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } @@ -3023,7 +3039,7 @@ int playlist_move(struct playlist_info* if (check_control(playlist) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } @@ -3286,7 +3302,7 @@ int playlist_save(struct playlist_info* if (playlist->buffer_size < (int)(playlist->amount * sizeof(int))) { /* not enough buffer space to store updated indices */ - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); return -1; } @@ -3302,11 +3318,11 @@ int playlist_save(struct playlist_info* fd = open(path, O_CREAT|O_WRONLY|O_TRUNC); if (fd < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); return -1; } - display_playlist_count(count, str(LANG_PLAYLIST_SAVE_COUNT)); + display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT)); cpu_boost_id(true, CPUBOOSTID_PLAYLIST); @@ -3343,7 +3359,7 @@ int playlist_save(struct playlist_info* if (fdprintf(fd, "%s\n", tmp_buf) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); result = -1; break; } @@ -3359,7 +3375,7 @@ int playlist_save(struct playlist_info* index = (index+1)%playlist->amount; } - display_playlist_count(count, str(LANG_PLAYLIST_SAVE_COUNT)); + display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT)); close(fd); @@ -3430,7 +3446,7 @@ int playlist_directory_tracksearch(const if (ft_load(tc, dirname) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); *(tc->dirfilter) = old_dirfilter; return -1; } Index: rockbox-devel/apps/playlist_catalog.c =================================================================== --- rockbox-devel.orig/apps/playlist_catalog.c +++ rockbox-devel/apps/playlist_catalog.c @@ -37,6 +37,7 @@ #include "sprintf.h" #include "tree.h" #include "yesno.h" +#include "talk.h" #define PLAYLIST_CATALOG_CFG ROCKBOX_DIR "/playlist_catalog.config" #define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists" @@ -112,7 +113,7 @@ static int initialize_catalog(void) if (!playlist_dir_exists) { if (mkdir(playlist_dir, 0) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_CATALOG_NO_DIRECTORY), + gui_syncsplash(HZ*2, true, ID2P(LANG_CATALOG_NO_DIRECTORY), playlist_dir); return -1; } @@ -146,7 +147,7 @@ static int create_playlist_list(char** p if (ft_load(tc, playlist_dir) < 0) { - gui_syncsplash(HZ*2, true, str(LANG_CATALOG_NO_DIRECTORY), + gui_syncsplash(HZ*2, true, ID2P(LANG_CATALOG_NO_DIRECTORY), playlist_dir); goto exit; } @@ -231,7 +232,7 @@ static int display_playlists(char* playl if (num_playlists <= 0) { - gui_syncsplash(HZ*2, true, str(LANG_CATALOG_NO_PLAYLISTS)); + gui_syncsplash(HZ*2, true, ID2P(LANG_CATALOG_NO_PLAYLISTS)); return -1; } @@ -319,6 +320,15 @@ static int display_playlists(char* playl insert */ static void display_insert_count(int count) { + static long talked_tick = 0; + if(count && (talked_tick == 0 + || TIME_AFTER(current_tick, talked_tick+5*HZ))) + { + talked_tick = current_tick; + talk_number(count, false); + talk_id(LANG_PLAYLIST_INSERT_COUNT, true); + } + gui_syncsplash(0, true, str(LANG_PLAYLIST_INSERT_COUNT), count, #if CONFIG_KEYPAD == PLAYER_PAD str(LANG_STOP_ABORT) @@ -403,7 +413,7 @@ static int add_to_playlist(const char* p /* search directory for tracks and append to playlist */ bool recurse = false; char *lines[] = { - (char *)str(LANG_RECURSE_DIRECTORY_QUESTION), + ID2P(LANG_RECURSE_DIRECTORY_QUESTION), sel }; struct text_message message={lines, 2}; Index: rockbox-devel/apps/plugin.c =================================================================== --- rockbox-devel.orig/apps/plugin.c +++ rockbox-devel/apps/plugin.c @@ -504,7 +504,7 @@ int plugin_load(const char* plugin, void plugin_loaded = false; } - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); strcpy(current_plugin,p); #ifdef SIMULATOR Index: rockbox-devel/apps/settings.c =================================================================== --- rockbox-devel.orig/apps/settings.c +++ rockbox-devel/apps/settings.c @@ -1064,6 +1064,7 @@ int settings_save( void ) lcd_remote_update(); #endif #endif + cond_talk_ids_fq(LANG_SETTINGS_SAVE_RECORDER); sleep(HZ*2); return -1; } @@ -1763,12 +1764,12 @@ bool settings_save_config(void) if (!kbd_input(filename, sizeof filename)) { fd = creat(filename, O_WRONLY); if (fd < 0) - gui_syncsplash(HZ, true, str(LANG_FAILED)); + gui_syncsplash(HZ, true, ID2P(LANG_FAILED)); else break; } else { - gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL)); + gui_syncsplash(HZ, true, ID2P(LANG_MENU_SETTING_CANCEL)); return false; } } @@ -1821,7 +1822,7 @@ bool settings_save_config(void) close(fd); - gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED)); + gui_syncsplash(HZ, true, ID2P(LANG_SETTINGS_SAVED)); return true; } @@ -2068,7 +2069,7 @@ bool do_set_setting(const unsigned char* } else if (action == ACTION_STD_CANCEL) { - gui_syncsplash(HZ/2,true,str(LANG_MENU_SETTING_CANCEL)); + gui_syncsplash(HZ/2,true, ID2P(LANG_MENU_SETTING_CANCEL)); if (cb_data->type == INT) *(int*)variable = oldvalue; else *(bool*)variable = (bool)oldvalue; Index: rockbox-devel/apps/settings_menu.c =================================================================== --- rockbox-devel.orig/apps/settings_menu.c +++ rockbox-devel/apps/settings_menu.c @@ -1408,7 +1408,7 @@ static bool audioscrobbler(void) NULL); if (!scrobbler_is_enabled() && global_settings.audioscrobbler) - gui_syncsplash(HZ*2, true, str(LANG_PLEASE_REBOOT)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLEASE_REBOOT)); if(scrobbler_is_enabled() && !global_settings.audioscrobbler) scrobbler_shutdown(); @@ -1634,7 +1634,7 @@ static bool dircache(void) NULL); if (!dircache_is_enabled() && global_settings.dircache) - gui_syncsplash(HZ*2, true, str(LANG_PLEASE_REBOOT)); + gui_syncsplash(HZ*2, true, ID2P(LANG_PLEASE_REBOOT)); if (!result) dircache_disable(); @@ -1829,12 +1829,12 @@ static bool bookmark_settings_menu(void) } static bool reset_settings(void) { - unsigned char *lines[]={str(LANG_RESET_ASK_RECORDER)}; + unsigned char *lines[]={ID2P(LANG_RESET_ASK_RECORDER)}; unsigned char *yes_lines[]={ str(LANG_RESET_DONE_SETTING), - str(LANG_RESET_DONE_CLEAR) + ID2P(LANG_RESET_DONE_CLEAR) }; - unsigned char *no_lines[]={yes_lines[0], str(LANG_RESET_DONE_CANCEL)}; + unsigned char *no_lines[]={yes_lines[0], ID2P(LANG_RESET_DONE_CANCEL)}; struct text_message message={(char **)lines, 1}; struct text_message yes_message={(char **)yes_lines, 2}; struct text_message no_message={(char **)no_lines, 2}; Index: rockbox-devel/apps/sound_menu.c =================================================================== --- rockbox-devel.orig/apps/sound_menu.c +++ rockbox-devel/apps/sound_menu.c @@ -1079,7 +1079,7 @@ bool rectrigger(void) switch (button) { case ACTION_STD_CANCEL: - gui_syncsplash(50, true, str(LANG_MENU_SETTING_CANCEL)); + gui_syncsplash(50, true, ID2P(LANG_MENU_SETTING_CANCEL)); global_settings.rec_start_thres = old_start_thres; global_settings.rec_start_duration = old_start_duration; global_settings.rec_prerecord_time = old_prerecord_time; Index: rockbox-devel/apps/tagcache.c =================================================================== --- rockbox-devel.orig/apps/tagcache.c +++ rockbox-devel/apps/tagcache.c @@ -3810,7 +3810,7 @@ bool tagcache_update(void) return false; queue_post(&tagcache_queue, Q_UPDATE, 0); - gui_syncsplash(HZ*2, true, str(LANG_TAGCACHE_FORCE_UPDATE_SPLASH)); + gui_syncsplash(HZ*2, true, ID2P(LANG_TAGCACHE_FORCE_UPDATE_SPLASH)); return false; } @@ -3818,7 +3818,7 @@ bool tagcache_update(void) bool tagcache_rebuild(void) { queue_post(&tagcache_queue, Q_REBUILD, 0); - gui_syncsplash(HZ*2, true, str(LANG_TAGCACHE_FORCE_UPDATE_SPLASH)); + gui_syncsplash(HZ*2, true, ID2P(LANG_TAGCACHE_FORCE_UPDATE_SPLASH)); return false; } Index: rockbox-devel/apps/tagtree.c =================================================================== --- rockbox-devel.orig/apps/tagtree.c +++ rockbox-devel/apps/tagtree.c @@ -671,7 +671,7 @@ bool tagtree_export(void) gui_syncsplash(0, true, str(LANG_CREATING)); if (!tagcache_create_changelog(&tcs)) { - gui_syncsplash(HZ*2, true, str(LANG_FAILED)); + gui_syncsplash(HZ*2, true, ID2P(LANG_FAILED)); } return false; @@ -679,10 +679,10 @@ bool tagtree_export(void) bool tagtree_import(void) { - gui_syncsplash(0, true, str(LANG_WAIT)); + gui_syncsplash(0, true, ID2P(LANG_WAIT)); if (!tagcache_import_changelog()) { - gui_syncsplash(HZ*2, true, str(LANG_FAILED)); + gui_syncsplash(HZ*2, true, ID2P(LANG_FAILED)); } return false; @@ -1195,7 +1195,7 @@ int retrieve_entries(struct tree_context if (!sort && (sort_inverse || sort_limit)) { - gui_syncsplash(HZ*4, true, str(LANG_SHOWDIR_BUFFER_FULL), total_count); + gui_syncsplash(HZ*4, true, ID2P(LANG_SHOWDIR_BUFFER_FULL)); logf("Too small dir buffer"); return 0; } @@ -1386,7 +1386,7 @@ int tagtree_enter(struct tree_context* c !global_settings.party_mode && playlist_modified(NULL)) { - char *lines[]={str(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; + char *lines[]={ID2P(LANG_WARN_ERASEDYNPLAYLIST_PROMPT)}; struct text_message message={lines, 1}; if (gui_syncyesno_run(&message, NULL, NULL) != YESNO_YES) @@ -1463,7 +1463,7 @@ bool insert_all_playlist(struct tree_con cpu_boost_id(true, CPUBOOSTID_TAGTREE); if (!tagcache_search(&tcs, tag_filename)) { - gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY)); + gui_syncsplash(HZ, true, ID2P(LANG_TAGCACHE_BUSY)); cpu_boost_id(false, CPUBOOSTID_TAGTREE); return false; } @@ -1560,12 +1560,12 @@ bool tagtree_insert_selection_playlist(i } if (tc->filesindir <= 0) - gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_PLAYER)); + gui_syncsplash(HZ, true, ID2P(LANG_END_PLAYLIST_PLAYER)); else { logf("insert_all_playlist"); if (!insert_all_playlist(tc, position, queue)) - gui_syncsplash(HZ*2, true, str(LANG_FAILED)); + gui_syncsplash(HZ*2, true, ID2P(LANG_FAILED)); } /* Finally return the dirlevel to its original value. */ Index: rockbox-devel/apps/filetypes.c =================================================================== --- rockbox-devel.orig/apps/filetypes.c +++ rockbox-devel/apps/filetypes.c @@ -340,14 +340,14 @@ static void scan_plugins(void) /* exttypes[] full, bail out */ if (cnt_exttypes >= MAX_EXTTYPES) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_EXTENSION_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_EXTENSION_FULL)); break; } /* filetypes[] full, bail out */ if (cnt_filetypes >= MAX_FILETYPES) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_FULL)); break; } @@ -380,7 +380,7 @@ static void scan_plugins(void) /* filter out to long filenames */ if (strlen((char *)entry->d_name) > MAX_PLUGIN_LENGTH + 5) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_PLUGIN_NAME_LONG)); continue; } @@ -561,13 +561,13 @@ bool read_config(const char* file) { if (cnt_exttypes >= MAX_EXTTYPES) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_EXTENSION_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_EXTENSION_FULL)); break; } if (cnt_filetypes >= MAX_FILETYPES) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_FULL)); break; } @@ -636,7 +636,7 @@ bool read_config(const char* file) { if (strlen(str[plugin]) > MAX_PLUGIN_LENGTH) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_PLUGIN_NAME_LONG)); str[plugin] = NULL; continue; } @@ -736,7 +736,7 @@ static char* string2icon(const char* str (unsigned long) string_buffer - (unsigned long) next_free_string) < ICON_LENGTH) { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_STRING_BUFFER_EMPTY)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_STRING_BUFFER_EMPTY)); return NULL; } @@ -792,7 +792,7 @@ static char* get_string(const char* str) } else { - gui_syncsplash(HZ, true, str(LANG_FILETYPES_STRING_BUFFER_EMPTY)); + gui_syncsplash(HZ, true, ID2P(LANG_FILETYPES_STRING_BUFFER_EMPTY)); return NULL; } } Index: rockbox-devel/apps/tree.c =================================================================== --- rockbox-devel.orig/apps/tree.c +++ rockbox-devel/apps/tree.c @@ -364,7 +364,7 @@ static int update_dir(void) (tc.dirfull || tc.filesindir == global_settings.max_files_in_dir) ) { - gui_syncsplash(HZ, true, str(LANG_SHOWDIR_BUFFER_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_SHOWDIR_BUFFER_FULL)); } } #ifdef HAVE_TAGCACHE @@ -516,7 +516,7 @@ static void start_resume(bool just_power else return; } else if (! just_powered_on) { - gui_syncsplash(HZ*2, true, str(LANG_NOTHING_TO_RESUME)); + gui_syncsplash(HZ*2, true, ID2P(LANG_NOTHING_TO_RESUME)); } } @@ -657,7 +657,7 @@ static bool dirbrowse(void) if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0) { - gui_syncsplash(HZ*2, true, str(LANG_NO_FILES)); + gui_syncsplash(HZ*2, true, ID2P(LANG_NO_FILES)); return false; /* No files found for rockbox_browser() */ } } Index: rockbox-devel/apps/playlist_viewer.c =================================================================== --- rockbox-devel.orig/apps/playlist_viewer.c +++ rockbox-devel/apps/playlist_viewer.c @@ -633,6 +633,7 @@ bool playlist_viewer_ex(char* filename) if (!viewer.playlist && !(audio_status() & AUDIO_STATUS_PLAY)) { /* Play has stopped */ + cond_talk_ids_fq(LANG_END_PLAYLIST_RECORDER); #ifdef HAVE_LCD_CHARCELLS gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_PLAYER)); #else @@ -694,7 +695,7 @@ bool playlist_viewer_ex(char* filename) ret = playlist_move(viewer.playlist, viewer.move_track, current_track->index); if (ret < 0) - gui_syncsplash(HZ, true, str(LANG_MOVE_FAILED)); + gui_syncsplash(HZ, true, ID2P(LANG_MOVE_FAILED)); update_playlist(true); viewer.move_track = -1; Index: rockbox-devel/apps/eq_menu.c =================================================================== --- rockbox-devel.orig/apps/eq_menu.c +++ rockbox-devel/apps/eq_menu.c @@ -308,24 +308,16 @@ static bool eq_set_band4(void) static bool eq_advanced_menu(void) { - int m, i; + int m; bool result; - char peak_band_label[3][32]; static struct menu_item items[] = { { ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), eq_set_band0 }, - { NULL, eq_set_band1 }, - { NULL, eq_set_band2 }, - { NULL, eq_set_band3 }, + { ID2P(LANG_EQUALIZER_BAND_PEAK1), eq_set_band1 }, + { ID2P(LANG_EQUALIZER_BAND_PEAK2), eq_set_band2 }, + { ID2P(LANG_EQUALIZER_BAND_PEAK3), eq_set_band3 }, { ID2P(LANG_EQUALIZER_BAND_HIGH_SHELF), eq_set_band4 }, }; - /* Construct menu labels */ - for(i = 1; i < 4; i++) { - snprintf(peak_band_label[i-1], sizeof(peak_band_label[i-1]), - str(LANG_EQUALIZER_BAND_PEAK), i); - items[i].desc = peak_band_label[i-1]; - } - m = menu_init( items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); result = menu_run(m); @@ -718,12 +710,12 @@ static bool eq_save_preset(void) if (!kbd_input(filename, sizeof filename)) { fd = creat(filename, O_WRONLY); if (fd < 0) - gui_syncsplash(HZ, true, str(LANG_FAILED)); + gui_syncsplash(HZ, true, ID2P(LANG_FAILED)); else break; } else { - gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL)); + gui_syncsplash(HZ, true, ID2P(LANG_MENU_SETTING_CANCEL)); return false; } } @@ -742,7 +734,7 @@ static bool eq_save_preset(void) close(fd); - gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED)); + gui_syncsplash(HZ, true, ID2P(LANG_SETTINGS_SAVED)); return true; } Index: rockbox-devel/apps/dbtree.c =================================================================== --- rockbox-devel.orig/apps/dbtree.c +++ rockbox-devel/apps/dbtree.c @@ -131,11 +131,16 @@ int db_load(struct tree_context* c) i = db_search(c, searchstring); c->dirlength = c->filesindir = i; if (c->dirfull) { - gui_syncsplash(HZ, true, str(LANG_SHOWDIR_BUFFER_FULL)); + gui_syncsplash(HZ, true, ID2P(LANG_SHOWDIR_BUFFER_FULL)); c->dirfull = false; } - else + else{ + if (global_settings.talk_menu) { + talk_number(i, false); + talk_id(LANG_ID3DB_MATCHES, true); + } gui_syncsplash(HZ, true, str(LANG_ID3DB_MATCHES), i); + } return i; case allsongs: Index: rockbox-devel/apps/misc.c =================================================================== --- rockbox-devel.orig/apps/misc.c +++ rockbox-devel/apps/misc.c @@ -60,6 +60,7 @@ #include "gui/gwps-common.h" #include "misc.h" +#include "playback.h" /* Format a large-range value for output, using the appropriate unit so that * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" @@ -584,23 +585,27 @@ static bool clean_shutdown(void (*callba x5_backlight_shutdown(); #endif if (!battery_level_safe()) + { + cond_talk_ids(LANG_WARNING_BATTERY_EMPTY, LANG_SHUTTINGDOWN); gui_syncsplash(3*HZ, true, "%s %s", str(LANG_WARNING_BATTERY_EMPTY), str(LANG_SHUTTINGDOWN)); - else if (battery_level_critical()) + } else if (battery_level_critical()) + { + cond_talk_ids(LANG_WARNING_BATTERY_LOW, LANG_SHUTTINGDOWN); gui_syncsplash(3*HZ, true, "%s %s", str(LANG_WARNING_BATTERY_LOW), str(LANG_SHUTTINGDOWN)); - else { + } else { #ifdef HAVE_TAGCACHE if (!tagcache_prepare_shutdown()) { cancel_shutdown(); - gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY)); + gui_syncsplash(HZ, true, ID2P(LANG_TAGCACHE_BUSY)); return false; } #endif - gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN)); + gui_syncsplash(0, true, ID2P(LANG_SHUTTINGDOWN)); } if (global_settings.fade_on_stop @@ -612,7 +617,9 @@ static bool clean_shutdown(void (*callba audio_stop(); while (audio_status()) sleep(1); - + + voice_wait(); + if (callback != NULL) callback(parameter);