summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-02-12 14:22:35 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-02-12 14:22:35 +0000
commitfb62831faa2612da0372eb3dcfb0c19901e321ad (patch)
tree9fdb6817672b8a9757699c27aad2d362f39f51d9
parentb0810520be34bbcedeadab92e4bf63d04af03720 (diff)
downloadrockbox-fb62831faa2612da0372eb3dcfb0c19901e321ad.tar.gz
rockbox-fb62831faa2612da0372eb3dcfb0c19901e321ad.zip
* Move playback menu to the new sysetm
(http://forums.rockbox.org/index.php?topic=8703.0 if I broke any of those settings accidently). * Add set_int_ex() which is the same as set_int() but adds a param which is a callback that returns the voice ID to talk for the selected value * Change the "pause on headphone unplug" to use meaningful strings in the config instead of numbers, this setting will be reset. * saves ~500bytes on the rec build :D git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12285 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/SOURCES1
-rw-r--r--apps/menu.c5
-rw-r--r--apps/menus/exported_menus.h2
-rw-r--r--apps/menus/playback_menu.c209
-rw-r--r--apps/settings.c40
-rw-r--r--apps/settings.h6
-rw-r--r--apps/settings_list.c169
-rw-r--r--apps/settings_list.h1
-rw-r--r--apps/settings_menu.c485
9 files changed, 366 insertions, 552 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 93f6d1246e..e57c882a8b 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -13,6 +13,7 @@ main_menu.c
13menu.c 13menu.c
14menus/display_menu.c 14menus/display_menu.c
15menus/main_menu.c 15menus/main_menu.c
16menus/playback_menu.c
16menus/playlist_menu.c 17menus/playlist_menu.c
17#ifdef HAVE_RECORDING 18#ifdef HAVE_RECORDING
18menus/recording_menu.c 19menus/recording_menu.c
diff --git a/apps/menu.c b/apps/menu.c
index f5d40f1a98..a084871e58 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -631,14 +631,15 @@ int do_menu(const struct menu_item_ex *start_menu)
631 } 631 }
632 if (setting->flags&F_INT_SETTING) 632 if (setting->flags&F_INT_SETTING)
633 { 633 {
634 set_int(str(setting->lang_id), 634 set_int_ex(str(setting->lang_id),
635 NULL, 635 NULL,
636 setting->int_setting->unit,var, 636 setting->int_setting->unit,var,
637 setting->int_setting->option_callback, 637 setting->int_setting->option_callback,
638 setting->int_setting->step, 638 setting->int_setting->step,
639 setting->int_setting->min, 639 setting->int_setting->min,
640 setting->int_setting->max, 640 setting->int_setting->max,
641 setting->int_setting->formatter); 641 setting->int_setting->formatter,
642 setting->int_setting->get_talk_id);
642 } 643 }
643 else if (setting->flags&F_CHOICE_SETTING) 644 else if (setting->flags&F_CHOICE_SETTING)
644 { 645 {
diff --git a/apps/menus/exported_menus.h b/apps/menus/exported_menus.h
index 3d6a11a16e..db085a7d2f 100644
--- a/apps/menus/exported_menus.h
+++ b/apps/menus/exported_menus.h
@@ -26,7 +26,7 @@
26extern const struct menu_item_ex 26extern const struct menu_item_ex
27 main_menu_, /* main_menu.c */ 27 main_menu_, /* main_menu.c */
28 display_menu, /* display_menu.c */ 28 display_menu, /* display_menu.c */
29// playback_settings, /* playback_menu.c */ 29 playback_menu_item, /* playback_menu.c */
30#ifdef HAVE_RECORDING 30#ifdef HAVE_RECORDING
31 recording_settings_menu, /* recording_menu.c */ 31 recording_settings_menu, /* recording_menu.c */
32#endif 32#endif
diff --git a/apps/menus/playback_menu.c b/apps/menus/playback_menu.c
new file mode 100644
index 0000000000..63a95b28ce
--- /dev/null
+++ b/apps/menus/playback_menu.c
@@ -0,0 +1,209 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id: $
10 *
11 * Copyright (C) 2007 Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include <stdbool.h>
22#include <stddef.h>
23#include <limits.h>
24#include "config.h"
25#include "lang.h"
26#include "action.h"
27#include "splash.h"
28#include "settings.h"
29#include "menu.h"
30#include "sound_menu.h"
31#include "kernel.h"
32#include "playlist.h"
33#include "dsp.h"
34#include "scrobbler.h"
35#include "audio.h"
36
37#if CONFIG_CODEC == SWCODEC
38int setcrossfadeonexit_callback(int action,const struct menu_item_ex *this_item)
39{
40 (void)this_item;
41 switch (action)
42 {
43 case ACTION_EXIT_MENUITEM: /* on exit */
44 audio_set_crossfade(global_settings.crossfade);
45 break;
46 }
47 return action;
48}
49
50#endif /* CONFIG_CODEC == SWCODEC */
51
52/***********************************/
53/* PLAYBACK MENU */
54int playback_callback(int action,const struct menu_item_ex *this_item);
55
56MENUITEM_SETTING(shuffle_item, &global_settings.playlist_shuffle, playback_callback);
57MENUITEM_SETTING(repeat_mode, &global_settings.repeat_mode, playback_callback);
58MENUITEM_SETTING(play_selected, &global_settings.play_selected, NULL);
59MENUITEM_SETTING(resume, &global_settings.resume, NULL);
60
61MENUITEM_SETTING(ff_rewind_accel, &global_settings.ff_rewind_accel, NULL);
62MENUITEM_SETTING(ff_rewind_min_step, &global_settings.ff_rewind_min_step, NULL);
63MAKE_MENU(ff_rewind_settings_menu, ID2P(LANG_WIND_MENU), 0,
64 &ff_rewind_min_step, &ff_rewind_accel);
65#if CONFIG_CODEC == SWCODEC
66int buffermargin_callback(int action,const struct menu_item_ex *this_item)
67{
68 (void)this_item;
69 switch (action)
70 {
71 case ACTION_EXIT_MENUITEM: /* on exit */
72 audio_set_buffer_margin(global_settings.buffer_margin);
73 break;
74 }
75 return action;
76}
77#else
78# define buffermargin_callback NULL
79#endif
80MENUITEM_SETTING(buffer_margin, &global_settings.buffer_margin,
81 buffermargin_callback);
82MENUITEM_SETTING(fade_on_stop, &global_settings.fade_on_stop, NULL);
83MENUITEM_SETTING(party_mode, &global_settings.party_mode, NULL);
84
85#if CONFIG_CODEC == SWCODEC
86/* crossfade submenu */
87MENUITEM_SETTING(crossfade, &global_settings.crossfade, setcrossfadeonexit_callback);
88MENUITEM_SETTING(crossfade_fade_in_delay,
89 &global_settings.crossfade_fade_in_delay, setcrossfadeonexit_callback);
90MENUITEM_SETTING(crossfade_fade_in_duration,
91 &global_settings.crossfade_fade_in_duration, setcrossfadeonexit_callback);
92MENUITEM_SETTING(crossfade_fade_out_delay,
93 &global_settings.crossfade_fade_out_delay, setcrossfadeonexit_callback);
94MENUITEM_SETTING(crossfade_fade_out_duration,
95 &global_settings.crossfade_fade_out_duration, setcrossfadeonexit_callback);
96MENUITEM_SETTING(crossfade_fade_out_mixmode,
97 &global_settings.crossfade_fade_out_mixmode,NULL);
98MAKE_MENU(crossfade_settings_menu,ID2P(LANG_CROSSFADE),0,
99 &crossfade, &crossfade_fade_in_delay, &crossfade_fade_in_duration,
100 &crossfade_fade_out_delay, &crossfade_fade_out_duration,
101 &crossfade_fade_out_mixmode);
102
103/* replay gain submenu */
104
105int replaygain_callback(int action,const struct menu_item_ex *this_item)
106{
107 (void)this_item;
108 switch (action)
109 {
110 case ACTION_EXIT_MENUITEM: /* on exit */
111 dsp_set_replaygain(true);
112 break;
113 }
114 return action;
115}
116MENUITEM_SETTING(replaygain, &global_settings.replaygain ,replaygain_callback);
117MENUITEM_SETTING(replaygain_noclip, &global_settings.replaygain_noclip ,replaygain_callback);
118MENUITEM_SETTING(replaygain_type, &global_settings.replaygain_type ,replaygain_callback);
119MENUITEM_SETTING(replaygain_preamp, &global_settings.replaygain_preamp ,replaygain_callback);
120MAKE_MENU(replaygain_settings_menu,ID2P(LANG_REPLAYGAIN),0,
121 &replaygain,&replaygain_noclip,
122 &replaygain_type,&replaygain_preamp);
123
124MENUITEM_SETTING(beep, &global_settings.beep ,NULL);
125#endif /* CONFIG_CODEC == SWCODEC */
126
127#ifdef HAVE_SPDIF_POWER
128MENUITEM_SETTING(spdif_enable, &global_settings.spdif_enable, NULL);
129#endif
130MENUITEM_SETTING(id3_v1_first, &global_settings.id3_v1_first, NULL);
131MENUITEM_SETTING(next_folder, &global_settings.next_folder, NULL);
132int audioscrobbler_callback(int action,const struct menu_item_ex *this_item)
133{
134 (void)this_item;
135 switch (action)
136 {
137 case ACTION_EXIT_MENUITEM: /* on exit */
138 if (!scrobbler_is_enabled() && global_settings.audioscrobbler)
139 gui_syncsplash(HZ*2, true, str(LANG_PLEASE_REBOOT));
140
141 if(scrobbler_is_enabled() && !global_settings.audioscrobbler)
142 scrobbler_shutdown();
143 break;
144 }
145 return action;
146}
147MENUITEM_SETTING(audioscrobbler, &global_settings.audioscrobbler, audioscrobbler_callback);
148
149#ifdef HAVE_HEADPHONE_DETECTION
150MENUITEM_SETTING(unplug_mode, &global_settings.unplug_mode, NULL);
151MENUITEM_SETTING(unplug_rw, &global_settings.unplug_rw, NULL);
152MENUITEM_SETTING(unplug_autoresume, &global_settings.unplug_autoresume, NULL);
153MAKE_MENU(unplug_menu, ID2P(LANG_UNPLUG), 0,
154 &unplug_mode, &unplug_rw, &unplug_autoresume);
155#endif
156
157MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
158 &shuffle_item, &repeat_mode, &play_selected, &resume,
159 &ff_rewind_settings_menu,
160 &buffer_margin, &fade_on_stop, &party_mode,
161
162#if CONFIG_CODEC == SWCODEC
163 &crossfade_settings_menu, &replaygain_settings_menu, &beep,
164#endif
165
166#ifdef HAVE_SPDIF_POWER
167 &spdif_enable,
168#endif
169 &id3_v1_first, &next_folder, &audioscrobbler
170#ifdef HAVE_HEADPHONE_DETECTION
171 ,&unplug_menu
172#endif
173 );
174int playback_callback(int action,const struct menu_item_ex *this_item)
175{
176 static bool old_shuffle = false;
177 static int old_repeat_mode = 0;
178 (void)this_item;
179 switch (action)
180 {
181 case ACTION_ENTER_MENUITEM:
182 if (this_item == &shuffle_item)
183 old_shuffle = global_settings.playlist_shuffle;
184 else if (this_item == &repeat_mode)
185 old_repeat_mode = global_settings.repeat_mode;
186 break;
187 case ACTION_EXIT_MENUITEM: /* on exit */
188 if ((this_item == &shuffle_item) &&
189 (old_shuffle != global_settings.playlist_shuffle)
190 && (audio_status() & AUDIO_STATUS_PLAY))
191 {
192#if CONFIG_CODEC == SWCODEC
193 dsp_set_replaygain(true);
194#endif
195 if (global_settings.playlist_shuffle)
196 {
197 playlist_randomise(NULL, current_tick, true);
198 }
199 else
200 {
201 playlist_sort(NULL, true);
202 }
203 }
204 break;
205 }
206 return action;
207}
208/* PLAYBACK MENU */
209/***********************************/
diff --git a/apps/settings.c b/apps/settings.c
index 8ff623f653..52cfb6ed48 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -1022,11 +1022,15 @@ bool set_bool_options(const char* string, bool* variable,
1022 return result; 1022 return result;
1023} 1023}
1024 1024
1025static void talk_unit(int unit, int value) 1025static void talk_unit(int unit, int value, long (*get_talk_id)(int value))
1026{ 1026{
1027 if (global_settings.talk_menu) 1027 if (global_settings.talk_menu)
1028 { 1028 {
1029 if (unit < UNIT_LAST) 1029 if (get_talk_id)
1030 {
1031 talk_id(get_talk_id(value),false);
1032 }
1033 else if (unit < UNIT_LAST)
1030 { /* use the available unit definition */ 1034 { /* use the available unit definition */
1031 talk_value(value, unit, false); 1035 talk_value(value, unit, false);
1032 } 1036 }
@@ -1046,7 +1050,8 @@ struct value_setting_data {
1046 int voice_unit; 1050 int voice_unit;
1047 const char * unit; 1051 const char * unit;
1048 void (*formatter)(char* dest, int dest_length, 1052 void (*formatter)(char* dest, int dest_length,
1049 int variable, const char* unit); 1053 int value, const char* unit);
1054 long (*get_talk_id)(int value);
1050 /* used for BOOL and "choice" settings */ 1055 /* used for BOOL and "choice" settings */
1051 struct opt_items* options; 1056 struct opt_items* options;
1052}; 1057};
@@ -1100,7 +1105,7 @@ static bool do_set_setting(const unsigned char* string, void *variable,
1100 if (global_settings.talk_menu) 1105 if (global_settings.talk_menu)
1101 { 1106 {
1102 if (cb_data->type == INT && !cb_data->options) 1107 if (cb_data->type == INT && !cb_data->options)
1103 talk_unit(cb_data->voice_unit, *(int*)variable); 1108 talk_unit(cb_data->voice_unit, *(int*)variable, cb_data->get_talk_id);
1104 else talk_id(cb_data->options[selected].voice_id, false); 1109 else talk_id(cb_data->options[selected].voice_id, false);
1105 } 1110 }
1106 1111
@@ -1121,7 +1126,7 @@ static bool do_set_setting(const unsigned char* string, void *variable,
1121 { 1126 {
1122 value = cb_data->max - 1127 value = cb_data->max -
1123 gui_synclist_get_sel_pos(&lists)*cb_data->step; 1128 gui_synclist_get_sel_pos(&lists)*cb_data->step;
1124 talk_unit(cb_data->voice_unit, value); 1129 talk_unit(cb_data->voice_unit, value, cb_data->get_talk_id);
1125 } 1130 }
1126 else 1131 else
1127 { 1132 {
@@ -1195,7 +1200,7 @@ static const char *unit_strings[] =
1195 [UNIT_KBIT] 1200 [UNIT_KBIT]
1196 = "kb/s", 1201 = "kb/s",
1197}; 1202};
1198bool set_int(const unsigned char* string, 1203bool set_int_ex(const unsigned char* string,
1199 const char* unit, 1204 const char* unit,
1200 int voice_unit, 1205 int voice_unit,
1201 int* variable, 1206 int* variable,
@@ -1203,11 +1208,12 @@ bool set_int(const unsigned char* string,
1203 int step, 1208 int step,
1204 int min, 1209 int min,
1205 int max, 1210 int max,
1206 void (*formatter)(char*, int, int, const char*) ) 1211 void (*formatter)(char*, int, int, const char*),
1212 long (*get_talk_id)(int))
1207{ 1213{
1208#if CONFIG_KEYPAD != PLAYER_PAD 1214#if CONFIG_KEYPAD != PLAYER_PAD
1209 struct value_setting_data data = { 1215 struct value_setting_data data = {
1210 INT,max, step, voice_unit,unit,formatter,NULL }; 1216 INT,max, step, voice_unit,unit,formatter,get_talk_id,NULL };
1211 if (unit == NULL) 1217 if (unit == NULL)
1212 data.unit = unit_strings[voice_unit]; 1218 data.unit = unit_strings[voice_unit];
1213 return do_set_setting(string,variable,(max-min)/step + 1, 1219 return do_set_setting(string,variable,(max-min)/step + 1,
@@ -1215,14 +1221,26 @@ bool set_int(const unsigned char* string,
1215#else 1221#else
1216 int count = (max-min)/step + 1; 1222 int count = (max-min)/step + 1;
1217 struct value_setting_data data = { 1223 struct value_setting_data data = {
1218 INT,min, -step, voice_unit,unit,formatter,NULL }; 1224 INT,min, -step, voice_unit,unit,formatter,get_talk_id,NULL };
1219 if (unit == NULL) 1225 if (unit == NULL)
1220 data.unit = unit_strings[voice_unit]; 1226 data.unit = unit_strings[voice_unit];
1221 return do_set_setting(string,variable,count, 1227 return do_set_setting(string,variable,count,
1222 count - ((max-*variable)/step), &data,function); 1228 count - ((max-*variable)/step), &data,function);
1223#endif 1229#endif
1224} 1230}
1225 1231bool set_int(const unsigned char* string,
1232 const char* unit,
1233 int voice_unit,
1234 int* variable,
1235 void (*function)(int),
1236 int step,
1237 int min,
1238 int max,
1239 void (*formatter)(char*, int, int, const char*) )
1240{
1241 return set_int_ex(string, unit, voice_unit, variable, function,
1242 step, min, max, formatter, NULL);
1243}
1226/* NOTE: the 'type' parameter specifies the actual type of the variable 1244/* NOTE: the 'type' parameter specifies the actual type of the variable
1227 that 'variable' points to. not the value within. Only variables with 1245 that 'variable' points to. not the value within. Only variables with
1228 type 'bool' should use parameter BOOL. 1246 type 'bool' should use parameter BOOL.
@@ -1234,7 +1252,7 @@ bool set_option(const char* string, void* variable, enum optiontype type,
1234 const struct opt_items* options, int numoptions, void (*function)(int)) 1252 const struct opt_items* options, int numoptions, void (*function)(int))
1235{ 1253{
1236 struct value_setting_data data = { 1254 struct value_setting_data data = {
1237 type,0, 0, 0,NULL,NULL,(struct opt_items*)options }; 1255 type,0, 0, 0,NULL,NULL,NULL,(struct opt_items*)options };
1238 int selected; 1256 int selected;
1239 if (type == BOOL) 1257 if (type == BOOL)
1240 selected = *(bool*)variable ? 1 : 0; 1258 selected = *(bool*)variable ? 1 : 0;
diff --git a/apps/settings.h b/apps/settings.h
index 0411f6e7db..00017d2e1d 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -241,6 +241,12 @@ bool set_int(const unsigned char* string, const char* unit, int voice_unit,
241 int* variable, 241 int* variable,
242 void (*function)(int), int step, int min, int max, 242 void (*function)(int), int step, int min, int max,
243 void (*formatter)(char*, int, int, const char*) ); 243 void (*formatter)(char*, int, int, const char*) );
244/* use this one if you need to create a lang from the value (i.e with TALK_ID()) */
245bool set_int_ex(const unsigned char* string, const char* unit, int voice_unit,
246 int* variable,
247 void (*function)(int), int step, int min, int max,
248 void (*formatter)(char*, int, int, const char*),
249 long (*get_talk_id)(int));
244 250
245/* the following are either not in setting.c or shouldnt be */ 251/* the following are either not in setting.c or shouldnt be */
246bool set_time_screen(const char* string, struct tm *tm); 252bool set_time_screen(const char* string, struct tm *tm);
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 969d7c361c..1023235af5 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -19,7 +19,7 @@
19 19
20#include "config.h" 20#include "config.h"
21#include <stdbool.h> 21#include <stdbool.h>
22 22#include <string.h>
23#include "lang.h" 23#include "lang.h"
24#include "talk.h" 24#include "talk.h"
25#include "lcd.h" 25#include "lcd.h"
@@ -27,6 +27,9 @@
27#include "settings_list.h" 27#include "settings_list.h"
28#include "sound.h" 28#include "sound.h"
29#include "dsp.h" 29#include "dsp.h"
30#include "debug.h"
31#include "mpeg.h"
32#include "audio.h"
30 33
31/* some sets of values which are used more than once, to save memory */ 34/* some sets of values which are used more than once, to save memory */
32static const char off_on[] = "off,on"; 35static const char off_on[] = "off,on";
@@ -76,6 +79,34 @@ static const char trig_durations_conf [] =
76static const char backlight_times_conf [] = 79static const char backlight_times_conf [] =
77 "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90"; 80 "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
78#endif 81#endif
82/* ffwd/rewind and scan acceleration stuff */
83static int ff_rewind_min_stepvals[] = {1,2,3,4,5,6,8,10,15,20,25,30,45,60};
84static long ff_rewind_min_step_getlang(int value)
85{
86 return TALK_ID(ff_rewind_min_stepvals[value], UNIT_SEC);
87}
88static void ff_rewind_min_step_formatter(char *buffer, int buffer_size,
89 int val, const char *unit)
90{
91 (void)unit;
92 snprintf(buffer, buffer_size, "%ds", ff_rewind_min_stepvals[val]);
93}
94static long scanaccel_getlang(int value)
95{
96 if (value == 0)
97 return LANG_OFF;
98 return TALK_ID(value, UNIT_SEC);
99}
100static void scanaccel_formatter(char *buffer, int buffer_size,
101 int val, const char *unit)
102{
103 (void)unit;
104 if (val == 0)
105 strcpy(buffer, str(LANG_OFF));
106 else
107 snprintf(buffer, buffer_size, "2x/%ds", val);
108}
109
79 110
80#define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT) 111#define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT)
81/** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h 112/** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h
@@ -155,13 +186,21 @@ static const char backlight_times_conf [] =
155 {cb, count, {.talks = (int[]){__VA_ARGS__}}}}}} 186 {cb, count, {.talks = (int[]){__VA_ARGS__}}}}}}
156 187
157/* for settings which use the set_int() setting screen. 188/* for settings which use the set_int() setting screen.
158 unit is the UNIT_ define to display/talk. */ 189 unit is the UNIT_ define to display/talk.
159#define INT_SETTING(flags, var, lang_id, default, name, \ 190 the first one saves a string to the config file,
160 unit, min, max, step, formatter, cb) \ 191 the second one saves the variable value to the config file */
192#define INT_SETTING_W_CFGVALS(flags, var, lang_id, default, name, cfg_vals, \
193 unit, min, max, step, formatter, get_talk_id, cb) \
161 {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ 194 {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \
162 lang_id, INT(default), \ 195 lang_id, INT(default), name, cfg_vals, \
163 name, NULL, {.int_setting = (struct int_setting[]){ \ 196 {.int_setting = (struct int_setting[]){ \
164 {cb, unit, min, max, step, formatter}}}} 197 {cb, unit, min, max, step, formatter, get_talk_id}}}}
198#define INT_SETTING(flags, var, lang_id, default, name, \
199 unit, min, max, step, formatter, get_talk_id, cb) \
200 {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \
201 lang_id, INT(default), name, NULL, \
202 {.int_setting = (struct int_setting[]){ \
203 {cb, unit, min, max, step, formatter, get_talk_id}}}}
165 204
166#if CONFIG_CODEC == SWCODEC 205#if CONFIG_CODEC == SWCODEC
167static void crossfeed_format(char* buffer, int buffer_size, int value, 206static void crossfeed_format(char* buffer, int buffer_size, int value,
@@ -188,6 +227,16 @@ static void crossfeed_hf_cutoff_helper(int val)
188 global_settings.crossfeed_cross_gain 227 global_settings.crossfeed_cross_gain
189 + global_settings.crossfeed_hf_attenuation, val); 228 + global_settings.crossfeed_hf_attenuation, val);
190} 229}
230
231static void replaygain_preamp_format(char* buffer, int buffer_size, int value,
232 const char* unit)
233{
234 int v = abs(value);
235
236 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "",
237 v / 10, v % 10, unit);
238}
239
191#endif 240#endif
192#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 241#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
193static void set_mdb_enable(bool value) 242static void set_mdb_enable(bool value)
@@ -277,7 +326,7 @@ const struct settings_list settings[] = {
277 SYSTEM_SETTING(NVRAM(4),topruntime,0), 326 SYSTEM_SETTING(NVRAM(4),topruntime,0),
278#if MEM > 1 327#if MEM > 1
279 INT_SETTING(0,max_files_in_playlist,LANG_MAX_FILES_IN_PLAYLIST,10000, 328 INT_SETTING(0,max_files_in_playlist,LANG_MAX_FILES_IN_PLAYLIST,10000,
280 "max files in playlist", UNIT_INT,1000,20000,1000,NULL,NULL), 329 "max files in playlist", UNIT_INT,1000,20000,1000,NULL,NULL,NULL),
281 {F_T_INT,&global_settings.max_files_in_dir,LANG_MAX_FILES_IN_DIR, 330 {F_T_INT,&global_settings.max_files_in_dir,LANG_MAX_FILES_IN_DIR,
282 INT(400),"max files in dir",NULL,UNUSED}, 331 INT(400),"max files in dir",NULL,UNUSED},
283#else 332#else
@@ -398,16 +447,21 @@ const struct settings_list settings[] = {
398 OFFON_SETTING(0,play_selected,LANG_PLAY_SELECTED,true,"play selected",NULL), 447 OFFON_SETTING(0,play_selected,LANG_PLAY_SELECTED,true,"play selected",NULL),
399 OFFON_SETTING(0,party_mode,LANG_PARTY_MODE,false,"party mode",NULL), 448 OFFON_SETTING(0,party_mode,LANG_PARTY_MODE,false,"party mode",NULL),
400 OFFON_SETTING(0,fade_on_stop,LANG_FADE_ON_STOP,true,"volume fade",NULL), 449 OFFON_SETTING(0,fade_on_stop,LANG_FADE_ON_STOP,true,"volume fade",NULL),
401 {F_T_INT,&global_settings.ff_rewind_min_step,LANG_FFRW_STEP,INT(FF_REWIND_1000), 450 INT_SETTING_W_CFGVALS(0, ff_rewind_min_step, LANG_FFRW_STEP, FF_REWIND_1000,
402 "scan min step","1,2,3,4,5,6,8,10,15,20,25,30,45,60",UNUSED}, 451 "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60", UNIT_SEC,
403 {F_T_INT,&global_settings.ff_rewind_accel,LANG_FFRW_ACCEL,INT(3), 452 13, 0, -1, ff_rewind_min_step_formatter,
404 "scan accel",NULL,UNUSED}, 453 ff_rewind_min_step_getlang, NULL),
454 INT_SETTING(0, ff_rewind_accel, LANG_FFRW_ACCEL, 3, "scan accel",
455 UNIT_SEC, 16, 0, -1, scanaccel_formatter, scanaccel_getlang, NULL),
405#if CONFIG_CODEC == SWCODEC 456#if CONFIG_CODEC == SWCODEC
406 {F_T_INT,&global_settings.buffer_margin,LANG_MP3BUFFER_MARGIN,INT(0),"antiskip", 457 STRINGCHOICE_SETTING(0, buffer_margin, LANG_MP3BUFFER_MARGIN, 0,"antiskip",
407 "5s,15s,30s,1min,2min,3min,5min,10min",UNUSED}, 458 "5s,15s,30s,1min,2min,3min,5min,10min",NULL, 8,
459 TALK_ID(5, UNIT_SEC), TALK_ID(15, UNIT_SEC),
460 TALK_ID(30, UNIT_SEC), TALK_ID(1, UNIT_MIN), TALK_ID(2, UNIT_MIN),
461 TALK_ID(3, UNIT_MIN), TALK_ID(5, UNIT_MIN), TALK_ID(10, UNIT_MIN)),
408#else 462#else
409 {F_T_INT,&global_settings.buffer_margin,LANG_MP3BUFFER_MARGIN,INT(0), 463 INT_SETTING(0, buffer_margin, LANG_MP3BUFFER_MARGIN, 0, "antiskip", \
410 "antiskip",NULL,UNUSED}, 464 UNIT_SEC, 0, 7, 1, NULL, NULL, audio_set_buffer_margin),
411#endif 465#endif
412 /* disk */ 466 /* disk */
413#ifndef HAVE_MMC 467#ifndef HAVE_MMC
@@ -482,9 +536,9 @@ const struct settings_list settings[] = {
482 "sort files","alpha,oldest,newest,type",UNUSED}, 536 "sort files","alpha,oldest,newest,type",UNUSED},
483 {F_T_INT,&global_settings.sort_dir,LANG_SORT_DIR,INT(0), 537 {F_T_INT,&global_settings.sort_dir,LANG_SORT_DIR,INT(0),
484 "sort dirs","alpha,oldest,newest",UNUSED}, 538 "sort dirs","alpha,oldest,newest",UNUSED},
485 BOOL_SETTING(0,id3_v1_first,LANG_ID3_ORDER,false, 539 BOOL_SETTING(0, id3_v1_first, LANG_ID3_ORDER, false,
486 "id3 tag priority","v2-v1,v1-v2", 540 "id3 tag priority", "v2-v1,v1-v2",
487 LANG_ID3_V2_FIRST,LANG_ID3_V1_FIRST,NULL), 541 LANG_ID3_V2_FIRST, LANG_ID3_V1_FIRST, mpeg_id3_options),
488 542
489#ifdef HAVE_RECORDING 543#ifdef HAVE_RECORDING
490 /* recording */ 544 /* recording */
@@ -567,57 +621,61 @@ const struct settings_list settings[] = {
567#endif /* HAVE_RECORDING */ 621#endif /* HAVE_RECORDING */
568 622
569#ifdef HAVE_SPDIF_POWER 623#ifdef HAVE_SPDIF_POWER
570 OFFON_SETTING(0,spdif_enable,LANG_SPDIF_ENABLE,false,"spdif enable",NULL), 624 OFFON_SETTING(0, spdif_enable, LANG_SPDIF_ENABLE, false,
625 "spdif enable", spdif_power_enable),
571#endif 626#endif
572 {F_T_INT,&global_settings.next_folder,LANG_NEXT_FOLDER,INT(FOLDER_ADVANCE_OFF), 627 CHOICE_SETTING(0, next_folder, LANG_NEXT_FOLDER, FOLDER_ADVANCE_OFF,
573 "folder navigation","off,on,random",UNUSED}, 628 "folder navigation", "off,on,random",NULL ,3,
629 ID2P(LANG_SET_BOOL_NO), ID2P(LANG_SET_BOOL_YES), ID2P(LANG_RANDOM)),
574 OFFON_SETTING(0,runtimedb,LANG_RUNTIMEDB_ACTIVE,false,"gather runtime data",NULL), 630 OFFON_SETTING(0,runtimedb,LANG_RUNTIMEDB_ACTIVE,false,"gather runtime data",NULL),
575 631
576#if CONFIG_CODEC == SWCODEC 632#if CONFIG_CODEC == SWCODEC
577 /* replay gain */ 633 /* replay gain */
578 OFFON_SETTING(0,replaygain,LANG_REPLAYGAIN,false,"replaygain",NULL), 634 OFFON_SETTING(0, replaygain, LANG_REPLAYGAIN, false, "replaygain", NULL),
579 {F_T_INT,&global_settings.replaygain_type,LANG_REPLAYGAIN_MODE,INT(REPLAYGAIN_ALBUM), 635 CHOICE_SETTING(0, replaygain_type, LANG_REPLAYGAIN_MODE, REPLAYGAIN_ALBUM,
580 "replaygain type","track,album,track shuffle",UNUSED}, 636 "replaygain type", "track,album,track shuffle", NULL, 3,
581 OFFON_SETTING(0,replaygain_noclip,LANG_REPLAYGAIN_NOCLIP, 637 ID2P(LANG_TRACK_GAIN), ID2P(LANG_ALBUM_GAIN), ID2P(LANG_SHUFFLE_GAIN)),
582 false,"replaygain noclip",NULL), 638 OFFON_SETTING(0, replaygain_noclip, LANG_REPLAYGAIN_NOCLIP,
583 {F_T_INT,&global_settings.replaygain_preamp,LANG_REPLAYGAIN_PREAMP, 639 false, "replaygain noclip", NULL),
584 INT(0),"replaygain preamp",NULL,UNUSED}, 640 INT_SETTING(0, replaygain_preamp, LANG_REPLAYGAIN_PREAMP, 0, "replaygain preamp",
585 641 UNIT_DB, -120, 120, 1, replaygain_preamp_format, NULL, NULL),
586 {F_T_INT,&global_settings.beep,LANG_BEEP,INT(0),"beep","off,weak,moderate,strong",UNUSED}, 642
643 CHOICE_SETTING(0, beep, LANG_BEEP, 0,
644 "beep", "off,weak,moderate,strong", NULL, 3,
645 ID2P(LANG_OFF), ID2P(LANG_WEAK), ID2P(LANG_MODERATE), ID2P(LANG_STRONG)),
587 646
588 /* crossfade */ 647 /* crossfade */
589 {F_T_INT,&global_settings.crossfade,LANG_CROSSFADE_ENABLE,INT(0),"crossfade", 648 CHOICE_SETTING(0, crossfade, LANG_CROSSFADE_ENABLE, 0, "crossfade",
590 "off,shuffle,track skip,shuffle and track skip,always",UNUSED}, 649 "off,shuffle,track skip,shuffle and track skip,always",NULL, 5,
591 {F_T_INT,&global_settings.crossfade_fade_in_delay,LANG_CROSSFADE_FADE_IN_DELAY,INT(0), 650 ID2P(LANG_OFF), ID2P(LANG_SHUFFLE), ID2P(LANG_TRACKSKIP),
592 "crossfade fade in delay",NULL,UNUSED}, 651 ID2P(LANG_SHUFFLE_TRACKSKIP), ID2P(LANG_ALWAYS)),
593 {F_T_INT,&global_settings.crossfade_fade_out_delay, 652 INT_SETTING(0, crossfade_fade_in_delay, LANG_CROSSFADE_FADE_IN_DELAY, 0,
594 LANG_CROSSFADE_FADE_OUT_DELAY,INT(0), 653 "crossfade fade in delay", UNIT_SEC, 0, 7, 1, NULL, NULL, NULL),
595 "crossfade fade out delay",NULL,UNUSED}, 654 INT_SETTING(0, crossfade_fade_out_delay, LANG_CROSSFADE_FADE_OUT_DELAY, 0,
596 {F_T_INT,&global_settings.crossfade_fade_in_duration, 655 "crossfade fade out delay", UNIT_SEC, 0, 7, 1, NULL, NULL, NULL),
597 LANG_CROSSFADE_FADE_IN_DURATION,INT(0), 656 INT_SETTING(0, crossfade_fade_in_duration, LANG_CROSSFADE_FADE_IN_DURATION, 0,
598 "crossfade fade in duration",NULL,UNUSED}, 657 "crossfade fade in duration", UNIT_SEC, 0, 15, 1, NULL, NULL, NULL),
599 {F_T_INT,&global_settings.crossfade_fade_out_duration, 658 INT_SETTING(0, crossfade_fade_out_duration, LANG_CROSSFADE_FADE_OUT_DURATION, 0,
600 LANG_CROSSFADE_FADE_OUT_DURATION,INT(0), 659 "crossfade fade out duration", UNIT_SEC, 0, 15, 1, NULL, NULL, NULL),
601 "crossfade fade out duration",NULL,UNUSED}, 660 CHOICE_SETTING(0, crossfade_fade_out_mixmode, LANG_CROSSFADE_FADE_OUT_MODE,
602 {F_T_INT,&global_settings.crossfade_fade_out_mixmode, 661 0, "crossfade fade out mode", "crossfade,mix" ,NULL, 2,
603 LANG_CROSSFADE_FADE_OUT_MODE,INT(0), 662 ID2P(LANG_CROSSFADE), ID2P(LANG_MIX)),
604 "crossfade fade out mode","crossfade,mix",UNUSED},
605 663
606 /* crossfeed */ 664 /* crossfeed */
607 OFFON_SETTING(0,crossfeed, LANG_CROSSFEED, false, 665 OFFON_SETTING(0,crossfeed, LANG_CROSSFEED, false,
608 "crossfeed", dsp_set_crossfeed), 666 "crossfeed", dsp_set_crossfeed),
609 INT_SETTING(0, crossfeed_direct_gain, LANG_CROSSFEED_DIRECT_GAIN, 15, 667 INT_SETTING(0, crossfeed_direct_gain, LANG_CROSSFEED_DIRECT_GAIN, 15,
610 "crossfeed direct gain", UNIT_DB, 0, 60, 5, 668 "crossfeed direct gain", UNIT_DB, 0, 60, 5,
611 crossfeed_format, dsp_set_crossfeed_direct_gain), 669 crossfeed_format, NULL, dsp_set_crossfeed_direct_gain),
612 INT_SETTING(0, crossfeed_cross_gain, LANG_CROSSFEED_CROSS_GAIN, 60, 670 INT_SETTING(0, crossfeed_cross_gain, LANG_CROSSFEED_CROSS_GAIN, 60,
613 "crossfeed cross gain", UNIT_DB, 30, 120, 5, 671 "crossfeed cross gain", UNIT_DB, 30, 120, 5,
614 crossfeed_format, crossfeed_cross_gain_helper), 672 crossfeed_format, NULL, crossfeed_cross_gain_helper),
615 INT_SETTING(0, crossfeed_hf_attenuation, LANG_CROSSFEED_HF_ATTENUATION, 160, 673 INT_SETTING(0, crossfeed_hf_attenuation, LANG_CROSSFEED_HF_ATTENUATION, 160,
616 "crossfeed hf attenuation", UNIT_DB, 60, 240, 5, 674 "crossfeed hf attenuation", UNIT_DB, 60, 240, 5,
617 crossfeed_format, crossfeed_hf_att_helper), 675 crossfeed_format, NULL, crossfeed_hf_att_helper),
618 INT_SETTING(0, crossfeed_hf_cutoff, LANG_CROSSFEED_HF_CUTOFF,700, 676 INT_SETTING(0, crossfeed_hf_cutoff, LANG_CROSSFEED_HF_CUTOFF,700,
619 "crossfeed hf cutoff", UNIT_HERTZ, 500, 2000, 100, 677 "crossfeed hf cutoff", UNIT_HERTZ, 500, 2000, 100,
620 crossfeed_format, crossfeed_hf_cutoff_helper), 678 crossfeed_format, NULL, crossfeed_hf_cutoff_helper),
621 /* equalizer */ 679 /* equalizer */
622 OFFON_SETTING(0,eq_enabled,LANG_EQUALIZER_ENABLED,false,"eq enabled",NULL), 680 OFFON_SETTING(0,eq_enabled,LANG_EQUALIZER_ENABLED,false,"eq enabled",NULL),
623 {F_T_INT,&global_settings.eq_precut,LANG_EQUALIZER_PRECUT,INT(0), 681 {F_T_INT,&global_settings.eq_precut,LANG_EQUALIZER_PRECUT,INT(0),
@@ -763,10 +821,11 @@ const struct settings_list settings[] = {
763#endif 821#endif
764#endif 822#endif
765#ifdef HAVE_HEADPHONE_DETECTION 823#ifdef HAVE_HEADPHONE_DETECTION
766 {F_T_INT,&global_settings.unplug_mode,LANG_UNPLUG,INT(0), 824 CHOICE_SETTING(0, unplug_mode, LANG_UNPLUG, 0,
767 "pause on headphone unplug",NULL,UNUSED}, 825 "pause on headphone unplug", "off,pause,pause and resume", NULL, 3,
768 {F_T_INT,&global_settings.unplug_rw,LANG_UNPLUG_RW,INT(0), 826 ID2P(LANG_OFF), ID2P(LANG_PAUSE), ID2P(LANG_UNPLUG_RESUME)),
769 "rewind duration on pause",NULL,UNUSED}, 827 INT_SETTING(0, unplug_rw, LANG_UNPLUG_RW, 0, "rewind duration on pause",
828 UNIT_SEC, 0, 15, 1, NULL, NULL,NULL) ,
770 OFFON_SETTING(0,unplug_autoresume,LANG_UNPLUG_DISABLE_AUTORESUME,false, 829 OFFON_SETTING(0,unplug_autoresume,LANG_UNPLUG_DISABLE_AUTORESUME,false,
771 "disable autoresume if phones not present",NULL), 830 "disable autoresume if phones not present",NULL),
772#endif 831#endif
diff --git a/apps/settings_list.h b/apps/settings_list.h
index 7a5a445469..cbbd23a4b5 100644
--- a/apps/settings_list.h
+++ b/apps/settings_list.h
@@ -70,6 +70,7 @@ struct int_setting {
70 int max; 70 int max;
71 int step; 71 int step;
72 void (*formatter)(char*, int, int, const char*); 72 void (*formatter)(char*, int, int, const char*);
73 long (*get_talk_id)(int);
73}; 74};
74#define F_INT_SETTING 0x80 75#define F_INT_SETTING 0x80
75 76
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 054dd145a9..79c4d9d6e5 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -83,6 +83,7 @@ void dac_line_in(bool enable);
83#if LCD_DEPTH > 1 83#if LCD_DEPTH > 1
84#include "backdrop.h" 84#include "backdrop.h"
85#endif 85#endif
86#include "menus/exported_menus.h"
86 87
87#ifdef CONFIG_CHARGING 88#ifdef CONFIG_CHARGING
88static bool car_adapter_mode(void) 89static bool car_adapter_mode(void)
@@ -733,40 +734,6 @@ static bool peak_meter_menu(void)
733} 734}
734#endif /* HAVE_LCD_BITMAP */ 735#endif /* HAVE_LCD_BITMAP */
735 736
736static bool shuffle(void)
737{
738 return set_bool( str(LANG_SHUFFLE), &global_settings.playlist_shuffle );
739}
740
741static bool repeat_mode(void)
742{
743 bool result;
744 static const struct opt_items names[] = {
745 { STR(LANG_OFF) },
746 { STR(LANG_REPEAT_ALL) },
747 { STR(LANG_REPEAT_ONE) },
748 { STR(LANG_SHUFFLE) },
749#if (AB_REPEAT_ENABLE == 1)
750 { STR(LANG_REPEAT_AB) }
751#endif
752 };
753 int old_repeat = global_settings.repeat_mode;
754
755 result = set_option( str(LANG_REPEAT), &global_settings.repeat_mode,
756 INT, names, NUM_REPEAT_MODES, NULL );
757
758 if (old_repeat != global_settings.repeat_mode &&
759 (audio_status() & AUDIO_STATUS_PLAY))
760 audio_flush_and_reload_tracks();
761
762 return result;
763}
764
765static bool play_selected(void)
766{
767 return set_bool( str(LANG_PLAY_SELECTED), &global_settings.play_selected );
768}
769
770static bool dir_filter(void) 737static bool dir_filter(void)
771{ 738{
772 static const struct opt_items names[] = { 739 static const struct opt_items names[] = {
@@ -825,23 +792,6 @@ static bool sort_dir(void)
825 return ret; 792 return ret;
826} 793}
827 794
828static bool resume(void)
829{
830 return set_bool( str(LANG_RESUME), &global_settings.resume);
831}
832
833#ifdef HAVE_SPDIF_POWER
834static bool spdif(void)
835{
836 bool rc = set_bool_options(str(LANG_SPDIF_ENABLE),
837 &global_settings.spdif_enable,
838 STR(LANG_ON),
839 STR(LANG_OFF),
840 spdif_power_enable);
841 return rc;
842}
843#endif
844
845static bool autocreatebookmark(void) 795static bool autocreatebookmark(void)
846{ 796{
847 bool retval = false; 797 bool retval = false;
@@ -1153,68 +1103,6 @@ static bool max_files_in_playlist(void)
1153 NULL, 1000, 1000, 20000, NULL ); 1103 NULL, 1000, 1000, 20000, NULL );
1154} 1104}
1155 1105
1156#if CONFIG_CODEC == SWCODEC
1157static bool buffer_margin(void)
1158{
1159 int ret;
1160 static const struct opt_items names[] = {
1161 { "5s", TALK_ID(5, UNIT_SEC) },
1162 { "15s", TALK_ID(15, UNIT_SEC) },
1163 { "30s", TALK_ID(30, UNIT_SEC) },
1164 { "1min", TALK_ID(1, UNIT_MIN) },
1165 { "2min", TALK_ID(2, UNIT_MIN) },
1166 { "3min", TALK_ID(3, UNIT_MIN) },
1167 { "5min", TALK_ID(5, UNIT_MIN) },
1168 { "10min", TALK_ID(10, UNIT_MIN) }
1169 };
1170
1171 ret = set_option(str(LANG_MP3BUFFER_MARGIN), &global_settings.buffer_margin,
1172 INT, names, 8, NULL);
1173 audio_set_buffer_margin(global_settings.buffer_margin);
1174
1175 return ret;
1176}
1177#else
1178static bool buffer_margin(void)
1179{
1180 return set_int(str(LANG_MP3BUFFER_MARGIN), "s", UNIT_SEC,
1181 &global_settings.buffer_margin,
1182 audio_set_buffer_margin, 1, 0, 7, NULL );
1183}
1184#endif
1185
1186static bool ff_rewind_min_step(void)
1187{
1188 static const struct opt_items names[] = {
1189 { "1s", TALK_ID(1, UNIT_SEC) },
1190 { "2s", TALK_ID(2, UNIT_SEC) },
1191 { "3s", TALK_ID(3, UNIT_SEC) },
1192 { "4s", TALK_ID(4, UNIT_SEC) },
1193 { "5s", TALK_ID(5, UNIT_SEC) },
1194 { "6s", TALK_ID(6, UNIT_SEC) },
1195 { "8s", TALK_ID(8, UNIT_SEC) },
1196 { "10s", TALK_ID(10, UNIT_SEC) },
1197 { "15s", TALK_ID(15, UNIT_SEC) },
1198 { "20s", TALK_ID(20, UNIT_SEC) },
1199 { "25s", TALK_ID(25, UNIT_SEC) },
1200 { "30s", TALK_ID(30, UNIT_SEC) },
1201 { "45s", TALK_ID(45, UNIT_SEC) },
1202 { "60s", TALK_ID(60, UNIT_SEC) }
1203 };
1204 return set_option(str(LANG_FFRW_STEP), &global_settings.ff_rewind_min_step,
1205 INT, names, 14, NULL );
1206}
1207
1208static bool set_fade_on_stop(void)
1209{
1210 return set_bool( str(LANG_FADE_ON_STOP), &global_settings.fade_on_stop );
1211}
1212
1213static bool set_party_mode(void)
1214{
1215 return set_bool( str(LANG_PARTY_MODE), &global_settings.party_mode );
1216}
1217
1218#ifdef CONFIG_BACKLIGHT 1106#ifdef CONFIG_BACKLIGHT
1219static bool set_bl_filter_first_keypress(void) 1107static bool set_bl_filter_first_keypress(void)
1220{ 1108{
@@ -1234,30 +1122,6 @@ static bool set_remote_bl_filter_first_keypress(void)
1234#endif 1122#endif
1235#endif 1123#endif
1236 1124
1237static bool ff_rewind_accel(void)
1238{
1239 static const struct opt_items names[] = {
1240 { STR(LANG_OFF) },
1241 { "2x/1s", TALK_ID(1, UNIT_SEC) },
1242 { "2x/2s", TALK_ID(2, UNIT_SEC) },
1243 { "2x/3s", TALK_ID(3, UNIT_SEC) },
1244 { "2x/4s", TALK_ID(4, UNIT_SEC) },
1245 { "2x/5s", TALK_ID(5, UNIT_SEC) },
1246 { "2x/6s", TALK_ID(6, UNIT_SEC) },
1247 { "2x/7s", TALK_ID(7, UNIT_SEC) },
1248 { "2x/8s", TALK_ID(8, UNIT_SEC) },
1249 { "2x/9s", TALK_ID(9, UNIT_SEC) },
1250 { "2x/10s", TALK_ID(10, UNIT_SEC) },
1251 { "2x/11s", TALK_ID(11, UNIT_SEC) },
1252 { "2x/12s", TALK_ID(12, UNIT_SEC) },
1253 { "2x/13s", TALK_ID(13, UNIT_SEC) },
1254 { "2x/14s", TALK_ID(14, UNIT_SEC) },
1255 { "2x/15s", TALK_ID(15, UNIT_SEC) }
1256 };
1257 return set_option(str(LANG_FFRW_ACCEL), &global_settings.ff_rewind_accel,
1258 INT, names, 16, NULL );
1259}
1260
1261static bool browse_current(void) 1125static bool browse_current(void)
1262{ 1126{
1263 return set_bool( str(LANG_FOLLOW), &global_settings.browse_current ); 1127 return set_bool( str(LANG_FOLLOW), &global_settings.browse_current );
@@ -1373,62 +1237,6 @@ static bool button_bar(void)
1373#endif /* CONFIG_KEYPAD == RECORDER_PAD */ 1237#endif /* CONFIG_KEYPAD == RECORDER_PAD */
1374#endif /* HAVE_LCD_BITMAP */ 1238#endif /* HAVE_LCD_BITMAP */
1375 1239
1376static bool ff_rewind_settings_menu(void)
1377{
1378 int m;
1379 bool result;
1380
1381 static const struct menu_item items[] = {
1382 { ID2P(LANG_FFRW_STEP), ff_rewind_min_step },
1383 { ID2P(LANG_FFRW_ACCEL), ff_rewind_accel },
1384 };
1385
1386 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
1387 NULL, NULL, NULL);
1388 result = menu_run(m);
1389 menu_exit(m);
1390
1391 return result;
1392}
1393
1394static bool id3_order(void)
1395{
1396 return set_bool_options( str(LANG_ID3_ORDER),
1397 &global_settings.id3_v1_first,
1398 STR(LANG_ID3_V1_FIRST),
1399 STR(LANG_ID3_V2_FIRST),
1400 mpeg_id3_options);
1401}
1402
1403static bool next_folder(void)
1404{
1405 static const struct opt_items names[] = {
1406 { STR(LANG_SET_BOOL_NO) },
1407 { STR(LANG_SET_BOOL_YES) },
1408 { STR(LANG_RANDOM) },
1409 };
1410 return set_option(str(LANG_NEXT_FOLDER),
1411 &global_settings.next_folder,
1412 INT, names, 3, NULL );
1413}
1414
1415static bool audioscrobbler(void)
1416{
1417 bool result = set_bool_options(str(LANG_AUDIOSCROBBLER),
1418 &global_settings.audioscrobbler,
1419 STR(LANG_ON),
1420 STR(LANG_OFF),
1421 NULL);
1422
1423 if (!scrobbler_is_enabled() && global_settings.audioscrobbler)
1424 gui_syncsplash(HZ*2, true, str(LANG_PLEASE_REBOOT));
1425
1426 if(scrobbler_is_enabled() && !global_settings.audioscrobbler)
1427 scrobbler_shutdown();
1428
1429 return result;
1430}
1431
1432static bool codepage_setting(void) 1240static bool codepage_setting(void)
1433{ 1241{
1434 static const struct opt_items names[] = { 1242 static const struct opt_items names[] = {
@@ -1451,193 +1259,6 @@ static bool codepage_setting(void)
1451 INT, names, 13, set_codepage ); 1259 INT, names, 13, set_codepage );
1452} 1260}
1453 1261
1454#if CONFIG_CODEC == SWCODEC
1455static bool replaygain(void)
1456{
1457 bool result = set_bool(str(LANG_REPLAYGAIN_ENABLE),
1458 &global_settings.replaygain);
1459
1460 dsp_set_replaygain(true);
1461 return result;
1462}
1463
1464static bool replaygain_mode(void)
1465{
1466 static const struct opt_items names[] = {
1467 { STR(LANG_TRACK_GAIN) },
1468 { STR(LANG_ALBUM_GAIN) },
1469 { STR(LANG_SHUFFLE_GAIN) },
1470 };
1471 bool result = set_option(str(LANG_REPLAYGAIN_MODE),
1472 &global_settings.replaygain_type, INT, names, 3, NULL);
1473
1474 dsp_set_replaygain(true);
1475 return result;
1476}
1477
1478static bool replaygain_noclip(void)
1479{
1480 bool result = set_bool(str(LANG_REPLAYGAIN_NOCLIP),
1481 &global_settings.replaygain_noclip);
1482
1483 dsp_set_replaygain(true);
1484 return result;
1485}
1486
1487static void replaygain_preamp_format(char* buffer, int buffer_size, int value,
1488 const char* unit)
1489{
1490 int v = abs(value);
1491
1492 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "",
1493 v / 10, v % 10, unit);
1494}
1495
1496static bool replaygain_preamp(void)
1497{
1498 bool result = set_int(str(LANG_REPLAYGAIN_PREAMP), str(LANG_UNIT_DB),
1499 UNIT_DB, &global_settings.replaygain_preamp, NULL, 1, -120, 120,
1500 replaygain_preamp_format);
1501
1502 dsp_set_replaygain(true);
1503 return result;
1504}
1505
1506static bool replaygain_settings_menu(void)
1507{
1508 int m;
1509 bool result;
1510
1511 static const struct menu_item items[] = {
1512 { ID2P(LANG_REPLAYGAIN_ENABLE), replaygain },
1513 { ID2P(LANG_REPLAYGAIN_NOCLIP), replaygain_noclip },
1514 { ID2P(LANG_REPLAYGAIN_MODE), replaygain_mode },
1515 { ID2P(LANG_REPLAYGAIN_PREAMP), replaygain_preamp },
1516 };
1517
1518 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
1519 NULL, NULL, NULL);
1520 result = menu_run(m);
1521 menu_exit(m);
1522 return result;
1523}
1524
1525static bool crossfade(void)
1526{
1527 static const struct opt_items names[] = {
1528 { STR(LANG_OFF) },
1529 { STR(LANG_SHUFFLE) },
1530 { STR(LANG_TRACKSKIP) },
1531 { STR(LANG_SHUFFLE_TRACKSKIP) },
1532 { STR(LANG_ALWAYS) },
1533 };
1534
1535 bool ret;
1536
1537 ret=set_option( str(LANG_CROSSFADE_ENABLE),
1538 &global_settings.crossfade, INT, names, 5, NULL);
1539 audio_set_crossfade(global_settings.crossfade);
1540 return ret;
1541}
1542
1543static bool crossfade_fade_in_delay(void)
1544{
1545 bool ret;
1546
1547 ret = set_int(str(LANG_CROSSFADE_FADE_IN_DELAY), "s", UNIT_SEC,
1548 &global_settings.crossfade_fade_in_delay,
1549 NULL, 1, 0, 7, NULL );
1550 audio_set_crossfade(global_settings.crossfade);
1551 return ret;
1552}
1553
1554static bool crossfade_fade_out_delay(void)
1555{
1556 bool ret;
1557
1558 ret = set_int(str(LANG_CROSSFADE_FADE_OUT_DELAY), "s", UNIT_SEC,
1559 &global_settings.crossfade_fade_out_delay,
1560 NULL, 1, 0, 7, NULL );
1561 audio_set_crossfade(global_settings.crossfade);
1562 return ret;
1563}
1564
1565static bool crossfade_fade_in_duration(void)
1566{
1567 bool ret;
1568
1569 ret = set_int(str(LANG_CROSSFADE_FADE_IN_DURATION), "s", UNIT_SEC,
1570 &global_settings.crossfade_fade_in_duration,
1571 NULL, 1, 0, 15, NULL );
1572 audio_set_crossfade(global_settings.crossfade);
1573 return ret;
1574}
1575
1576static bool crossfade_fade_out_duration(void)
1577{
1578 bool ret;
1579
1580 ret = set_int(str(LANG_CROSSFADE_FADE_OUT_DURATION), "s", UNIT_SEC,
1581 &global_settings.crossfade_fade_out_duration,
1582 NULL, 1, 0, 15, NULL );
1583 audio_set_crossfade(global_settings.crossfade);
1584 return ret;
1585}
1586
1587static bool crossfade_fade_out_mixmode(void)
1588{
1589 static const struct opt_items names[] = {
1590 { STR(LANG_CROSSFADE) },
1591 { STR(LANG_MIX) },
1592 };
1593 bool ret;
1594 ret=set_option( str(LANG_CROSSFADE_FADE_OUT_MODE),
1595 &global_settings.crossfade_fade_out_mixmode, INT, names, 2, NULL);
1596
1597 return ret;
1598}
1599
1600/**
1601 * Menu to configure the crossfade settings.
1602 */
1603static bool crossfade_settings_menu(void)
1604{
1605 int m;
1606 bool result;
1607
1608 static const struct menu_item items[] = {
1609 { ID2P(LANG_CROSSFADE_ENABLE), crossfade },
1610 { ID2P(LANG_CROSSFADE_FADE_IN_DELAY), crossfade_fade_in_delay },
1611 { ID2P(LANG_CROSSFADE_FADE_IN_DURATION), crossfade_fade_in_duration },
1612 { ID2P(LANG_CROSSFADE_FADE_OUT_DELAY), crossfade_fade_out_delay },
1613 { ID2P(LANG_CROSSFADE_FADE_OUT_DURATION), crossfade_fade_out_duration },
1614 { ID2P(LANG_CROSSFADE_FADE_OUT_MODE), crossfade_fade_out_mixmode },
1615 };
1616
1617 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
1618 NULL, NULL, NULL);
1619 result = menu_run(m);
1620 menu_exit(m);
1621 return result;
1622}
1623
1624static bool beep(void)
1625{
1626 static const struct opt_items names[] = {
1627 { STR(LANG_OFF) },
1628 { STR(LANG_WEAK) },
1629 { STR(LANG_MODERATE) },
1630 { STR(LANG_STRONG) },
1631 };
1632 bool ret;
1633 ret=set_option( str(LANG_BEEP),
1634 &global_settings.beep, INT, names, 4, NULL);
1635
1636 return ret;
1637}
1638#endif
1639
1640
1641#ifdef HAVE_DIRCACHE 1262#ifdef HAVE_DIRCACHE
1642static bool dircache(void) 1263static bool dircache(void)
1643{ 1264{
@@ -1716,111 +1337,9 @@ static bool tagcache_settings_menu(void)
1716} 1337}
1717#endif 1338#endif
1718 1339
1719#ifdef HAVE_HEADPHONE_DETECTION
1720static bool unplug_mode(void)
1721{
1722 static const struct opt_items names[] = {
1723 { STR(LANG_OFF) },
1724 { STR(LANG_PAUSE) },
1725 { STR(LANG_UNPLUG_RESUME) },
1726 };
1727 bool ret;
1728 ret=set_option( str(LANG_UNPLUG),
1729 &global_settings.unplug_mode, INT, names, 3, NULL);
1730
1731 return ret;
1732}
1733
1734static bool unplug_rw(void)
1735{
1736 bool ret;
1737
1738 ret = set_int(str(LANG_UNPLUG_RW), "s", UNIT_SEC,
1739 &global_settings.unplug_rw,
1740 NULL, 1, 0, 15, NULL );
1741 audio_set_crossfade(global_settings.unplug_rw);
1742 return ret;
1743}
1744
1745static bool unplug_autoresume(void)
1746{
1747 return set_bool( str(LANG_UNPLUG_DISABLE_AUTORESUME),
1748 &global_settings.unplug_autoresume );
1749}
1750
1751static bool unplug_menu(void)
1752{
1753 int m;
1754 bool result;
1755
1756 static const struct menu_item items[] = {
1757 { ID2P(LANG_UNPLUG), unplug_mode },
1758 { ID2P(LANG_UNPLUG_RW), unplug_rw },
1759 { ID2P(LANG_UNPLUG_DISABLE_AUTORESUME), unplug_autoresume },
1760 };
1761
1762 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
1763 NULL, NULL, NULL);
1764 result = menu_run(m);
1765 menu_exit(m);
1766 return result;
1767}
1768#endif
1769
1770bool playback_settings_menu(void) 1340bool playback_settings_menu(void)
1771{ 1341{
1772 int m; 1342 return do_menu(&playback_menu_item);
1773 bool result;
1774
1775 static const struct menu_item items[] = {
1776 { ID2P(LANG_SHUFFLE), shuffle },
1777 { ID2P(LANG_REPEAT), repeat_mode },
1778 { ID2P(LANG_PLAY_SELECTED), play_selected },
1779 { ID2P(LANG_RESUME), resume },
1780 { ID2P(LANG_WIND_MENU), ff_rewind_settings_menu },
1781 { ID2P(LANG_MP3BUFFER_MARGIN), buffer_margin },
1782 { ID2P(LANG_FADE_ON_STOP), set_fade_on_stop },
1783 { ID2P(LANG_PARTY_MODE), set_party_mode },
1784#if CONFIG_CODEC == SWCODEC
1785 { ID2P(LANG_CROSSFADE), crossfade_settings_menu },
1786 { ID2P(LANG_REPLAYGAIN), replaygain_settings_menu },
1787 { ID2P(LANG_BEEP), beep },
1788#endif
1789#ifdef HAVE_SPDIF_POWER
1790 { ID2P(LANG_SPDIF_ENABLE), spdif },
1791#endif
1792 { ID2P(LANG_ID3_ORDER), id3_order },
1793 { ID2P(LANG_NEXT_FOLDER), next_folder },
1794#ifdef HAVE_HEADPHONE_DETECTION
1795 { ID2P(LANG_UNPLUG), unplug_menu },
1796#endif
1797 { ID2P(LANG_AUDIOSCROBBLER), audioscrobbler}
1798 };
1799
1800 bool old_shuffle = global_settings.playlist_shuffle;
1801
1802 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
1803 NULL, NULL, NULL);
1804 result = menu_run(m);
1805 menu_exit(m);
1806
1807 if ((old_shuffle != global_settings.playlist_shuffle)
1808 && (audio_status() & AUDIO_STATUS_PLAY))
1809 {
1810#if CONFIG_CODEC == SWCODEC
1811 dsp_set_replaygain(true);
1812#endif
1813
1814 if (global_settings.playlist_shuffle)
1815 {
1816 playlist_randomise(NULL, current_tick, true);
1817 }
1818 else
1819 {
1820 playlist_sort(NULL, true);
1821 }
1822 }
1823 return result;
1824} 1343}
1825 1344
1826static bool bookmark_settings_menu(void) 1345static bool bookmark_settings_menu(void)