diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 1749972965..395bce0ab1 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -11,6 +11,8 @@ # If you re-order things or remove entries, you must bump the binary language # file version number in both the 'binlang' tool and the language loader code. # +# The "voice' entry contains how we want the speech UI to pronounce this. +# id: LANG_SOUND_SETTINGS desc: in the main menu eng: "Sound Settings" @@ -2345,5 +2347,29 @@ eng: "" voice: "gigabyte" new: +id: VOICE_MILLIAMPHOURS +desc: spoken only +eng: "" +voice: "milliamp hours" +new: + +id: VOICE_PIXEL +desc: spoken only +eng: "" +voice: "pixel" +new: + +id: VOICE_PER_SEC +desc: spoken only +eng: "" +voice: "per second" +new: + +id: VOICE_HERTZ +desc: spoken only +eng: "" +voice: "hertz" +new: + #carry on adding normal LANG_ strings below diff --git a/apps/settings.c b/apps/settings.c index e68e74b2c2..927e8d17c6 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -1682,6 +1682,7 @@ bool set_bool_options(char* string, bool* variable, bool set_int(char* string, char* unit, + int voice_unit, int* variable, void (*function)(int), int step, @@ -1691,6 +1692,7 @@ bool set_int(char* string, bool done = false; int button; int org_value=*variable; + int last_value = 0x7FFFFFFF; /* out of range init */ #ifdef HAVE_LCD_BITMAP if(global_settings.statusbar) @@ -1711,6 +1713,20 @@ bool set_int(char* string, #endif lcd_update(); + if (*variable != last_value) + { + if (voice_unit < UNIT_LAST) + { /* use the available unit definition */ + talk_value(*variable, voice_unit, false); + } + else + { /* say the number, followed by an arbitrary voice ID */ + talk_number(*variable, false); + talk_id(voice_unit, true); + } + last_value = *variable; + } + button = button_get_w_tmo(HZ/2); switch(button) { #ifdef HAVE_RECORDER_KEYPAD diff --git a/apps/settings.h b/apps/settings.h index b51c4d8e47..350d14a346 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -230,7 +230,7 @@ bool set_bool_options(char* string, bool* variable, bool set_bool(char* string, bool* variable ); bool set_option(char* string, void* variable, enum optiontype type, struct opt_items* options, int numoptions, void (*function)(int)); -bool set_int(char* string, char* unit, int* variable, +bool set_int(char* string, char* unit, int voice_unit, int* variable, void (*function)(int), int step, int min, int max ); bool set_time(char* string, int timedate[]); int read_line(int fd, char* buffer, int buffer_size); diff --git a/apps/settings_menu.c b/apps/settings_menu.c index e1dcf6582c..35602f001b 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -63,7 +63,8 @@ static bool car_adapter_mode(void) static bool contrast(void) { - return set_int( str(LANG_CONTRAST), "", &global_settings.contrast, + return set_int( str(LANG_CONTRAST), "", UNIT_INT, + &global_settings.contrast, lcd_set_contrast, 1, MIN_CONTRAST_SETTING, MAX_CONTRAST_SETTING ); } @@ -154,7 +155,7 @@ static bool volume_type(void) #ifdef PM_DEBUG static bool peak_meter_fps_menu(void) { bool retval = false; - retval = set_int( "Refresh rate", "/s", + retval = set_int( "Refresh rate", "/s", UNIT_PER_SEC, &peak_meter_fps, NULL, 1, 5, 40); return retval; @@ -251,7 +252,7 @@ static bool peak_meter_release(void) { fits into a 7 bit number. The 8th bit is used for storing something else in the rtc ram. Also, the max value is 0x7e, since the RTC value 0xff is reserved */ - retval = set_int( str(LANG_PM_RELEASE), str(LANG_PM_UNITS_PER_READ), + retval = set_int( str(LANG_PM_RELEASE), STR(LANG_PM_UNITS_PER_READ), &global_settings.peak_meter_release, NULL, 1, 1, 0x7e); @@ -320,7 +321,7 @@ static bool peak_meter_min(void) { int range_max = -global_settings.peak_meter_max; int min = -global_settings.peak_meter_min; - retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), + retval = set_int(str(LANG_PM_MIN), str(LANG_PM_DBFS), UNIT_DB, &min, NULL, 1, -89, range_max); global_settings.peak_meter_min = - min; @@ -330,7 +331,7 @@ static bool peak_meter_min(void) { else { int min = global_settings.peak_meter_min; - retval = set_int(str(LANG_PM_MIN), "%", + retval = set_int(str(LANG_PM_MIN), "%", UNIT_PERCENT, &min, NULL, 1, 0, global_settings.peak_meter_max - 1); @@ -354,7 +355,7 @@ static bool peak_meter_max(void) { int range_min = -global_settings.peak_meter_min; int max = -global_settings.peak_meter_max;; - retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), + retval = set_int(str(LANG_PM_MAX), str(LANG_PM_DBFS), UNIT_DB, &max, NULL, 1, range_min, 0); global_settings.peak_meter_max = - max; @@ -365,7 +366,7 @@ static bool peak_meter_max(void) { else { int max = global_settings.peak_meter_max; - retval = set_int(str(LANG_PM_MAX), "%", + retval = set_int(str(LANG_PM_MAX), "%", UNIT_PERCENT, &max, NULL, 1, global_settings.peak_meter_min + 1, 100); @@ -579,7 +580,8 @@ static bool poweroff_idle_timer(void) static bool scroll_speed(void) { - return set_int(str(LANG_SCROLL), "Hz", &global_settings.scroll_speed, + return set_int(str(LANG_SCROLL), "Hz", UNIT_HERTZ, + &global_settings.scroll_speed, &lcd_scroll_speed, 1, 1, 10 ); } @@ -587,7 +589,8 @@ static bool scroll_speed(void) static bool scroll_delay(void) { int dummy = global_settings.scroll_delay * (HZ/10); - int rc = set_int(str(LANG_SCROLL_DELAY), "ms", &dummy, + int rc = set_int(str(LANG_SCROLL_DELAY), "ms", UNIT_MS, + &dummy, &lcd_scroll_delay, 100, 0, 2500 ); global_settings.scroll_delay = dummy / (HZ/10); return rc; @@ -596,7 +599,7 @@ static bool scroll_delay(void) #ifdef HAVE_LCD_BITMAP static bool scroll_step(void) { - return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", + return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", UNIT_PIXEL, &global_settings.scroll_step, &lcd_scroll_step, 1, 1, LCD_WIDTH ); } @@ -604,7 +607,8 @@ static bool scroll_step(void) static bool bidir_limit(void) { - return set_int(str(LANG_BIDIR_SCROLL), "%", &global_settings.bidir_limit, + return set_int(str(LANG_BIDIR_SCROLL), "%", UNIT_PERCENT, + &global_settings.bidir_limit, &lcd_bidir_scroll, 25, 0, 200 ); } @@ -627,7 +631,8 @@ static bool jump_scroll(void) static bool jump_scroll_delay(void) { int dummy = global_settings.jump_scroll_delay * (HZ/10); - int rc = set_int(str(LANG_JUMP_SCROLL_DELAY), "ms", &dummy, + int rc = set_int(str(LANG_JUMP_SCROLL_DELAY), "ms", UNIT_MS, + &dummy, &lcd_jump_scroll_delay, 100, 0, 2500 ); global_settings.jump_scroll_delay = dummy / (HZ/10); return rc; @@ -640,7 +645,8 @@ static bool jump_scroll_delay(void) */ static bool battery_capacity(void) { - return set_int(str(LANG_BATTERY_CAPACITY), "mAh", &global_settings.battery_capacity, + return set_int(str(LANG_BATTERY_CAPACITY), "mAh", UNIT_MAH, + &global_settings.battery_capacity, &set_battery_capacity, 50, 1500, BATTERY_CAPACITY_MAX ); } #endif @@ -754,7 +760,8 @@ static bool timeformat_set(void) static bool spindown(void) { - return set_int(str(LANG_SPINDOWN), "s", &global_settings.disk_spindown, + return set_int(str(LANG_SPINDOWN), "s", UNIT_SEC, + &global_settings.disk_spindown, ata_spindown, 1, 3, 254 ); } @@ -778,21 +785,21 @@ static bool poweroff(void) static bool max_files_in_dir(void) { - return set_int(str(LANG_MAX_FILES_IN_DIR), "", + return set_int(str(LANG_MAX_FILES_IN_DIR), "", UNIT_INT, &global_settings.max_files_in_dir, NULL, 50, 50, 10000 ); } static bool max_files_in_playlist(void) { - return set_int(str(LANG_MAX_FILES_IN_PLAYLIST), "", + return set_int(str(LANG_MAX_FILES_IN_PLAYLIST), "", UNIT_INT, &global_settings.max_files_in_playlist, NULL, 1000, 1000, 20000 ); } static bool buffer_margin(void) { - return set_int(str(LANG_MP3BUFFER_MARGIN), "s", + return set_int(str(LANG_MP3BUFFER_MARGIN), "s", UNIT_SEC, &global_settings.buffer_margin, mpeg_set_buffer_margin, 1, 0, 7 ); } diff --git a/apps/sound_menu.c b/apps/sound_menu.c index 0001d8b2fe..67e6999e8d 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c @@ -238,7 +238,7 @@ static bool recchannels(void) static bool recquality(void) { - return set_int(str(LANG_RECORDING_QUALITY), "", + return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, &global_settings.rec_quality, NULL, 1, 0, 7 ); } diff --git a/apps/talk.c b/apps/talk.c index d208c7296c..bbc09a67c1 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -35,8 +35,8 @@ extern void bitswap(unsigned char *data, int length); /* no header for this */ /***************** Constants *****************/ -#define VOICEFONT_FILENAME "/.rockbox/langs/english.voice" -#define QUEUE_SIZE 32 +#define QUEUE_SIZE 20 +const char* voicefont_file = "/.rockbox/langs/english.voice"; /***************** Data types *****************/ @@ -87,7 +87,7 @@ static int load_voicefont(void) p_voicefont = NULL; /* indicate no voicefont if we fail below */ - fd = open(VOICEFONT_FILENAME, O_RDONLY); + fd = open(voicefont_file, O_RDONLY); if (fd < 0) /* failed to open */ { p_voicefont = NULL; /* indicate no voicefont */ @@ -203,8 +203,20 @@ static int queue_clip(unsigned char* buf, int size, bool enqueue) void talk_init(void) { - has_voicefont = true; /* unless we fail later, assume we have one */ - talk_buffer_steal(); + int fd; + + fd = open(voicefont_file, O_RDONLY); + if (fd >= 0) /* success */ + { + close(fd); + has_voicefont = true; + } + else + { + has_voicefont = false; /* no voice file available */ + } + + talk_buffer_steal(); /* abuse this for most of our inits */ queue_write = queue_read = 0; } @@ -294,18 +306,18 @@ int talk_file(char* filename, bool enqueue) } -/* say a numeric value, this works for english, - but not necessarily for other languages */ +/* say a numeric value, this word ordering works for english, + but not necessarily for other languages (e.g. german) */ int talk_number(int n, bool enqueue) { - int level = 0; // mille count - int mil = 1000000000; // highest possible "-illion" + int level = 0; /* mille count */ + int mil = 1000000000; /* highest possible "-illion" */ if (!enqueue) shutup(); /* cut off all the pending stuff */ if (n==0) - { // special case + { /* special case */ talk_id(VOICE_ZERO, true); return 0; } @@ -318,9 +330,9 @@ int talk_number(int n, bool enqueue) while (n) { - int segment = n / mil; // extract in groups of 3 digits - n -= segment * mil; // remove the used digits from number - mil /= 1000; // digit place for next round + int segment = n / mil; /* extract in groups of 3 digits */ + n -= segment * mil; /* remove the used digits from number */ + mil /= 1000; /* digit place for next round */ if (segment) { @@ -333,7 +345,7 @@ int talk_number(int n, bool enqueue) talk_id(VOICE_HUNDRED, true); } - // combination indexing + /* combination indexing */ if (ones > 20) { int tens = ones/10 + 18; @@ -341,11 +353,11 @@ int talk_number(int n, bool enqueue) ones %= 10; } - // direct indexing + /* direct indexing */ if (ones) talk_id(VOICE_ZERO + ones, true); - // add billion, million, thousand + /* add billion, million, thousand */ if (mil) talk_id(VOICE_BILLION + level, true); } @@ -369,7 +381,11 @@ int talk_value(int n, int unit, bool enqueue) VOICE_DB, VOICE_PERCENT, VOICE_MEGABYTE, - VOICE_GIGABYTE + VOICE_GIGABYTE, + VOICE_MILLIAMPHOURS, + VOICE_PIXEL, + VOICE_PER_SEC, + VOICE_HERTZ, }; if (unit < 0 || unit >= UNIT_LAST) @@ -377,7 +393,7 @@ int talk_value(int n, int unit, bool enqueue) else unit_id = unit_voiced[unit]; - if ((n==1 || n==-1) // singular? + if ((n==1 || n==-1) /* singular? */ && unit_id >= VOICE_SECONDS && unit_id <= VOICE_HOURS) { unit_id--; /* use the singular for those units which have */ diff --git a/apps/talk.h b/apps/talk.h index 4851e7b6fb..518549ed74 100644 --- a/apps/talk.h +++ b/apps/talk.h @@ -38,6 +38,10 @@ enum { UNIT_PERCENT, /* % */ UNIT_MB, /* megabyte */ UNIT_GB, /* gigabyte */ + UNIT_MAH, /* milliAmp hours */ + UNIT_PIXEL, /* pixels */ + UNIT_PER_SEC, /* per second */ + UNIT_HERTZ, /* hertz */ UNIT_LAST /* END MARKER */ };