Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 27817) +++ apps/lang/english.lang (working copy) @@ -12619,3 +12619,45 @@ *: "Update on Stop" + + id: LANG_TRACKONLY + desc: used in track x of y constructs + user: core + + *: "Track" + + + *: "Track" + + + *: "Track" + + + + id: LANG_VOICEINFO + desc: progressively voice information on the wps hotkey + user: core + + *: "Announce Information" + + + *: "Announce Information" + + + *: "Announce Information" + + + + id: LANG_ELAPSED + desc: prefix for elapsed playtime announcement + user: core + + *: "Elapsed" + + + *: "Elapsed" + + + *: "Elapsed" + + Index: apps/onplay.c =================================================================== --- apps/onplay.c (revision 27817) +++ apps/onplay.c (working copy) @@ -64,6 +64,8 @@ #include "pitchscreen.h" #include "viewport.h" +#include "powermgmt.h" + static int context; static char* selected_file = NULL; static int selected_file_attr = 0; @@ -1216,6 +1218,173 @@ return ONPLAY_RELOAD_DIR; } + +#define MAX_INFO_TEMPLATE 21 + +#define ANNOUNCEMENTSETTINGSFILE ROCKBOX_DIR "/announce.cfg" + +#define ANNOUNCEMENT_TIMEOUT 10 + +static int voiced_info = 0; + +static char infotemplate[MAX_INFO_TEMPLATE]; + +static bool infotemplate_loaded = false; + +static int info_reset_timeout = 0; + +static int voice_general_info(void) +{ + if (infotemplate_loaded == false) + { + memset(infotemplate, 0, MAX_INFO_TEMPLATE); + + int fd = open_utf8(ANNOUNCEMENTSETTINGSFILE, O_RDONLY); + + if (fd < 0) + { +#if CONFIG_RTC + *infotemplate = 'A'; +#else + *infotemplate = 'B'; +#endif + } + else + { + read_line(fd, infotemplate, (sizeof infotemplate) - 1); + + infotemplate_loaded = true; + + close(fd); + } + } + + int target_info = 0; + + if (TIME_AFTER(current_tick, info_reset_timeout)) + { + voiced_info = 0; + } + + info_reset_timeout = current_tick + ANNOUNCEMENT_TIMEOUT * HZ; + + /* + Loop through every char in the string, announcing those that + fall into the current group + */ + char* testchar = infotemplate; + + talk_shutup(); + + while (*testchar != 0) + { + if (*testchar == ':') + { + target_info++; + + /* + If we move to the next group, stop announcing + */ + if (target_info > voiced_info) + { + break; + } + } + + /* + If we're on the correct group + announce the current token + */ + if (target_info == voiced_info) + { + if (*testchar == 'A') + { +#if CONFIG_RTC + /* + Current time + */ + + struct tm *tm = get_time(); + + if (valid_time(tm)) + { + talk_id(LANG_TIME, true); + talk_time(tm, true); + } +#endif + } + else if (*testchar == 'B') + { + /* + Time played and time left for the current track + */ + struct mp3entry* id3 = audio_current_track(); + + int elapsed_length = id3->elapsed / 1000; + int track_length = id3->length / 1000; + + talk_id(LANG_ELAPSED, true); + + talk_value_decimal(elapsed_length, UNIT_TIME, 0, true); + + talk_id(LANG_OF, true); + + talk_value_decimal(track_length, UNIT_TIME, 0, true); + } + else if (*testchar == 'C') + { + /* + Track X of Y + */ + int current_track = playlist_get_display_index(); + int total_tracks = playlist_amount(); + + talk_id(LANG_TRACKONLY, true); + + talk_number(current_track, true); + + talk_id(LANG_OF, true); + + talk_number(total_tracks, true); + } + else if (*testchar == 'D') + { + talk_ids(true, LANG_BATTERY_TIME, TALK_ID(battery_level(), UNIT_PERCENT)); + } + else if (*testchar == 'E') + { + talk_ids(true, LANG_BATTERY_TIME, TALK_ID(battery_time() * 60, UNIT_TIME)); + } + else if (*testchar == 'F') + { + int remaining = get_sleep_timer(); + + talk_id(LANG_SLEEP_TIMER, true); + + talk_value_decimal(remaining, UNIT_TIME, 0, true); + } + else if (*testchar == ' ') + { + talk_id(VOICE_PAUSE, true); + } + } + + ++testchar; + } + + if (*testchar == 0) + { + voiced_info = 0; + } + else + { + ++voiced_info; + } + + return ONPLAY_OK; +} + + struct hotkey_assignment { int action; /* hotkey_action */ int lang_id; /* Language ID */ @@ -1252,6 +1421,9 @@ { HOTKEY_INSERT_SHUFFLED, LANG_INSERT_SHUFFLED, HOTKEY_FUNC(playlist_insert_shuffled, NULL), ONPLAY_OK }, + { HOTKEY_VOICEINFO, LANG_VOICEINFO, + HOTKEY_FUNC(voice_general_info, NULL), + ONPLAY_OK }, #ifdef HAVE_PICTUREFLOW_INTEGRATION { HOTKEY_PICTUREFLOW, LANG_ONPLAY_PICTUREFLOW, HOTKEY_FUNC(NULL, NULL), Index: apps/onplay.h =================================================================== --- apps/onplay.h (revision 27817) +++ apps/onplay.h (working copy) @@ -44,6 +44,7 @@ HOTKEY_DELETE, HOTKEY_INSERT, HOTKEY_INSERT_SHUFFLED, + HOTKEY_VOICEINFO, HOTKEY_PICTUREFLOW, }; #endif Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 27817) +++ apps/settings_list.c (working copy) @@ -1755,7 +1755,7 @@ #ifdef HAVE_HOTKEY TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, hotkey_wps, LANG_HOTKEY_WPS, HOTKEY_VIEW_PLAYLIST, "hotkey wps", - "off,view playlist,show track info,pitchscreen,open with,delete" + "off,view playlist,show track info,pitchscreen,open with,delete,voiceinfo" #ifdef HAVE_PICTUREFLOW_INTEGRATION ",pictureflow" #endif @@ -1767,7 +1767,7 @@ #endif HOTKEY_OFF, HOTKEY_VIEW_PLAYLIST, HOTKEY_SHOW_TRACK_INFO, HOTKEY_PITCHSCREEN, - HOTKEY_OPEN_WITH, HOTKEY_DELETE + HOTKEY_OPEN_WITH, HOTKEY_DELETE,HOTKEY_VOICEINFO #ifdef HAVE_PICTUREFLOW_INTEGRATION , HOTKEY_PICTUREFLOW #endif