diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index d42d08188a..0452467994 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c @@ -345,7 +345,8 @@ static int selection_to_val(const struct settings_list *setting, int selection) int setting_id = setting->sound_setting->setting; #ifndef ASCENDING_INT_SETTINGS step = sound_steps(setting_id); - max = sound_max(setting_id); + max = (setting_id == SOUND_VOLUME) ? + global_settings.volume_limit : sound_max(setting_id); /* min = sound_min(setting_id); */ #else step = -sound_steps(setting_id); @@ -429,7 +430,8 @@ static void val_to_selection(const struct settings_list *setting, int oldvalue, int setting_id = setting->sound_setting->setting; int steps = sound_steps(setting_id); int min = sound_min(setting_id); - int max = sound_max(setting_id); + int max = (setting_id == SOUND_VOLUME) ? + global_settings.volume_limit : sound_max(setting_id); *nb_items = (max-min)/steps + 1; #ifndef ASCENDING_INT_SETTINGS *selected = (max - oldvalue) / steps; diff --git a/apps/lang/chinese-simp.lang b/apps/lang/chinese-simp.lang index 4c3dd3c18f..e90ec510d2 100644 --- a/apps/lang/chinese-simp.lang +++ b/apps/lang/chinese-simp.lang @@ -13039,3 +13039,17 @@ *: "扫描媒体时扫描指定文件夹" + + id: LANG_VOLUME_LIMIT + desc: in sound_settings + user: core + + *: "Maximum Volume Limit" + + + *: "音量限制" + + + *: "音量限制" + + diff --git a/apps/lang/chinese-trad.lang b/apps/lang/chinese-trad.lang index f8dc5c38d6..0d0b68d1e5 100644 --- a/apps/lang/chinese-trad.lang +++ b/apps/lang/chinese-trad.lang @@ -11240,3 +11240,17 @@ *: "檔案大小" + + id: LANG_VOLUME_LIMIT + desc: in sound_settings + user: core + + *: "Maximum Volume Limit" + + + *: "音量限制" + + + *: "音量限制" + + diff --git a/apps/lang/english.lang b/apps/lang/english.lang index dcad532f7a..d7f4476be6 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -13178,3 +13178,17 @@ *: "Slow" + + id: LANG_VOLUME_LIMIT + desc: in sound_settings + user: core + + *: "Maximum Volume Limit" + + + *: "Maximum Volume Limit" + + + *: "Maximum Volume Limit" + + diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c index 28cc257193..8913266a5f 100644 --- a/apps/menus/sound_menu.c +++ b/apps/menus/sound_menu.c @@ -34,10 +34,50 @@ #include "menu_common.h" #include "splash.h" #include "kernel.h" +#include "talk.h" +#include "option_select.h" +#include "misc.h" + +static int32_t get_dec_talkid(int value, int unit) +{ + return TALK_ID_DECIMAL(value, 1, unit); +} + +static int volume_limit_callback(int action,const struct menu_item_ex *this_item) +{ + (void)this_item; + + static struct int_setting volume_limit_int_setting; + volume_limit_int_setting.option_callback = NULL; + volume_limit_int_setting.unit = UNIT_DB; + volume_limit_int_setting.min = sound_min(SOUND_VOLUME); + volume_limit_int_setting.max = sound_max(SOUND_VOLUME); + volume_limit_int_setting.step = sound_steps(SOUND_VOLUME); + volume_limit_int_setting.formatter = NULL; + volume_limit_int_setting.get_talk_id = get_dec_talkid; + + struct settings_list setting; + setting.flags = F_BANFROMQS|F_INT_SETTING|F_T_INT|F_NO_WRAP; + setting.lang_id = LANG_VOLUME_LIMIT; + setting.default_val.int_ = sound_max(SOUND_VOLUME); + setting.int_setting = &volume_limit_int_setting; + + switch (action) + { + case ACTION_ENTER_MENUITEM: + setting.setting = &global_settings.volume_limit; + option_screen(&setting, NULL, false, ID2P(LANG_VOLUME_LIMIT)); + case ACTION_EXIT_MENUITEM: /* on exit */ + setvol(); + break; + } + return action; +} /***********************************/ /* SOUND MENU */ MENUITEM_SETTING(volume, &global_settings.volume, NULL); +MENUITEM_SETTING(volume_limit, &global_settings.volume_limit, volume_limit_callback); #ifdef AUDIOHW_HAVE_BASS MENUITEM_SETTING(bass, &global_settings.bass, #ifdef HAVE_SW_TONE_CONTROLS @@ -171,6 +211,7 @@ static int timestretch_callback(int action,const struct menu_item_ex *this_item) MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio, &volume + ,&volume_limit #ifdef AUDIOHW_HAVE_BASS ,&bass #endif diff --git a/apps/misc.c b/apps/misc.c index e746c432e6..fa33bb5c4f 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -793,6 +793,9 @@ void setvol(void) global_settings.volume = min_vol; if (global_settings.volume > max_vol) global_settings.volume = max_vol; + if (global_settings.volume > global_settings.volume_limit) + global_settings.volume = global_settings.volume_limit; + sound_set_volume(global_settings.volume); global_status.last_volume_change = current_tick; settings_save(); diff --git a/apps/settings.h b/apps/settings.h index 087ff0cb45..62ae038385 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -828,6 +828,7 @@ struct user_settings #ifdef HAVE_PLAY_FREQ int play_frequency; /* core audio output frequency selection */ #endif + int volume_limit; /* maximum volume limit */ }; /** global variables **/ diff --git a/apps/settings_list.c b/apps/settings_list.c index bd2bfce36f..01bc5c53f4 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -661,9 +661,39 @@ static int32_t hotkey_getlang(int value, int unit) return get_hotkey_lang_id(value); } #endif /* HAVE_HOTKEY */ + +/* volume limiter */ +static void volume_limit_load_from_cfg(void* var, char*value) +{ + *(int*)var = atoi(value); +} +static char* volume_limit_write_to_cfg(void* setting, char*buf, int buf_len) +{ + int current = *(int*)setting; + snprintf(buf, buf_len, "%d", current); + return buf; +} +static bool volume_limit_is_changed(void* setting, void* defaultval) +{ + int current = *(int*)setting; + + if ((int*)defaultval == NULL) + *(int*)defaultval = sound_max(SOUND_VOLUME); + return (current != sound_max(SOUND_VOLUME)); +} +static void volume_limit_set_default(void* setting, void* defaultval) +{ + (void)defaultval; + *(int*)setting = sound_max(SOUND_VOLUME); +} + const struct settings_list settings[] = { /* sound settings */ - SOUND_SETTING(F_NO_WRAP,volume, LANG_VOLUME, "volume", SOUND_VOLUME), + SOUND_SETTING(F_NO_WRAP, volume, LANG_VOLUME, "volume", SOUND_VOLUME), + CUSTOM_SETTING(F_NO_WRAP, volume_limit, LANG_VOLUME_LIMIT, + NULL, "volume limit", + volume_limit_load_from_cfg, volume_limit_write_to_cfg, + volume_limit_is_changed, volume_limit_set_default), SOUND_SETTING(0, balance, LANG_BALANCE, "balance", SOUND_BALANCE), /* Tone controls */ #ifdef AUDIOHW_HAVE_BASS diff --git a/manual/configure_rockbox/sound_settings.tex b/manual/configure_rockbox/sound_settings.tex index d2da07b983..7022315c83 100644 --- a/manual/configure_rockbox/sound_settings.tex +++ b/manual/configure_rockbox/sound_settings.tex @@ -48,6 +48,12 @@ change to customise your listening experience. \opt{iaudiom3,iaudiom5,iaudiox5,sansa,sansaAMS,iriverh10,iriverh10_5gb,vibe500,fuzeplus}{% The minimum setting is -24~dB and the maximum is 24~dB.} +\section{\label{ref:volume_limit}Volume Limit} + This setting adjusts the maximum volume of your music. The setting is by + default set to the maximum volume which equals to no limit. To set a volume + limit, select a volume from the list and the maximum volume will be limited to + the selected value all over the system. + \opt{ipodvideo}{ \section{Bass Cutoff} This setting controls the frequency below which the bass adjustment applies.