diff options
-rw-r--r-- | apps/SOURCES | 1 | ||||
-rw-r--r-- | apps/menus/recording_menu.c | 826 | ||||
-rw-r--r-- | apps/settings_list.c | 72 | ||||
-rw-r--r-- | apps/sound_menu.c | 968 |
4 files changed, 874 insertions, 993 deletions
diff --git a/apps/SOURCES b/apps/SOURCES index 04199cd1fb..3f0c2bd2d9 100644 --- a/apps/SOURCES +++ b/apps/SOURCES | |||
@@ -33,7 +33,6 @@ root_menu.c | |||
33 | screens.c | 33 | screens.c |
34 | settings.c | 34 | settings.c |
35 | settings_list.c | 35 | settings_list.c |
36 | sound_menu.c | ||
37 | status.c | 36 | status.c |
38 | cuesheet.c | 37 | cuesheet.c |
39 | #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC | 38 | #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC |
diff --git a/apps/menus/recording_menu.c b/apps/menus/recording_menu.c index 248cf1655a..3d1bfcaf03 100644 --- a/apps/menus/recording_menu.c +++ b/apps/menus/recording_menu.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /*************************************************************************** | 1 | /*************************************************************************** |
3 | * __________ __ ___. | 2 | * __________ __ ___. |
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
@@ -18,19 +17,824 @@ | |||
18 | * | 17 | * |
19 | ****************************************************************************/ | 18 | ****************************************************************************/ |
20 | 19 | ||
21 | #include <stdbool.h> | ||
22 | #include <stddef.h> | ||
23 | #include <limits.h> | ||
24 | #include "config.h" | 20 | #include "config.h" |
21 | #include <stdio.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <stdbool.h> | ||
24 | #include "system.h" | ||
25 | #include "kernel.h" | ||
26 | #include "lcd.h" | ||
27 | #include "menu.h" | ||
28 | #include "button.h" | ||
29 | #include "mp3_playback.h" | ||
30 | #include "settings.h" | ||
31 | #include "statusbar.h" | ||
32 | #include "screens.h" | ||
33 | #include "icons.h" | ||
34 | #ifdef HAVE_LCD_BITMAP | ||
35 | #include "font.h" | ||
36 | #include "scrollbar.h" | ||
37 | #endif | ||
25 | #include "lang.h" | 38 | #include "lang.h" |
39 | #include "sprintf.h" | ||
40 | #include "talk.h" | ||
41 | #include "misc.h" | ||
42 | #include "sound.h" | ||
43 | #ifdef HAVE_RECORDING | ||
44 | #include "audio.h" | ||
45 | #if CONFIG_TUNER | ||
46 | #include "radio.h" | ||
47 | #endif | ||
48 | #endif | ||
49 | #ifdef HAVE_RECORDING | ||
50 | #include "peakmeter.h" | ||
51 | #include "mas.h" | ||
52 | #endif | ||
53 | #include "splash.h" | ||
54 | #if CONFIG_CODEC == SWCODEC | ||
55 | #include "dsp.h" | ||
56 | #include "menus/eq_menu.h" | ||
57 | #include "pcmbuf.h" | ||
58 | #ifdef HAVE_RECORDING | ||
59 | #include "enc_config.h" | ||
60 | #endif | ||
61 | #include "general.h" | ||
62 | #endif | ||
26 | #include "action.h" | 63 | #include "action.h" |
27 | #include "settings.h" | ||
28 | #include "menu.h" | ||
29 | #include "recording.h" | ||
30 | 64 | ||
31 | #ifdef HAVE_RECORDING | 65 | static bool no_source_in_menu = true; |
32 | /* TEMP */ | 66 | int recmenu_callback(int action,const struct menu_item_ex *this_item); |
33 | bool recording_menu(bool no_source); /* from apps/sound_menu.h */ | 67 | |
68 | static int recsource_func(void) | ||
69 | { | ||
70 | int n_opts = AUDIO_NUM_SOURCES; | ||
71 | |||
72 | static const struct opt_items names[AUDIO_NUM_SOURCES] = { | ||
73 | [AUDIO_SRC_MIC] = { STR(LANG_RECORDING_SRC_MIC) }, | ||
74 | [AUDIO_SRC_LINEIN] = { STR(LANG_RECORDING_SRC_LINE) }, | ||
75 | #ifdef HAVE_SPDIF_IN | ||
76 | [AUDIO_SRC_SPDIF] = { STR(LANG_RECORDING_SRC_DIGITAL) }, | ||
77 | #endif | ||
78 | #ifdef HAVE_FMRADIO_IN | ||
79 | [AUDIO_SRC_FMRADIO] = { STR(LANG_FM_RADIO) } | ||
80 | #endif | ||
81 | }; | ||
82 | |||
83 | /* caveat: assumes it's the last item! */ | ||
84 | #ifdef HAVE_FMRADIO_IN | ||
85 | if (!radio_hardware_present()) | ||
86 | n_opts--; | ||
87 | #endif | ||
88 | |||
89 | return set_option(str(LANG_RECORDING_SOURCE), | ||
90 | &global_settings.rec_source, INT, names, | ||
91 | n_opts, NULL ); | ||
92 | } | ||
93 | MENUITEM_FUNCTION(recsource, ID2P(LANG_RECORDING_SOURCE), | ||
94 | recsource_func, recmenu_callback, Icon_Menu_setting); | ||
95 | |||
96 | #if CONFIG_CODEC == SWCODEC | ||
97 | /* Makes an options list from a source list of options and indexes */ | ||
98 | static void make_options_from_indexes(const struct opt_items *src_names, | ||
99 | const long *src_indexes, | ||
100 | int n_indexes, | ||
101 | struct opt_items *dst_names) | ||
102 | { | ||
103 | while (--n_indexes >= 0) | ||
104 | dst_names[n_indexes] = src_names[src_indexes[n_indexes]]; | ||
105 | } /* make_options_from_indexes */ | ||
106 | |||
107 | |||
108 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
109 | |||
110 | static int recfrequency_func(void) | ||
111 | { | ||
112 | #if CONFIG_CODEC == MAS3587F | ||
113 | static const struct opt_items names[6] = { | ||
114 | { "44.1kHz", TALK_ID(44, UNIT_KHZ) }, | ||
115 | { "48kHz", TALK_ID(48, UNIT_KHZ) }, | ||
116 | { "32kHz", TALK_ID(32, UNIT_KHZ) }, | ||
117 | { "22.05kHz", TALK_ID(22, UNIT_KHZ) }, | ||
118 | { "24kHz", TALK_ID(24, UNIT_KHZ) }, | ||
119 | { "16kHz", TALK_ID(16, UNIT_KHZ) } | ||
120 | }; | ||
121 | return set_option(str(LANG_RECORDING_FREQUENCY), | ||
122 | &global_settings.rec_frequency, INT, | ||
123 | names, 6, NULL ); | ||
124 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
125 | |||
126 | #if CONFIG_CODEC == SWCODEC | ||
127 | static const struct opt_items names[REC_NUM_FREQ] = { | ||
128 | REC_HAVE_96_([REC_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },) | ||
129 | REC_HAVE_88_([REC_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },) | ||
130 | REC_HAVE_64_([REC_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },) | ||
131 | REC_HAVE_48_([REC_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },) | ||
132 | REC_HAVE_44_([REC_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },) | ||
133 | REC_HAVE_32_([REC_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },) | ||
134 | REC_HAVE_24_([REC_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },) | ||
135 | REC_HAVE_22_([REC_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },) | ||
136 | REC_HAVE_16_([REC_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },) | ||
137 | REC_HAVE_12_([REC_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },) | ||
138 | REC_HAVE_11_([REC_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },) | ||
139 | REC_HAVE_8_( [REC_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },) | ||
140 | }; | ||
141 | |||
142 | struct opt_items opts[REC_NUM_FREQ]; | ||
143 | unsigned long table[REC_NUM_FREQ]; | ||
144 | int n_opts; | ||
145 | int rec_frequency; | ||
146 | bool ret; | ||
147 | |||
148 | #ifdef HAVE_SPDIF_IN | ||
149 | if (global_settings.rec_source == AUDIO_SRC_SPDIF) | ||
150 | { | ||
151 | /* Inform user that frequency follows the source's frequency */ | ||
152 | opts[0].string = ID2P(LANG_SOURCE_FREQUENCY); | ||
153 | opts[0].voice_id = LANG_SOURCE_FREQUENCY; | ||
154 | n_opts = 1; | ||
155 | rec_frequency = 0; | ||
156 | } | ||
157 | else | ||
158 | #endif | ||
159 | { | ||
160 | struct encoder_caps caps; | ||
161 | struct encoder_config cfg; | ||
162 | |||
163 | cfg.rec_format = global_settings.rec_format; | ||
164 | global_to_encoder_config(&cfg); | ||
165 | |||
166 | if (!enc_get_caps(&cfg, &caps, true)) | ||
167 | return false; | ||
168 | |||
169 | /* Construct samplerate menu based upon encoder settings */ | ||
170 | n_opts = make_list_from_caps32(REC_SAMPR_CAPS, NULL, | ||
171 | caps.samplerate_caps, table); | ||
172 | |||
173 | if (n_opts == 0) | ||
174 | return false; /* No common flags...?? */ | ||
175 | |||
176 | make_options_from_indexes(names, table, n_opts, opts); | ||
177 | |||
178 | /* Find closest rate that the potentially restricted list | ||
179 | comes to */ | ||
180 | make_list_from_caps32(REC_SAMPR_CAPS, rec_freq_sampr, | ||
181 | caps.samplerate_caps, table); | ||
182 | |||
183 | rec_frequency = round_value_to_list32( | ||
184 | rec_freq_sampr[global_settings.rec_frequency], | ||
185 | table, n_opts, false); | ||
186 | } | ||
187 | |||
188 | ret = set_option(str(LANG_RECORDING_FREQUENCY), | ||
189 | &rec_frequency, INT, opts, n_opts, NULL ); | ||
190 | |||
191 | if (!ret | ||
192 | #ifdef HAVE_SPDIF_IN | ||
193 | && global_settings.rec_source != AUDIO_SRC_SPDIF | ||
194 | #endif | ||
195 | ) | ||
196 | { | ||
197 | /* Translate back to full index */ | ||
198 | global_settings.rec_frequency = | ||
199 | round_value_to_list32(table[rec_frequency], | ||
200 | rec_freq_sampr, | ||
201 | REC_NUM_FREQ, | ||
202 | false); | ||
203 | } | ||
204 | |||
205 | return ret; | ||
206 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
207 | } /* recfrequency */ | ||
208 | MENUITEM_FUNCTION(recfrequency, ID2P(LANG_RECORDING_FREQUENCY), | ||
209 | recfrequency_func, NULL, Icon_Menu_setting); | ||
210 | |||
211 | |||
212 | static int recchannels_func(void) | ||
213 | { | ||
214 | static const struct opt_items names[CHN_NUM_MODES] = { | ||
215 | [CHN_MODE_STEREO] = { STR(LANG_CHANNEL_STEREO) }, | ||
216 | [CHN_MODE_MONO] = { STR(LANG_CHANNEL_MONO) } | ||
217 | }; | ||
218 | #if CONFIG_CODEC == MAS3587F | ||
219 | return set_option(str(LANG_RECORDING_CHANNELS), | ||
220 | &global_settings.rec_channels, INT, | ||
221 | names, CHN_NUM_MODES, NULL ); | ||
222 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
223 | |||
224 | #if CONFIG_CODEC == SWCODEC | ||
225 | struct opt_items opts[CHN_NUM_MODES]; | ||
226 | long table[CHN_NUM_MODES]; | ||
227 | struct encoder_caps caps; | ||
228 | struct encoder_config cfg; | ||
229 | int n_opts; | ||
230 | int rec_channels; | ||
231 | bool ret; | ||
232 | |||
233 | cfg.rec_format = global_settings.rec_format; | ||
234 | global_to_encoder_config(&cfg); | ||
235 | |||
236 | if (!enc_get_caps(&cfg, &caps, true)) | ||
237 | return false; | ||
238 | |||
239 | n_opts = make_list_from_caps32(CHN_CAP_ALL, NULL, | ||
240 | caps.channel_caps, table); | ||
241 | |||
242 | rec_channels = round_value_to_list32(global_settings.rec_channels, | ||
243 | table, n_opts, false); | ||
244 | |||
245 | make_options_from_indexes(names, table, n_opts, opts); | ||
246 | |||
247 | ret = set_option(str(LANG_RECORDING_CHANNELS), &rec_channels, | ||
248 | INT, opts, n_opts, NULL ); | ||
249 | |||
250 | if (!ret) | ||
251 | global_settings.rec_channels = table[rec_channels]; | ||
252 | |||
253 | return ret; | ||
254 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
255 | } | ||
256 | MENUITEM_FUNCTION(recchannels, ID2P(LANG_RECORDING_CHANNELS), | ||
257 | recchannels_func, NULL, Icon_Menu_setting); | ||
258 | |||
259 | #if CONFIG_CODEC == SWCODEC | ||
260 | |||
261 | static int recformat_func(void) | ||
262 | { | ||
263 | static const struct opt_items names[REC_NUM_FORMATS] = { | ||
264 | [REC_FORMAT_AIFF] = { STR(LANG_AFMT_AIFF) }, | ||
265 | [REC_FORMAT_MPA_L3] = { STR(LANG_AFMT_MPA_L3) }, | ||
266 | [REC_FORMAT_WAVPACK] = { STR(LANG_AFMT_WAVPACK) }, | ||
267 | [REC_FORMAT_PCM_WAV] = { STR(LANG_AFMT_PCM_WAV) }, | ||
268 | }; | ||
269 | |||
270 | int rec_format = global_settings.rec_format; | ||
271 | bool res = set_option(str(LANG_RECORDING_FORMAT), &rec_format, INT, | ||
272 | names, REC_NUM_FORMATS, NULL ); | ||
273 | |||
274 | if (rec_format != global_settings.rec_format) | ||
275 | { | ||
276 | global_settings.rec_format = rec_format; | ||
277 | enc_global_settings_apply(); | ||
278 | } | ||
279 | |||
280 | return res; | ||
281 | } /* recformat */ | ||
282 | MENUITEM_FUNCTION(recformat, ID2P(LANG_RECORDING_FORMAT), | ||
283 | recformat_func, NULL, Icon_Menu_setting); | ||
284 | |||
285 | MENUITEM_FUNCTION(enc_global_config_menu_item, ID2P(LANG_ENCODER_SETTINGS), | ||
286 | (int(*)(void))enc_global_config_menu, NULL, Icon_Submenu); | ||
287 | |||
288 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
289 | |||
290 | |||
291 | int recmenu_callback(int action,const struct menu_item_ex *this_item) | ||
292 | { | ||
293 | switch (action) | ||
294 | { | ||
295 | case ACTION_REQUEST_MENUITEM: | ||
296 | if (this_item == &recsource && no_source_in_menu) | ||
297 | return ACTION_EXIT_MENUITEM; | ||
298 | break; | ||
299 | } | ||
300 | return action; | ||
301 | } | ||
302 | #if CONFIG_CODEC == MAS3587F | ||
303 | MENUITEM_SETTING(rec_quality, &global_settings.rec_quality, NULL); | ||
304 | MENUITEM_SETTING(rec_editable, &global_settings.rec_editable, NULL); | ||
305 | #endif | ||
306 | |||
307 | MENUITEM_SETTING(rec_split_type, &global_settings.rec_split_type, NULL); | ||
308 | MENUITEM_SETTING(rec_split_method, &global_settings.rec_split_method, NULL); | ||
309 | MENUITEM_SETTING(rec_timesplit, &global_settings.rec_timesplit, NULL); | ||
310 | MENUITEM_SETTING(rec_sizesplit, &global_settings.rec_sizesplit, NULL); | ||
311 | MAKE_MENU(filesplitoptionsmenu, ID2P(LANG_RECORD_TIMESPLIT), NULL, Icon_NOICON, | ||
312 | &rec_split_method, &rec_split_type, &rec_timesplit, &rec_sizesplit); | ||
313 | |||
314 | |||
315 | MENUITEM_SETTING(rec_prerecord_time, &global_settings.rec_prerecord_time, NULL); | ||
316 | static int recdirectory_func(void) | ||
317 | { | ||
318 | static const struct opt_items names[] = { | ||
319 | { rec_base_directory, -1 }, | ||
320 | { STR(LANG_RECORD_CURRENT_DIR) } | ||
321 | }; | ||
322 | return set_option(str(LANG_RECORD_DIRECTORY), | ||
323 | &global_settings.rec_directory, INT, | ||
324 | names, 2, NULL ); | ||
325 | } | ||
326 | MENUITEM_FUNCTION(recdirectory, ID2P(LANG_RECORD_DIRECTORY), | ||
327 | recdirectory_func, NULL, Icon_Menu_setting); | ||
328 | |||
329 | MENUITEM_SETTING(cliplight, &global_settings.cliplight, NULL); | ||
330 | |||
331 | #ifdef HAVE_AGC | ||
332 | static int agc_preset_func(void) | ||
333 | { | ||
334 | static const struct opt_items names[] = { | ||
335 | { STR(LANG_OFF) }, | ||
336 | { STR(LANG_AGC_SAFETY) }, | ||
337 | { STR(LANG_AGC_LIVE) }, | ||
338 | { STR(LANG_AGC_DJSET) }, | ||
339 | { STR(LANG_AGC_MEDIUM) }, | ||
340 | { STR(LANG_AGC_VOICE) }, | ||
341 | }; | ||
342 | if (global_settings.rec_source) | ||
343 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
344 | &global_settings.rec_agc_preset_line, | ||
345 | INT, names, 6, NULL ); | ||
346 | else | ||
347 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
348 | &global_settings.rec_agc_preset_mic, | ||
349 | INT, names, 6, NULL ); | ||
350 | } | ||
351 | |||
352 | static int agc_cliptime_func(void) | ||
353 | { | ||
354 | static const struct opt_items names[] = { | ||
355 | { "200ms", TALK_ID(200, UNIT_MS) }, | ||
356 | { "400ms", TALK_ID(400, UNIT_MS) }, | ||
357 | { "600ms", TALK_ID(600, UNIT_MS) }, | ||
358 | { "800ms", TALK_ID(800, UNIT_MS) }, | ||
359 | { "1s", TALK_ID(1, UNIT_SEC) } | ||
360 | }; | ||
361 | return set_option(str(LANG_RECORD_AGC_CLIPTIME), | ||
362 | &global_settings.rec_agc_cliptime, | ||
363 | INT, names, 5, NULL ); | ||
364 | } | ||
365 | MENUITEM_FUNCTION(agc_preset, ID2P(LANG_RECORD_AGC_PRESET), | ||
366 | agc_preset_func, NULL, Icon_Menu_setting); | ||
367 | MENUITEM_FUNCTION(agc_cliptime, ID2P(LANG_RECORD_AGC_CLIPTIME), | ||
368 | agc_cliptime_func, NULL, Icon_Menu_setting); | ||
369 | #endif /* HAVE_AGC */ | ||
370 | |||
371 | /** Rec trigger **/ | ||
372 | enum trigger_menu_option | ||
373 | { | ||
374 | TRIGGER_MODE, | ||
375 | TRIGGER_TYPE, | ||
376 | PRERECORD_TIME, | ||
377 | START_THRESHOLD, | ||
378 | START_DURATION, | ||
379 | STOP_THRESHOLD, | ||
380 | STOP_POSTREC, | ||
381 | STOP_GAP, | ||
382 | TRIG_OPTION_COUNT, | ||
383 | }; | ||
384 | |||
385 | static char* create_thres_str(int threshold) | ||
386 | { | ||
387 | static char retval[6]; | ||
388 | if (threshold < 0) { | ||
389 | if (threshold < -88) { | ||
390 | snprintf (retval, sizeof retval, "%s", str(LANG_DB_INF)); | ||
391 | } else { | ||
392 | snprintf (retval, sizeof retval, "%ddb", threshold + 1); | ||
393 | } | ||
394 | } else { | ||
395 | snprintf (retval, sizeof retval, "%d%%", threshold); | ||
396 | } | ||
397 | return retval; | ||
398 | } | ||
399 | |||
400 | #define INF_DB (-89) | ||
401 | static void change_threshold(int *threshold, int change) | ||
402 | { | ||
403 | if (global_settings.peak_meter_dbfs) { | ||
404 | if (*threshold >= 0) { | ||
405 | int db = (calc_db(*threshold * MAX_PEAK / 100) - 9000) / 100; | ||
406 | *threshold = db; | ||
407 | } | ||
408 | *threshold += change; | ||
409 | if (*threshold > -1) { | ||
410 | *threshold = INF_DB; | ||
411 | } else if (*threshold < INF_DB) { | ||
412 | *threshold = -1; | ||
413 | } | ||
414 | } else { | ||
415 | if (*threshold < 0) { | ||
416 | *threshold = peak_meter_db2sample(*threshold * 100) * 100 / MAX_PEAK; | ||
417 | } | ||
418 | *threshold += change; | ||
419 | if (*threshold > 100) { | ||
420 | *threshold = 0; | ||
421 | } else if (*threshold < 0) { | ||
422 | *threshold = 100; | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * Displays a menu for editing the trigger settings. | ||
429 | */ | ||
430 | bool rectrigger(void) | ||
431 | { | ||
432 | int exit_request = false; | ||
433 | enum trigger_menu_option selected = TRIGGER_MODE; | ||
434 | bool retval = false; | ||
435 | int old_x_margin[NB_SCREENS]; | ||
436 | int old_y_margin[NB_SCREENS]; | ||
437 | |||
438 | #define TRIGGER_MODE_COUNT 3 | ||
439 | static const unsigned char *trigger_modes[] = { | ||
440 | ID2P(LANG_OFF), | ||
441 | ID2P(LANG_RECORD_TRIG_NOREARM), | ||
442 | ID2P(LANG_RECORD_TRIG_REARM) | ||
443 | }; | ||
444 | |||
445 | #define PRERECORD_TIMES_COUNT 31 | ||
446 | static const unsigned char *prerecord_times[] = { | ||
447 | ID2P(LANG_OFF),"1s","2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", | ||
448 | "10s", "11s", "12s", "13s", "14s", "15s", "16s", "17s", "18s", "19s", | ||
449 | "20s", "21s", "22s", "23s", "24s", "25s", "26s", "27s", "28s", "29s", | ||
450 | "30s" | ||
451 | }; | ||
452 | |||
453 | #define TRIGGER_TYPE_COUNT 3 | ||
454 | static const unsigned char *trigger_types[] = { | ||
455 | ID2P(LANG_RECORD_TRIGGER_STOP), | ||
456 | ID2P(LANG_RECORD_TRIGGER_PAUSE), | ||
457 | ID2P(LANG_RECORD_TRIGGER_NEWFILESTP), | ||
458 | }; | ||
459 | |||
460 | static const unsigned char *option_name[] = { | ||
461 | [TRIGGER_MODE] = ID2P(LANG_RECORD_TRIGGER_MODE), | ||
462 | [TRIGGER_TYPE] = ID2P(LANG_RECORD_TRIGGER_TYPE), | ||
463 | [PRERECORD_TIME] = ID2P(LANG_RECORD_PRERECORD_TIME), | ||
464 | [START_THRESHOLD] = ID2P(LANG_RECORD_START_THRESHOLD), | ||
465 | [START_DURATION] = ID2P(LANG_RECORD_MIN_DURATION), | ||
466 | [STOP_THRESHOLD] = ID2P(LANG_RECORD_STOP_THRESHOLD), | ||
467 | [STOP_POSTREC] = ID2P(LANG_RECORD_STOP_POSTREC), | ||
468 | [STOP_GAP] = ID2P(LANG_RECORD_STOP_GAP) | ||
469 | }; | ||
470 | |||
471 | int old_start_thres = global_settings.rec_start_thres; | ||
472 | int old_start_duration = global_settings.rec_start_duration; | ||
473 | int old_prerecord_time = global_settings.rec_prerecord_time; | ||
474 | int old_stop_thres = global_settings.rec_stop_thres; | ||
475 | int old_stop_postrec = global_settings.rec_stop_postrec; | ||
476 | int old_stop_gap = global_settings.rec_stop_gap; | ||
477 | int old_trigger_mode = global_settings.rec_trigger_mode; | ||
478 | int old_trigger_type = global_settings.rec_trigger_type; | ||
479 | |||
480 | int offset[NB_SCREENS]; | ||
481 | int option_lines[NB_SCREENS]; | ||
482 | int w, h, i; | ||
483 | int stat_height = global_settings.statusbar ? STATUSBAR_HEIGHT : 0; | ||
484 | int pm_y[NB_SCREENS]; | ||
485 | |||
486 | int trig_xpos[NB_SCREENS]; | ||
487 | int trig_ypos[NB_SCREENS]; | ||
488 | int trig_width[NB_SCREENS]; | ||
489 | |||
490 | FOR_NB_SCREENS(i) | ||
491 | { | ||
492 | offset[i] = 0; | ||
493 | trig_xpos[i] = 0; | ||
494 | trig_ypos[i] = screens[i].height - stat_height - TRIG_HEIGHT; | ||
495 | pm_y[i] = screens[i].height - stat_height; | ||
496 | trig_width[i] = screens[i].width; | ||
497 | } | ||
498 | |||
499 | /* restart trigger with new values */ | ||
500 | settings_apply_trigger(); | ||
501 | peak_meter_trigger (global_settings.rec_trigger_mode != TRIG_MODE_OFF); | ||
502 | |||
503 | FOR_NB_SCREENS(i) | ||
504 | { | ||
505 | screens[i].clear_display(); | ||
506 | |||
507 | old_x_margin[i] = screens[i].getxmargin(); | ||
508 | old_y_margin[i] = screens[i].getymargin(); | ||
509 | if(global_settings.statusbar) | ||
510 | screens[i].setmargins(0, STATUSBAR_HEIGHT); | ||
511 | else | ||
512 | screens[i].setmargins(0, 0); | ||
513 | |||
514 | screens[i].getstringsize("M", &w, &h); | ||
515 | |||
516 | // 16 pixels are reserved for peak meter and trigger status | ||
517 | option_lines[i] = MIN(((screens[i].height) - | ||
518 | stat_height - 16)/h, | ||
519 | TRIG_OPTION_COUNT); | ||
520 | } | ||
521 | |||
522 | while (!exit_request) { | ||
523 | int button, k; | ||
524 | const char *str; | ||
525 | char option_value[TRIG_OPTION_COUNT][9]; | ||
526 | |||
527 | snprintf( | ||
528 | option_value[TRIGGER_MODE], | ||
529 | sizeof option_value[TRIGGER_MODE], | ||
530 | "%s", | ||
531 | P2STR(trigger_modes[global_settings.rec_trigger_mode])); | ||
532 | |||
533 | snprintf( | ||
534 | option_value[TRIGGER_TYPE], | ||
535 | sizeof option_value[TRIGGER_TYPE], | ||
536 | "%s", | ||
537 | P2STR(trigger_types[global_settings.rec_trigger_type])); | ||
538 | |||
539 | snprintf( | ||
540 | option_value[TRIGGER_TYPE], | ||
541 | sizeof option_value[TRIGGER_TYPE], | ||
542 | "%s", | ||
543 | P2STR(trigger_types[global_settings.rec_trigger_type])); | ||
544 | |||
545 | snprintf ( | ||
546 | option_value[PRERECORD_TIME], | ||
547 | sizeof option_value[PRERECORD_TIME], | ||
548 | "%s", | ||
549 | P2STR(prerecord_times[global_settings.rec_prerecord_time])); | ||
550 | |||
551 | /* due to value range shift (peak_meter_define_trigger) -1 is 0db */ | ||
552 | if (global_settings.rec_start_thres == -1) { | ||
553 | str = str(LANG_OFF); | ||
554 | } else { | ||
555 | str = create_thres_str(global_settings.rec_start_thres); | ||
556 | } | ||
557 | snprintf( | ||
558 | option_value[START_THRESHOLD], | ||
559 | sizeof option_value[START_THRESHOLD], | ||
560 | "%s", | ||
561 | str); | ||
562 | |||
563 | snprintf( | ||
564 | option_value[START_DURATION], | ||
565 | sizeof option_value[START_DURATION], | ||
566 | "%s", | ||
567 | trig_durations[global_settings.rec_start_duration]); | ||
568 | |||
569 | |||
570 | if (global_settings.rec_stop_thres <= INF_DB) { | ||
571 | str = str(LANG_OFF); | ||
572 | } else { | ||
573 | str = create_thres_str(global_settings.rec_stop_thres); | ||
574 | } | ||
575 | snprintf( | ||
576 | option_value[STOP_THRESHOLD], | ||
577 | sizeof option_value[STOP_THRESHOLD], | ||
578 | "%s", | ||
579 | str); | ||
580 | |||
581 | snprintf( | ||
582 | option_value[STOP_POSTREC], | ||
583 | sizeof option_value[STOP_POSTREC], | ||
584 | "%s", | ||
585 | trig_durations[global_settings.rec_stop_postrec]); | ||
586 | |||
587 | snprintf( | ||
588 | option_value[STOP_GAP], | ||
589 | sizeof option_value[STOP_GAP], | ||
590 | "%s", | ||
591 | trig_durations[global_settings.rec_stop_gap]); | ||
592 | |||
593 | FOR_NB_SCREENS(i) | ||
594 | { | ||
595 | screens[i].set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
596 | screens[i].fillrect(0, stat_height, screens[i].width, | ||
597 | screens[i].height - stat_height); | ||
598 | screens[i].set_drawmode(DRMODE_SOLID); | ||
599 | } | ||
600 | |||
601 | gui_syncstatusbar_draw(&statusbars, true); | ||
602 | |||
603 | /* reselect FONT_SYSFONT as status_draw has changed the font */ | ||
604 | /*lcd_setfont(FONT_SYSFIXED);*/ | ||
605 | |||
606 | FOR_NB_SCREENS(i) | ||
607 | { | ||
608 | for (k = 0; k < option_lines[i]; k++) { | ||
609 | int x, y; | ||
610 | |||
611 | str = P2STR(option_name[k + offset[i]]); | ||
612 | screens[i].putsxy((option_lines[i] < TRIG_OPTION_COUNT) ? 5 : 0, | ||
613 | stat_height + k * h, str); | ||
614 | |||
615 | str = option_value[k + offset[i]]; | ||
616 | screens[i].getstringsize(str, &w, &h); | ||
617 | y = stat_height + k * h; | ||
618 | x = screens[i].width - w; | ||
619 | screens[i].putsxy(x, y, str); | ||
620 | if ((int)selected == (k + offset[i])) { | ||
621 | screens[i].set_drawmode(DRMODE_COMPLEMENT); | ||
622 | screens[i].fillrect(x, y, w, h); | ||
623 | screens[i].set_drawmode(DRMODE_SOLID); | ||
624 | } | ||
625 | } | ||
626 | if (option_lines[i] < TRIG_OPTION_COUNT) | ||
627 | gui_scrollbar_draw(&screens[i], 0, stat_height, | ||
628 | 4, screens[i].height - 16 - stat_height, | ||
629 | TRIG_OPTION_COUNT, offset[i], offset[i] + option_lines[i], | ||
630 | VERTICAL); | ||
631 | } | ||
632 | |||
633 | peak_meter_draw_trig(trig_xpos, trig_ypos, trig_width, NB_SCREENS); | ||
634 | button = peak_meter_draw_get_btn(0, pm_y, 8, NB_SCREENS); | ||
635 | |||
636 | FOR_NB_SCREENS(i) | ||
637 | screens[i].update(); | ||
638 | |||
639 | switch (button) { | ||
640 | case ACTION_STD_CANCEL: | ||
641 | gui_syncsplash(50, true, str(LANG_MENU_SETTING_CANCEL)); | ||
642 | global_settings.rec_start_thres = old_start_thres; | ||
643 | global_settings.rec_start_duration = old_start_duration; | ||
644 | global_settings.rec_prerecord_time = old_prerecord_time; | ||
645 | global_settings.rec_stop_thres = old_stop_thres; | ||
646 | global_settings.rec_stop_postrec = old_stop_postrec; | ||
647 | global_settings.rec_stop_gap = old_stop_gap; | ||
648 | global_settings.rec_trigger_mode = old_trigger_mode; | ||
649 | global_settings.rec_trigger_type = old_trigger_type; | ||
650 | exit_request = true; | ||
651 | break; | ||
652 | |||
653 | case ACTION_REC_PAUSE: | ||
654 | exit_request = true; | ||
655 | break; | ||
656 | |||
657 | case ACTION_STD_PREV: | ||
658 | selected += TRIG_OPTION_COUNT - 1; | ||
659 | selected %= TRIG_OPTION_COUNT; | ||
660 | FOR_NB_SCREENS(i) | ||
661 | { | ||
662 | offset[i] = MIN(offset[i], (int)selected); | ||
663 | offset[i] = MAX(offset[i], (int)selected - option_lines[i] + 1); | ||
664 | } | ||
665 | break; | ||
666 | |||
667 | case ACTION_STD_NEXT: | ||
668 | selected ++; | ||
669 | selected %= TRIG_OPTION_COUNT; | ||
670 | FOR_NB_SCREENS(i) | ||
671 | { | ||
672 | offset[i] = MIN(offset[i], (int)selected); | ||
673 | offset[i] = MAX(offset[i], (int)selected - option_lines[i] + 1); | ||
674 | } | ||
675 | break; | ||
676 | |||
677 | case ACTION_SETTINGS_INC: | ||
678 | switch (selected) { | ||
679 | case TRIGGER_MODE: | ||
680 | global_settings.rec_trigger_mode ++; | ||
681 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
682 | break; | ||
683 | |||
684 | case TRIGGER_TYPE: | ||
685 | global_settings.rec_trigger_type ++; | ||
686 | global_settings.rec_trigger_type %= TRIGGER_TYPE_COUNT; | ||
687 | break; | ||
688 | |||
689 | case PRERECORD_TIME: | ||
690 | global_settings.rec_prerecord_time ++; | ||
691 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
692 | break; | ||
693 | |||
694 | case START_THRESHOLD: | ||
695 | change_threshold(&global_settings.rec_start_thres, 1); | ||
696 | break; | ||
697 | |||
698 | case START_DURATION: | ||
699 | global_settings.rec_start_duration ++; | ||
700 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
701 | break; | ||
702 | |||
703 | case STOP_THRESHOLD: | ||
704 | change_threshold(&global_settings.rec_stop_thres, 1); | ||
705 | break; | ||
706 | |||
707 | case STOP_POSTREC: | ||
708 | global_settings.rec_stop_postrec ++; | ||
709 | global_settings.rec_stop_postrec %= TRIG_DURATION_COUNT; | ||
710 | break; | ||
711 | |||
712 | case STOP_GAP: | ||
713 | global_settings.rec_stop_gap ++; | ||
714 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
715 | break; | ||
716 | |||
717 | case TRIG_OPTION_COUNT: | ||
718 | // avoid compiler warnings | ||
719 | break; | ||
720 | } | ||
721 | peak_meter_trigger(global_settings.rec_trigger_mode!=TRIG_OFF); | ||
722 | settings_apply_trigger(); | ||
723 | break; | ||
724 | |||
725 | case ACTION_SETTINGS_DEC: | ||
726 | switch (selected) { | ||
727 | case TRIGGER_MODE: | ||
728 | global_settings.rec_trigger_mode+=TRIGGER_MODE_COUNT-1; | ||
729 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
730 | break; | ||
731 | |||
732 | case TRIGGER_TYPE: | ||
733 | global_settings.rec_trigger_type+=TRIGGER_TYPE_COUNT-1; | ||
734 | global_settings.rec_trigger_type %= TRIGGER_TYPE_COUNT; | ||
735 | break; | ||
736 | |||
737 | case PRERECORD_TIME: | ||
738 | global_settings.rec_prerecord_time += PRERECORD_TIMES_COUNT - 1; | ||
739 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
740 | break; | ||
741 | |||
742 | case START_THRESHOLD: | ||
743 | change_threshold(&global_settings.rec_start_thres, -1); | ||
744 | break; | ||
745 | |||
746 | case START_DURATION: | ||
747 | global_settings.rec_start_duration += TRIG_DURATION_COUNT-1; | ||
748 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
749 | break; | ||
750 | |||
751 | case STOP_THRESHOLD: | ||
752 | change_threshold(&global_settings.rec_stop_thres, -1); | ||
753 | break; | ||
754 | |||
755 | case STOP_POSTREC: | ||
756 | global_settings.rec_stop_postrec += | ||
757 | TRIG_DURATION_COUNT - 1; | ||
758 | global_settings.rec_stop_postrec %= | ||
759 | TRIG_DURATION_COUNT; | ||
760 | break; | ||
761 | |||
762 | case STOP_GAP: | ||
763 | global_settings.rec_stop_gap += | ||
764 | TRIG_DURATION_COUNT - 1; | ||
765 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
766 | break; | ||
767 | |||
768 | case TRIG_OPTION_COUNT: | ||
769 | // avoid compiler warnings | ||
770 | break; | ||
771 | } | ||
772 | peak_meter_trigger(global_settings.rec_trigger_mode!=TRIG_OFF); | ||
773 | settings_apply_trigger(); | ||
774 | break; | ||
775 | |||
776 | case ACTION_REC_F2: | ||
777 | peak_meter_trigger(true); | ||
778 | break; | ||
779 | |||
780 | case SYS_USB_CONNECTED: | ||
781 | if(default_event_handler(button) == SYS_USB_CONNECTED) { | ||
782 | retval = true; | ||
783 | exit_request = true; | ||
784 | } | ||
785 | break; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | peak_meter_trigger(false); | ||
790 | FOR_NB_SCREENS(i) | ||
791 | { | ||
792 | screens[i].setfont(FONT_UI); | ||
793 | screens[i].setmargins(old_x_margin[i], old_y_margin[i]); | ||
794 | } | ||
795 | action_signalscreenchange(); | ||
796 | return retval; | ||
797 | } | ||
798 | |||
799 | MENUITEM_FUNCTION(rectrigger_item, ID2P(LANG_RECORD_TRIGGER), | ||
800 | (int(*)(void))rectrigger, NULL, Icon_Menu_setting); | ||
801 | |||
802 | |||
803 | |||
804 | |||
805 | |||
806 | |||
807 | |||
808 | |||
809 | MAKE_MENU(recording_setting_menu, ID2P(LANG_RECORDING_SETTINGS), NULL, Icon_Recording, | ||
810 | #if CONFIG_CODEC == MAS3587F | ||
811 | &rec_quality, | ||
812 | #endif | ||
813 | #if CONFIG_CODEC == SWCODEC | ||
814 | &recformat, &enc_global_config_menu_item, | ||
815 | #endif | ||
816 | &recfrequency, &recsource, /* recsource not shown if no_source */ | ||
817 | &recchannels, | ||
818 | #if CONFIG_CODEC == MAS3587F | ||
819 | &rec_editable, | ||
820 | #endif | ||
821 | &filesplitoptionsmenu, | ||
822 | &rec_prerecord_time, | ||
823 | &recdirectory, | ||
824 | #if CONFIG_BACKLIGHT | ||
825 | &cliplight, | ||
826 | #endif | ||
827 | &rectrigger_item, | ||
828 | #ifdef HAVE_AGC | ||
829 | &agc_preset, &agc_cliptime, | ||
830 | #endif | ||
831 | ); | ||
832 | |||
833 | bool recording_menu(bool no_source) | ||
834 | { | ||
835 | no_source_in_menu = no_source; | ||
836 | return do_menu(&recording_setting_menu, NULL); | ||
837 | }; | ||
838 | |||
34 | MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_SETTINGS), | 839 | MENUITEM_FUNCTION_WPARAM(recording_settings, ID2P(LANG_RECORDING_SETTINGS), |
35 | (int (*)(void*))recording_menu,0, NULL, Icon_NOICON); | 840 | (int (*)(void*))recording_menu,0, NULL, Icon_NOICON); |
36 | #endif | ||
diff --git a/apps/settings_list.c b/apps/settings_list.c index 67974c52d6..4dce7ae157 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c | |||
@@ -89,6 +89,22 @@ static const char trig_durations_conf [] = | |||
89 | # endif | 89 | # endif |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | static long rectime_getlang(int value) | ||
93 | { | ||
94 | if (value == 0) | ||
95 | return LANG_OFF; | ||
96 | return TALK_ID(value, UNIT_SEC); | ||
97 | } | ||
98 | static void rectime_formatter(char *buffer, int buffer_size, | ||
99 | int val, const char *unit) | ||
100 | { | ||
101 | (void)unit; | ||
102 | if (val == 0) | ||
103 | strcpy(buffer, str(LANG_OFF)); | ||
104 | else | ||
105 | snprintf(buffer, buffer_size, "%d s", val); | ||
106 | } | ||
107 | |||
92 | #endif /* HAVE_RECORDING */ | 108 | #endif /* HAVE_RECORDING */ |
93 | 109 | ||
94 | #if CONFIG_BACKLIGHT | 110 | #if CONFIG_BACKLIGHT |
@@ -700,18 +716,35 @@ const struct settings_list settings[] = { | |||
700 | 716 | ||
701 | #ifdef HAVE_RECORDING | 717 | #ifdef HAVE_RECORDING |
702 | /* recording */ | 718 | /* recording */ |
703 | {F_T_INT,&global_settings.rec_timesplit, LANG_SPLIT_TIME, INT(0),"rec timesplit", | 719 | STRINGCHOICE_SETTING(0, rec_timesplit, LANG_SPLIT_TIME, 0, |
720 | "rec timesplit", | ||
704 | "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00," | 721 | "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00," |
705 | "04:00,06:00,08:00,10:00,12:00,18:00,24:00",UNUSED}, | 722 | "04:00,06:00,08:00,10:00,12:00,18:00,24:00", |
706 | {F_T_INT,&global_settings.rec_sizesplit,LANG_SPLIT_SIZE,INT(0),"rec sizesplit", | 723 | NULL, 16, LANG_OFF, |
724 | TALK_ID(5, UNIT_MIN), TALK_ID(10, UNIT_MIN), TALK_ID(15, UNIT_MIN), | ||
725 | TALK_ID(30, UNIT_MIN), TALK_ID(60, UNIT_MIN), TALK_ID(74, UNIT_MIN), | ||
726 | TALK_ID(80, UNIT_MIN), TALK_ID(2, UNIT_HOUR), TALK_ID(4, UNIT_HOUR), | ||
727 | TALK_ID(6, UNIT_HOUR), TALK_ID(8, UNIT_HOUR), TALK_ID(10, UNIT_HOUR), | ||
728 | TALK_ID(12, UNIT_HOUR), TALK_ID(18, UNIT_HOUR), TALK_ID(20, UNIT_HOUR), | ||
729 | TALK_ID(24, UNIT_HOUR)), | ||
730 | STRINGCHOICE_SETTING(0, rec_sizesplit, LANG_SPLIT_SIZE, 0, | ||
731 | "rec sizesplit", | ||
707 | "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB," | 732 | "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB," |
708 | "256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB",UNUSED}, | 733 | "256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB", |
734 | NULL, 16, LANG_OFF, | ||
735 | TALK_ID(5, UNIT_MB), TALK_ID(10, UNIT_MB), TALK_ID(15, UNIT_MB), | ||
736 | TALK_ID(32, UNIT_MB), TALK_ID(64, UNIT_MB), TALK_ID(75, UNIT_MB), | ||
737 | TALK_ID(100, UNIT_MB), TALK_ID(128, UNIT_MB), TALK_ID(256, UNIT_MB), | ||
738 | TALK_ID(512, UNIT_MB), TALK_ID(650, UNIT_MB), TALK_ID(700, UNIT_MB), | ||
739 | TALK_ID(1024, UNIT_MB), TALK_ID(1536, UNIT_MB), TALK_ID(1792, UNIT_MB)), | ||
709 | {F_T_INT,&global_settings.rec_channels,LANG_RECORDING_CHANNELS,INT(0), | 740 | {F_T_INT,&global_settings.rec_channels,LANG_RECORDING_CHANNELS,INT(0), |
710 | "rec channels","stereo,mono",UNUSED}, | 741 | "rec channels","stereo,mono",UNUSED}, |
711 | {F_T_INT,&global_settings.rec_split_type,LANG_RECORDING_CHANNELS,INT(0), | 742 | CHOICE_SETTING(0, rec_split_type, LANG_SPLIT_TYPE, 0 , |
712 | "rec split type","Split, Stop",UNUSED}, | 743 | "rec split type", "Split, Stop", NULL, 2, |
713 | {F_T_INT,&global_settings.rec_split_method,LANG_SPLIT_MEASURE,INT(0), | 744 | ID2P(LANG_START_NEW_FILE), ID2P(LANG_STOP_RECORDING)), |
714 | "rec split method","Time,Filesize",UNUSED}, | 745 | CHOICE_SETTING(0, rec_split_method, LANG_SPLIT_MEASURE, 0 , |
746 | "rec split method", "Time,Filesize", NULL, 2, | ||
747 | ID2P(LANG_REC_TIME), ID2P(LANG_REC_SIZE)), | ||
715 | {F_T_INT,&global_settings.rec_source,LANG_RECORDING_SOURCE,INT(0), | 748 | {F_T_INT,&global_settings.rec_source,LANG_RECORDING_SOURCE,INT(0), |
716 | "rec source","mic,line" | 749 | "rec source","mic,line" |
717 | #ifdef HAVE_SPDIF_IN | 750 | #ifdef HAVE_SPDIF_IN |
@@ -721,11 +754,24 @@ const struct settings_list settings[] = { | |||
721 | ",fmradio" | 754 | ",fmradio" |
722 | #endif | 755 | #endif |
723 | ,UNUSED}, | 756 | ,UNUSED}, |
724 | {F_T_INT,&global_settings.rec_prerecord_time,LANG_RECORD_PRERECORD_TIME, | 757 | INT_SETTING(0, rec_prerecord_time, LANG_RECORD_PRERECORD_TIME, |
725 | INT(0),"prerecording time",NULL,UNUSED}, | 758 | 0, "prerecording time", |
759 | UNIT_SEC, 0, 30, 1, rectime_formatter, rectime_getlang, NULL), | ||
726 | {F_T_INT,&global_settings.rec_directory,LANG_RECORD_DIRECTORY, | 760 | {F_T_INT,&global_settings.rec_directory,LANG_RECORD_DIRECTORY, |
727 | INT(0),"rec directory",REC_BASE_DIR ",current",UNUSED}, | 761 | INT(0),"rec directory",REC_BASE_DIR ",current",UNUSED}, |
728 | #if CONFIG_BACKLIGHT | 762 | #if CONFIG_BACKLIGHT |
763 | CHOICE_SETTING(0, cliplight, LANG_CLIP_LIGHT, 0 , | ||
764 | "cliplight", "off,main,both,remote", NULL, | ||
765 | #ifdef HAVE_REMOTE_LCD | ||
766 | 4, | ||
767 | #else | ||
768 | 2, | ||
769 | #endif | ||
770 | ID2P(LANG_OFF), ID2P(LANG_MAIN_UNIT) | ||
771 | #ifdef HAVE_REMOTE_LCD | ||
772 | , ID2P(LANG_REMOTE_MAIN), ID2P(LANG_REMOTE_UNIT) | ||
773 | #endif | ||
774 | ), | ||
729 | {F_T_INT,&global_settings.cliplight,LANG_CLIP_LIGHT,INT(0), | 775 | {F_T_INT,&global_settings.cliplight,LANG_CLIP_LIGHT,INT(0), |
730 | "cliplight","off,main,both,remote",UNUSED}, | 776 | "cliplight","off,main,both,remote",UNUSED}, |
731 | #endif | 777 | #endif |
@@ -739,10 +785,10 @@ const struct settings_list settings[] = { | |||
739 | #if CONFIG_CODEC == MAS3587F | 785 | #if CONFIG_CODEC == MAS3587F |
740 | {F_T_INT,&global_settings.rec_frequency,LANG_RECORDING_FREQUENCY, | 786 | {F_T_INT,&global_settings.rec_frequency,LANG_RECORDING_FREQUENCY, |
741 | INT(0),"rec frequency","44,48,32,22,24,16",UNUSED}, | 787 | INT(0),"rec frequency","44,48,32,22,24,16",UNUSED}, |
742 | {F_T_INT,&global_settings.rec_quality,LANG_RECORDING_QUALITY,INT(5), | 788 | INT_SETTING(0, rec_quality, LANG_RECORDING_QUALITY, 5, "rec quality", |
743 | "rec quality",NULL,UNUSED}, | 789 | UNIT_INT, 0, 7, 1, NULL, NULL, NULL), |
744 | OFFON_SETTING(0,rec_editable,LANG_RECORDING_EDITABLE, | 790 | OFFON_SETTING(0,rec_editable,LANG_RECORDING_EDITABLE, |
745 | false,"editable recordings",NULL), | 791 | false,"editable recordings",NULL), |
746 | #endif /* CONFIG_CODEC == MAS3587F */ | 792 | #endif /* CONFIG_CODEC == MAS3587F */ |
747 | #if CONFIG_CODEC == SWCODEC | 793 | #if CONFIG_CODEC == SWCODEC |
748 | {F_T_INT,&global_settings.rec_frequency,LANG_RECORDING_FREQUENCY,INT(REC_FREQ_DEFAULT), | 794 | {F_T_INT,&global_settings.rec_frequency,LANG_RECORDING_FREQUENCY,INT(REC_FREQ_DEFAULT), |
diff --git a/apps/sound_menu.c b/apps/sound_menu.c deleted file mode 100644 index d7b7b80d6e..0000000000 --- a/apps/sound_menu.c +++ /dev/null | |||
@@ -1,968 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <stdbool.h> | ||
23 | #include "system.h" | ||
24 | #include "kernel.h" | ||
25 | #include "lcd.h" | ||
26 | #include "menu.h" | ||
27 | #include "button.h" | ||
28 | #include "mp3_playback.h" | ||
29 | #include "settings.h" | ||
30 | #include "statusbar.h" | ||
31 | #include "screens.h" | ||
32 | #ifdef HAVE_LCD_BITMAP | ||
33 | #include "icons.h" | ||
34 | #include "font.h" | ||
35 | #include "scrollbar.h" | ||
36 | #endif | ||
37 | #include "lang.h" | ||
38 | #include "sprintf.h" | ||
39 | #include "talk.h" | ||
40 | #include "misc.h" | ||
41 | #include "sound.h" | ||
42 | #ifdef HAVE_RECORDING | ||
43 | #include "audio.h" | ||
44 | #if CONFIG_TUNER | ||
45 | #include "radio.h" | ||
46 | #endif | ||
47 | #endif | ||
48 | #ifdef HAVE_RECORDING | ||
49 | #include "peakmeter.h" | ||
50 | #include "mas.h" | ||
51 | #endif | ||
52 | #include "splash.h" | ||
53 | #if CONFIG_CODEC == SWCODEC | ||
54 | #include "dsp.h" | ||
55 | #include "menus/eq_menu.h" | ||
56 | #include "pcmbuf.h" | ||
57 | #ifdef HAVE_RECORDING | ||
58 | #include "enc_config.h" | ||
59 | #endif | ||
60 | #include "general.h" | ||
61 | #endif | ||
62 | #include "action.h" | ||
63 | |||
64 | #ifdef HAVE_RECORDING | ||
65 | static bool recsource(void) | ||
66 | { | ||
67 | int n_opts = AUDIO_NUM_SOURCES; | ||
68 | |||
69 | static const struct opt_items names[AUDIO_NUM_SOURCES] = { | ||
70 | [AUDIO_SRC_MIC] = { STR(LANG_RECORDING_SRC_MIC) }, | ||
71 | [AUDIO_SRC_LINEIN] = { STR(LANG_RECORDING_SRC_LINE) }, | ||
72 | #ifdef HAVE_SPDIF_IN | ||
73 | [AUDIO_SRC_SPDIF] = { STR(LANG_RECORDING_SRC_DIGITAL) }, | ||
74 | #endif | ||
75 | #ifdef HAVE_FMRADIO_IN | ||
76 | [AUDIO_SRC_FMRADIO] = { STR(LANG_FM_RADIO) } | ||
77 | #endif | ||
78 | }; | ||
79 | |||
80 | /* caveat: assumes it's the last item! */ | ||
81 | #ifdef HAVE_FMRADIO_IN | ||
82 | if (!radio_hardware_present()) | ||
83 | n_opts--; | ||
84 | #endif | ||
85 | |||
86 | return set_option(str(LANG_RECORDING_SOURCE), | ||
87 | &global_settings.rec_source, INT, names, | ||
88 | n_opts, NULL ); | ||
89 | } | ||
90 | |||
91 | #if CONFIG_CODEC == MAS3587F | ||
92 | static bool recquality(void) | ||
93 | { | ||
94 | return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, | ||
95 | &global_settings.rec_quality, | ||
96 | NULL, 1, 0, 7, NULL ); | ||
97 | } | ||
98 | |||
99 | static bool receditable(void) | ||
100 | { | ||
101 | return set_bool(str(LANG_RECORDING_EDITABLE), | ||
102 | &global_settings.rec_editable); | ||
103 | } | ||
104 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
105 | |||
106 | #if CONFIG_CODEC == SWCODEC | ||
107 | /* Makes an options list from a source list of options and indexes */ | ||
108 | static void make_options_from_indexes(const struct opt_items *src_names, | ||
109 | const long *src_indexes, | ||
110 | int n_indexes, | ||
111 | struct opt_items *dst_names) | ||
112 | { | ||
113 | while (--n_indexes >= 0) | ||
114 | dst_names[n_indexes] = src_names[src_indexes[n_indexes]]; | ||
115 | } /* make_options_from_indexes */ | ||
116 | |||
117 | static bool recformat(void) | ||
118 | { | ||
119 | static const struct opt_items names[REC_NUM_FORMATS] = { | ||
120 | [REC_FORMAT_AIFF] = { STR(LANG_AFMT_AIFF) }, | ||
121 | [REC_FORMAT_MPA_L3] = { STR(LANG_AFMT_MPA_L3) }, | ||
122 | [REC_FORMAT_WAVPACK] = { STR(LANG_AFMT_WAVPACK) }, | ||
123 | [REC_FORMAT_PCM_WAV] = { STR(LANG_AFMT_PCM_WAV) }, | ||
124 | }; | ||
125 | |||
126 | int rec_format = global_settings.rec_format; | ||
127 | bool res = set_option(str(LANG_RECORDING_FORMAT), &rec_format, INT, | ||
128 | names, REC_NUM_FORMATS, NULL ); | ||
129 | |||
130 | if (rec_format != global_settings.rec_format) | ||
131 | { | ||
132 | global_settings.rec_format = rec_format; | ||
133 | enc_global_settings_apply(); | ||
134 | } | ||
135 | |||
136 | return res; | ||
137 | } /* recformat */ | ||
138 | |||
139 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
140 | |||
141 | static bool recfrequency(void) | ||
142 | { | ||
143 | #if CONFIG_CODEC == MAS3587F | ||
144 | static const struct opt_items names[6] = { | ||
145 | { "44.1kHz", TALK_ID(44, UNIT_KHZ) }, | ||
146 | { "48kHz", TALK_ID(48, UNIT_KHZ) }, | ||
147 | { "32kHz", TALK_ID(32, UNIT_KHZ) }, | ||
148 | { "22.05kHz", TALK_ID(22, UNIT_KHZ) }, | ||
149 | { "24kHz", TALK_ID(24, UNIT_KHZ) }, | ||
150 | { "16kHz", TALK_ID(16, UNIT_KHZ) } | ||
151 | }; | ||
152 | return set_option(str(LANG_RECORDING_FREQUENCY), | ||
153 | &global_settings.rec_frequency, INT, | ||
154 | names, 6, NULL ); | ||
155 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
156 | |||
157 | #if CONFIG_CODEC == SWCODEC | ||
158 | static const struct opt_items names[REC_NUM_FREQ] = { | ||
159 | REC_HAVE_96_([REC_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },) | ||
160 | REC_HAVE_88_([REC_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },) | ||
161 | REC_HAVE_64_([REC_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },) | ||
162 | REC_HAVE_48_([REC_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },) | ||
163 | REC_HAVE_44_([REC_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },) | ||
164 | REC_HAVE_32_([REC_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },) | ||
165 | REC_HAVE_24_([REC_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },) | ||
166 | REC_HAVE_22_([REC_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },) | ||
167 | REC_HAVE_16_([REC_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },) | ||
168 | REC_HAVE_12_([REC_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },) | ||
169 | REC_HAVE_11_([REC_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },) | ||
170 | REC_HAVE_8_( [REC_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },) | ||
171 | }; | ||
172 | |||
173 | struct opt_items opts[REC_NUM_FREQ]; | ||
174 | unsigned long table[REC_NUM_FREQ]; | ||
175 | int n_opts; | ||
176 | int rec_frequency; | ||
177 | bool ret; | ||
178 | |||
179 | #ifdef HAVE_SPDIF_IN | ||
180 | if (global_settings.rec_source == AUDIO_SRC_SPDIF) | ||
181 | { | ||
182 | /* Inform user that frequency follows the source's frequency */ | ||
183 | opts[0].string = ID2P(LANG_SOURCE_FREQUENCY); | ||
184 | opts[0].voice_id = LANG_SOURCE_FREQUENCY; | ||
185 | n_opts = 1; | ||
186 | rec_frequency = 0; | ||
187 | } | ||
188 | else | ||
189 | #endif | ||
190 | { | ||
191 | struct encoder_caps caps; | ||
192 | struct encoder_config cfg; | ||
193 | |||
194 | cfg.rec_format = global_settings.rec_format; | ||
195 | global_to_encoder_config(&cfg); | ||
196 | |||
197 | if (!enc_get_caps(&cfg, &caps, true)) | ||
198 | return false; | ||
199 | |||
200 | /* Construct samplerate menu based upon encoder settings */ | ||
201 | n_opts = make_list_from_caps32(REC_SAMPR_CAPS, NULL, | ||
202 | caps.samplerate_caps, table); | ||
203 | |||
204 | if (n_opts == 0) | ||
205 | return false; /* No common flags...?? */ | ||
206 | |||
207 | make_options_from_indexes(names, table, n_opts, opts); | ||
208 | |||
209 | /* Find closest rate that the potentially restricted list | ||
210 | comes to */ | ||
211 | make_list_from_caps32(REC_SAMPR_CAPS, rec_freq_sampr, | ||
212 | caps.samplerate_caps, table); | ||
213 | |||
214 | rec_frequency = round_value_to_list32( | ||
215 | rec_freq_sampr[global_settings.rec_frequency], | ||
216 | table, n_opts, false); | ||
217 | } | ||
218 | |||
219 | ret = set_option(str(LANG_RECORDING_FREQUENCY), | ||
220 | &rec_frequency, INT, opts, n_opts, NULL ); | ||
221 | |||
222 | if (!ret | ||
223 | #ifdef HAVE_SPDIF_IN | ||
224 | && global_settings.rec_source != AUDIO_SRC_SPDIF | ||
225 | #endif | ||
226 | ) | ||
227 | { | ||
228 | /* Translate back to full index */ | ||
229 | global_settings.rec_frequency = | ||
230 | round_value_to_list32(table[rec_frequency], | ||
231 | rec_freq_sampr, | ||
232 | REC_NUM_FREQ, | ||
233 | false); | ||
234 | } | ||
235 | |||
236 | return ret; | ||
237 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
238 | } /* recfrequency */ | ||
239 | |||
240 | static bool recchannels(void) | ||
241 | { | ||
242 | static const struct opt_items names[CHN_NUM_MODES] = { | ||
243 | [CHN_MODE_STEREO] = { STR(LANG_CHANNEL_STEREO) }, | ||
244 | [CHN_MODE_MONO] = { STR(LANG_CHANNEL_MONO) } | ||
245 | }; | ||
246 | #if CONFIG_CODEC == MAS3587F | ||
247 | return set_option(str(LANG_RECORDING_CHANNELS), | ||
248 | &global_settings.rec_channels, INT, | ||
249 | names, CHN_NUM_MODES, NULL ); | ||
250 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
251 | |||
252 | #if CONFIG_CODEC == SWCODEC | ||
253 | struct opt_items opts[CHN_NUM_MODES]; | ||
254 | long table[CHN_NUM_MODES]; | ||
255 | struct encoder_caps caps; | ||
256 | struct encoder_config cfg; | ||
257 | int n_opts; | ||
258 | int rec_channels; | ||
259 | bool ret; | ||
260 | |||
261 | cfg.rec_format = global_settings.rec_format; | ||
262 | global_to_encoder_config(&cfg); | ||
263 | |||
264 | if (!enc_get_caps(&cfg, &caps, true)) | ||
265 | return false; | ||
266 | |||
267 | n_opts = make_list_from_caps32(CHN_CAP_ALL, NULL, | ||
268 | caps.channel_caps, table); | ||
269 | |||
270 | rec_channels = round_value_to_list32(global_settings.rec_channels, | ||
271 | table, n_opts, false); | ||
272 | |||
273 | make_options_from_indexes(names, table, n_opts, opts); | ||
274 | |||
275 | ret = set_option(str(LANG_RECORDING_CHANNELS), &rec_channels, | ||
276 | INT, opts, n_opts, NULL ); | ||
277 | |||
278 | if (!ret) | ||
279 | global_settings.rec_channels = table[rec_channels]; | ||
280 | |||
281 | return ret; | ||
282 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
283 | } | ||
284 | |||
285 | static bool rectimesplit(void) | ||
286 | { | ||
287 | static const struct opt_items names[] = { | ||
288 | { STR(LANG_OFF) }, | ||
289 | { "00:05" , TALK_ID(5, UNIT_MIN) }, | ||
290 | { "00:10" , TALK_ID(10, UNIT_MIN) }, | ||
291 | { "00:15" , TALK_ID(15, UNIT_MIN) }, | ||
292 | { "00:30" , TALK_ID(30, UNIT_MIN) }, | ||
293 | { "01:00" , TALK_ID(1, UNIT_HOUR) }, | ||
294 | { "01:14" , TALK_ID(74, UNIT_MIN) }, | ||
295 | { "01:20" , TALK_ID(80, UNIT_MIN) }, | ||
296 | { "02:00" , TALK_ID(2, UNIT_HOUR) }, | ||
297 | { "04:00" , TALK_ID(4, UNIT_HOUR) }, | ||
298 | { "06:00" , TALK_ID(6, UNIT_HOUR) }, | ||
299 | { "08:00" , TALK_ID(8, UNIT_HOUR) }, | ||
300 | { "10:00" , TALK_ID(10, UNIT_HOUR) }, | ||
301 | { "12:00" , TALK_ID(12, UNIT_HOUR) }, | ||
302 | { "18:00" , TALK_ID(18, UNIT_HOUR) }, | ||
303 | { "24:00" , TALK_ID(24, UNIT_HOUR) } | ||
304 | }; | ||
305 | return set_option(str(LANG_SPLIT_TIME), | ||
306 | &global_settings.rec_timesplit, INT, | ||
307 | names, 16, NULL ); | ||
308 | } | ||
309 | |||
310 | static bool recsizesplit(void) | ||
311 | { | ||
312 | static const struct opt_items names[] = { | ||
313 | { STR(LANG_OFF) }, | ||
314 | { "5MB" , TALK_ID(5, UNIT_MB) }, | ||
315 | { "10MB" , TALK_ID(10, UNIT_MB) }, | ||
316 | { "15MB" , TALK_ID(15, UNIT_MB) }, | ||
317 | { "32MB" , TALK_ID(32, UNIT_MB) }, | ||
318 | { "64MB" , TALK_ID(64, UNIT_MB) }, | ||
319 | { "75MB" , TALK_ID(75, UNIT_MB) }, | ||
320 | { "100MB" , TALK_ID(100, UNIT_MB) }, | ||
321 | { "128MB" , TALK_ID(128, UNIT_MB) }, | ||
322 | { "256MB" , TALK_ID(256, UNIT_MB) }, | ||
323 | { "512MB" , TALK_ID(512, UNIT_MB) }, | ||
324 | { "650MB" , TALK_ID(650, UNIT_MB) }, | ||
325 | { "700MB" , TALK_ID(700, UNIT_MB) }, | ||
326 | { "1GB" , TALK_ID(1024, UNIT_MB) }, | ||
327 | { "1.5GB" , TALK_ID(1536, UNIT_MB) }, | ||
328 | { "1.75GB" , TALK_ID(1792, UNIT_MB) } | ||
329 | }; | ||
330 | return set_option(str(LANG_SPLIT_SIZE), | ||
331 | &global_settings.rec_sizesplit, INT, | ||
332 | names, 16, NULL ); | ||
333 | } | ||
334 | |||
335 | static bool splitmethod(void) | ||
336 | { | ||
337 | static const struct opt_items names[] = { | ||
338 | { STR(LANG_REC_TIME) }, | ||
339 | { STR(LANG_REC_SIZE) }, | ||
340 | }; | ||
341 | bool ret; | ||
342 | ret=set_option( str(LANG_SPLIT_MEASURE), | ||
343 | &global_settings.rec_split_method, INT, names, 2, NULL); | ||
344 | return ret; | ||
345 | } | ||
346 | |||
347 | static bool splittype(void) | ||
348 | { | ||
349 | static const struct opt_items names[] = { | ||
350 | { STR(LANG_START_NEW_FILE) }, | ||
351 | { STR(LANG_STOP_RECORDING) }, | ||
352 | }; | ||
353 | bool ret; | ||
354 | ret=set_option( str(LANG_SPLIT_TYPE), | ||
355 | &global_settings.rec_split_type, INT, names, 2, NULL); | ||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | static bool filesplitoptionsmenu(void) | ||
360 | { | ||
361 | int m; | ||
362 | bool result; | ||
363 | |||
364 | static const struct menu_item items[] = { | ||
365 | { ID2P(LANG_SPLIT_MEASURE), splitmethod }, | ||
366 | { ID2P(LANG_SPLIT_TYPE), splittype }, | ||
367 | { ID2P(LANG_SPLIT_TIME), rectimesplit }, | ||
368 | { ID2P(LANG_SPLIT_SIZE), recsizesplit } | ||
369 | }; | ||
370 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, | ||
371 | NULL, NULL, NULL); | ||
372 | result = menu_run(m); | ||
373 | menu_exit(m); | ||
374 | return result; | ||
375 | } | ||
376 | static bool recprerecord(void) | ||
377 | { | ||
378 | static const struct opt_items names[] = { | ||
379 | { STR(LANG_OFF) }, | ||
380 | { "1s", TALK_ID(1, UNIT_SEC) }, | ||
381 | { "2s", TALK_ID(2, UNIT_SEC) }, | ||
382 | { "3s", TALK_ID(3, UNIT_SEC) }, | ||
383 | { "4s", TALK_ID(4, UNIT_SEC) }, | ||
384 | { "5s", TALK_ID(5, UNIT_SEC) }, | ||
385 | { "6s", TALK_ID(6, UNIT_SEC) }, | ||
386 | { "7s", TALK_ID(7, UNIT_SEC) }, | ||
387 | { "8s", TALK_ID(8, UNIT_SEC) }, | ||
388 | { "9s", TALK_ID(9, UNIT_SEC) }, | ||
389 | { "10s", TALK_ID(10, UNIT_SEC) }, | ||
390 | { "11s", TALK_ID(11, UNIT_SEC) }, | ||
391 | { "12s", TALK_ID(12, UNIT_SEC) }, | ||
392 | { "13s", TALK_ID(13, UNIT_SEC) }, | ||
393 | { "14s", TALK_ID(14, UNIT_SEC) }, | ||
394 | { "15s", TALK_ID(15, UNIT_SEC) }, | ||
395 | { "16s", TALK_ID(16, UNIT_SEC) }, | ||
396 | { "17s", TALK_ID(17, UNIT_SEC) }, | ||
397 | { "18s", TALK_ID(18, UNIT_SEC) }, | ||
398 | { "19s", TALK_ID(19, UNIT_SEC) }, | ||
399 | { "20s", TALK_ID(20, UNIT_SEC) }, | ||
400 | { "21s", TALK_ID(21, UNIT_SEC) }, | ||
401 | { "22s", TALK_ID(22, UNIT_SEC) }, | ||
402 | { "23s", TALK_ID(23, UNIT_SEC) }, | ||
403 | { "24s", TALK_ID(24, UNIT_SEC) }, | ||
404 | { "25s", TALK_ID(25, UNIT_SEC) }, | ||
405 | { "26s", TALK_ID(26, UNIT_SEC) }, | ||
406 | { "27s", TALK_ID(27, UNIT_SEC) }, | ||
407 | { "28s", TALK_ID(28, UNIT_SEC) }, | ||
408 | { "29s", TALK_ID(29, UNIT_SEC) }, | ||
409 | { "30s", TALK_ID(30, UNIT_SEC) } | ||
410 | }; | ||
411 | return set_option(str(LANG_RECORD_PRERECORD_TIME), | ||
412 | &global_settings.rec_prerecord_time, INT, | ||
413 | names, 31, NULL ); | ||
414 | } | ||
415 | |||
416 | static bool recdirectory(void) | ||
417 | { | ||
418 | static const struct opt_items names[] = { | ||
419 | { rec_base_directory, -1 }, | ||
420 | { STR(LANG_RECORD_CURRENT_DIR) } | ||
421 | }; | ||
422 | return set_option(str(LANG_RECORD_DIRECTORY), | ||
423 | &global_settings.rec_directory, INT, | ||
424 | names, 2, NULL ); | ||
425 | } | ||
426 | |||
427 | #if CONFIG_BACKLIGHT | ||
428 | static bool cliplight(void) | ||
429 | { | ||
430 | static const struct opt_items names[] = { | ||
431 | { STR(LANG_OFF) }, | ||
432 | { STR(LANG_MAIN_UNIT) } | ||
433 | #ifdef HAVE_REMOTE_LCD | ||
434 | , { STR(LANG_REMOTE_MAIN) }, | ||
435 | { STR(LANG_REMOTE_UNIT) } | ||
436 | #endif | ||
437 | }; | ||
438 | |||
439 | return set_option( str(LANG_CLIP_LIGHT), | ||
440 | &global_settings.cliplight, INT, names, | ||
441 | #ifdef HAVE_REMOTE_LCD | ||
442 | 4, NULL ); | ||
443 | #else | ||
444 | 2, NULL ); | ||
445 | #endif | ||
446 | } | ||
447 | #endif /*CONFIG_BACKLIGHT */ | ||
448 | |||
449 | #ifdef HAVE_AGC | ||
450 | static bool agc_preset(void) | ||
451 | { | ||
452 | static const struct opt_items names[] = { | ||
453 | { STR(LANG_OFF) }, | ||
454 | { STR(LANG_AGC_SAFETY) }, | ||
455 | { STR(LANG_AGC_LIVE) }, | ||
456 | { STR(LANG_AGC_DJSET) }, | ||
457 | { STR(LANG_AGC_MEDIUM) }, | ||
458 | { STR(LANG_AGC_VOICE) }, | ||
459 | }; | ||
460 | if (global_settings.rec_source) | ||
461 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
462 | &global_settings.rec_agc_preset_line, | ||
463 | INT, names, 6, NULL ); | ||
464 | else | ||
465 | return set_option(str(LANG_RECORD_AGC_PRESET), | ||
466 | &global_settings.rec_agc_preset_mic, | ||
467 | INT, names, 6, NULL ); | ||
468 | } | ||
469 | |||
470 | static bool agc_cliptime(void) | ||
471 | { | ||
472 | static const struct opt_items names[] = { | ||
473 | { "200ms", TALK_ID(200, UNIT_MS) }, | ||
474 | { "400ms", TALK_ID(400, UNIT_MS) }, | ||
475 | { "600ms", TALK_ID(600, UNIT_MS) }, | ||
476 | { "800ms", TALK_ID(800, UNIT_MS) }, | ||
477 | { "1s", TALK_ID(1, UNIT_SEC) } | ||
478 | }; | ||
479 | return set_option(str(LANG_RECORD_AGC_CLIPTIME), | ||
480 | &global_settings.rec_agc_cliptime, | ||
481 | INT, names, 5, NULL ); | ||
482 | } | ||
483 | #endif /* HAVE_AGC */ | ||
484 | #endif /* HAVE_RECORDING */ | ||
485 | |||
486 | |||
487 | |||
488 | #ifdef HAVE_RECORDING | ||
489 | enum trigger_menu_option | ||
490 | { | ||
491 | TRIGGER_MODE, | ||
492 | TRIGGER_TYPE, | ||
493 | PRERECORD_TIME, | ||
494 | START_THRESHOLD, | ||
495 | START_DURATION, | ||
496 | STOP_THRESHOLD, | ||
497 | STOP_POSTREC, | ||
498 | STOP_GAP, | ||
499 | TRIG_OPTION_COUNT, | ||
500 | }; | ||
501 | |||
502 | #ifdef HAVE_RECORDING | ||
503 | static char* create_thres_str(int threshold) | ||
504 | { | ||
505 | static char retval[6]; | ||
506 | if (threshold < 0) { | ||
507 | if (threshold < -88) { | ||
508 | snprintf (retval, sizeof retval, "%s", str(LANG_DB_INF)); | ||
509 | } else { | ||
510 | snprintf (retval, sizeof retval, "%ddb", threshold + 1); | ||
511 | } | ||
512 | } else { | ||
513 | snprintf (retval, sizeof retval, "%d%%", threshold); | ||
514 | } | ||
515 | return retval; | ||
516 | } | ||
517 | |||
518 | #define INF_DB (-89) | ||
519 | static void change_threshold(int *threshold, int change) | ||
520 | { | ||
521 | if (global_settings.peak_meter_dbfs) { | ||
522 | if (*threshold >= 0) { | ||
523 | int db = (calc_db(*threshold * MAX_PEAK / 100) - 9000) / 100; | ||
524 | *threshold = db; | ||
525 | } | ||
526 | *threshold += change; | ||
527 | if (*threshold > -1) { | ||
528 | *threshold = INF_DB; | ||
529 | } else if (*threshold < INF_DB) { | ||
530 | *threshold = -1; | ||
531 | } | ||
532 | } else { | ||
533 | if (*threshold < 0) { | ||
534 | *threshold = peak_meter_db2sample(*threshold * 100) * 100 / MAX_PEAK; | ||
535 | } | ||
536 | *threshold += change; | ||
537 | if (*threshold > 100) { | ||
538 | *threshold = 0; | ||
539 | } else if (*threshold < 0) { | ||
540 | *threshold = 100; | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * Displays a menu for editing the trigger settings. | ||
547 | */ | ||
548 | bool rectrigger(void) | ||
549 | { | ||
550 | int exit_request = false; | ||
551 | enum trigger_menu_option selected = TRIGGER_MODE; | ||
552 | bool retval = false; | ||
553 | int old_x_margin[NB_SCREENS]; | ||
554 | int old_y_margin[NB_SCREENS]; | ||
555 | |||
556 | #define TRIGGER_MODE_COUNT 3 | ||
557 | static const unsigned char *trigger_modes[] = { | ||
558 | ID2P(LANG_OFF), | ||
559 | ID2P(LANG_RECORD_TRIG_NOREARM), | ||
560 | ID2P(LANG_RECORD_TRIG_REARM) | ||
561 | }; | ||
562 | |||
563 | #define PRERECORD_TIMES_COUNT 31 | ||
564 | static const unsigned char *prerecord_times[] = { | ||
565 | ID2P(LANG_OFF),"1s","2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", | ||
566 | "10s", "11s", "12s", "13s", "14s", "15s", "16s", "17s", "18s", "19s", | ||
567 | "20s", "21s", "22s", "23s", "24s", "25s", "26s", "27s", "28s", "29s", | ||
568 | "30s" | ||
569 | }; | ||
570 | |||
571 | #define TRIGGER_TYPE_COUNT 3 | ||
572 | static const unsigned char *trigger_types[] = { | ||
573 | ID2P(LANG_RECORD_TRIGGER_STOP), | ||
574 | ID2P(LANG_RECORD_TRIGGER_PAUSE), | ||
575 | ID2P(LANG_RECORD_TRIGGER_NEWFILESTP), | ||
576 | }; | ||
577 | |||
578 | static const unsigned char *option_name[] = { | ||
579 | [TRIGGER_MODE] = ID2P(LANG_RECORD_TRIGGER_MODE), | ||
580 | [TRIGGER_TYPE] = ID2P(LANG_RECORD_TRIGGER_TYPE), | ||
581 | [PRERECORD_TIME] = ID2P(LANG_RECORD_PRERECORD_TIME), | ||
582 | [START_THRESHOLD] = ID2P(LANG_RECORD_START_THRESHOLD), | ||
583 | [START_DURATION] = ID2P(LANG_RECORD_MIN_DURATION), | ||
584 | [STOP_THRESHOLD] = ID2P(LANG_RECORD_STOP_THRESHOLD), | ||
585 | [STOP_POSTREC] = ID2P(LANG_RECORD_STOP_POSTREC), | ||
586 | [STOP_GAP] = ID2P(LANG_RECORD_STOP_GAP) | ||
587 | }; | ||
588 | |||
589 | int old_start_thres = global_settings.rec_start_thres; | ||
590 | int old_start_duration = global_settings.rec_start_duration; | ||
591 | int old_prerecord_time = global_settings.rec_prerecord_time; | ||
592 | int old_stop_thres = global_settings.rec_stop_thres; | ||
593 | int old_stop_postrec = global_settings.rec_stop_postrec; | ||
594 | int old_stop_gap = global_settings.rec_stop_gap; | ||
595 | int old_trigger_mode = global_settings.rec_trigger_mode; | ||
596 | int old_trigger_type = global_settings.rec_trigger_type; | ||
597 | |||
598 | int offset[NB_SCREENS]; | ||
599 | int option_lines[NB_SCREENS]; | ||
600 | int w, h, i; | ||
601 | int stat_height = global_settings.statusbar ? STATUSBAR_HEIGHT : 0; | ||
602 | int pm_y[NB_SCREENS]; | ||
603 | |||
604 | int trig_xpos[NB_SCREENS]; | ||
605 | int trig_ypos[NB_SCREENS]; | ||
606 | int trig_width[NB_SCREENS]; | ||
607 | |||
608 | FOR_NB_SCREENS(i) | ||
609 | { | ||
610 | offset[i] = 0; | ||
611 | trig_xpos[i] = 0; | ||
612 | trig_ypos[i] = screens[i].height - stat_height - TRIG_HEIGHT; | ||
613 | pm_y[i] = screens[i].height - stat_height; | ||
614 | trig_width[i] = screens[i].width; | ||
615 | } | ||
616 | |||
617 | /* restart trigger with new values */ | ||
618 | settings_apply_trigger(); | ||
619 | peak_meter_trigger (global_settings.rec_trigger_mode != TRIG_MODE_OFF); | ||
620 | |||
621 | FOR_NB_SCREENS(i) | ||
622 | { | ||
623 | screens[i].clear_display(); | ||
624 | |||
625 | old_x_margin[i] = screens[i].getxmargin(); | ||
626 | old_y_margin[i] = screens[i].getymargin(); | ||
627 | if(global_settings.statusbar) | ||
628 | screens[i].setmargins(0, STATUSBAR_HEIGHT); | ||
629 | else | ||
630 | screens[i].setmargins(0, 0); | ||
631 | |||
632 | screens[i].getstringsize("M", &w, &h); | ||
633 | |||
634 | // 16 pixels are reserved for peak meter and trigger status | ||
635 | option_lines[i] = MIN(((screens[i].height) - | ||
636 | stat_height - 16)/h, | ||
637 | TRIG_OPTION_COUNT); | ||
638 | } | ||
639 | |||
640 | while (!exit_request) { | ||
641 | int button, k; | ||
642 | const char *str; | ||
643 | char option_value[TRIG_OPTION_COUNT][9]; | ||
644 | |||
645 | snprintf( | ||
646 | option_value[TRIGGER_MODE], | ||
647 | sizeof option_value[TRIGGER_MODE], | ||
648 | "%s", | ||
649 | P2STR(trigger_modes[global_settings.rec_trigger_mode])); | ||
650 | |||
651 | snprintf( | ||
652 | option_value[TRIGGER_TYPE], | ||
653 | sizeof option_value[TRIGGER_TYPE], | ||
654 | "%s", | ||
655 | P2STR(trigger_types[global_settings.rec_trigger_type])); | ||
656 | |||
657 | snprintf( | ||
658 | option_value[TRIGGER_TYPE], | ||
659 | sizeof option_value[TRIGGER_TYPE], | ||
660 | "%s", | ||
661 | P2STR(trigger_types[global_settings.rec_trigger_type])); | ||
662 | |||
663 | snprintf ( | ||
664 | option_value[PRERECORD_TIME], | ||
665 | sizeof option_value[PRERECORD_TIME], | ||
666 | "%s", | ||
667 | P2STR(prerecord_times[global_settings.rec_prerecord_time])); | ||
668 | |||
669 | /* due to value range shift (peak_meter_define_trigger) -1 is 0db */ | ||
670 | if (global_settings.rec_start_thres == -1) { | ||
671 | str = str(LANG_OFF); | ||
672 | } else { | ||
673 | str = create_thres_str(global_settings.rec_start_thres); | ||
674 | } | ||
675 | snprintf( | ||
676 | option_value[START_THRESHOLD], | ||
677 | sizeof option_value[START_THRESHOLD], | ||
678 | "%s", | ||
679 | str); | ||
680 | |||
681 | snprintf( | ||
682 | option_value[START_DURATION], | ||
683 | sizeof option_value[START_DURATION], | ||
684 | "%s", | ||
685 | trig_durations[global_settings.rec_start_duration]); | ||
686 | |||
687 | |||
688 | if (global_settings.rec_stop_thres <= INF_DB) { | ||
689 | str = str(LANG_OFF); | ||
690 | } else { | ||
691 | str = create_thres_str(global_settings.rec_stop_thres); | ||
692 | } | ||
693 | snprintf( | ||
694 | option_value[STOP_THRESHOLD], | ||
695 | sizeof option_value[STOP_THRESHOLD], | ||
696 | "%s", | ||
697 | str); | ||
698 | |||
699 | snprintf( | ||
700 | option_value[STOP_POSTREC], | ||
701 | sizeof option_value[STOP_POSTREC], | ||
702 | "%s", | ||
703 | trig_durations[global_settings.rec_stop_postrec]); | ||
704 | |||
705 | snprintf( | ||
706 | option_value[STOP_GAP], | ||
707 | sizeof option_value[STOP_GAP], | ||
708 | "%s", | ||
709 | trig_durations[global_settings.rec_stop_gap]); | ||
710 | |||
711 | FOR_NB_SCREENS(i) | ||
712 | { | ||
713 | screens[i].set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
714 | screens[i].fillrect(0, stat_height, screens[i].width, | ||
715 | screens[i].height - stat_height); | ||
716 | screens[i].set_drawmode(DRMODE_SOLID); | ||
717 | } | ||
718 | |||
719 | gui_syncstatusbar_draw(&statusbars, true); | ||
720 | |||
721 | /* reselect FONT_SYSFONT as status_draw has changed the font */ | ||
722 | /*lcd_setfont(FONT_SYSFIXED);*/ | ||
723 | |||
724 | FOR_NB_SCREENS(i) | ||
725 | { | ||
726 | for (k = 0; k < option_lines[i]; k++) { | ||
727 | int x, y; | ||
728 | |||
729 | str = P2STR(option_name[k + offset[i]]); | ||
730 | screens[i].putsxy((option_lines[i] < TRIG_OPTION_COUNT) ? 5 : 0, | ||
731 | stat_height + k * h, str); | ||
732 | |||
733 | str = option_value[k + offset[i]]; | ||
734 | screens[i].getstringsize(str, &w, &h); | ||
735 | y = stat_height + k * h; | ||
736 | x = screens[i].width - w; | ||
737 | screens[i].putsxy(x, y, str); | ||
738 | if ((int)selected == (k + offset[i])) { | ||
739 | screens[i].set_drawmode(DRMODE_COMPLEMENT); | ||
740 | screens[i].fillrect(x, y, w, h); | ||
741 | screens[i].set_drawmode(DRMODE_SOLID); | ||
742 | } | ||
743 | } | ||
744 | if (option_lines[i] < TRIG_OPTION_COUNT) | ||
745 | gui_scrollbar_draw(&screens[i], 0, stat_height, | ||
746 | 4, screens[i].height - 16 - stat_height, | ||
747 | TRIG_OPTION_COUNT, offset[i], offset[i] + option_lines[i], | ||
748 | VERTICAL); | ||
749 | } | ||
750 | |||
751 | peak_meter_draw_trig(trig_xpos, trig_ypos, trig_width, NB_SCREENS); | ||
752 | button = peak_meter_draw_get_btn(0, pm_y, 8, NB_SCREENS); | ||
753 | |||
754 | FOR_NB_SCREENS(i) | ||
755 | screens[i].update(); | ||
756 | |||
757 | switch (button) { | ||
758 | case ACTION_STD_CANCEL: | ||
759 | gui_syncsplash(50, true, str(LANG_MENU_SETTING_CANCEL)); | ||
760 | global_settings.rec_start_thres = old_start_thres; | ||
761 | global_settings.rec_start_duration = old_start_duration; | ||
762 | global_settings.rec_prerecord_time = old_prerecord_time; | ||
763 | global_settings.rec_stop_thres = old_stop_thres; | ||
764 | global_settings.rec_stop_postrec = old_stop_postrec; | ||
765 | global_settings.rec_stop_gap = old_stop_gap; | ||
766 | global_settings.rec_trigger_mode = old_trigger_mode; | ||
767 | global_settings.rec_trigger_type = old_trigger_type; | ||
768 | exit_request = true; | ||
769 | break; | ||
770 | |||
771 | case ACTION_REC_PAUSE: | ||
772 | exit_request = true; | ||
773 | break; | ||
774 | |||
775 | case ACTION_STD_PREV: | ||
776 | selected += TRIG_OPTION_COUNT - 1; | ||
777 | selected %= TRIG_OPTION_COUNT; | ||
778 | FOR_NB_SCREENS(i) | ||
779 | { | ||
780 | offset[i] = MIN(offset[i], (int)selected); | ||
781 | offset[i] = MAX(offset[i], (int)selected - option_lines[i] + 1); | ||
782 | } | ||
783 | break; | ||
784 | |||
785 | case ACTION_STD_NEXT: | ||
786 | selected ++; | ||
787 | selected %= TRIG_OPTION_COUNT; | ||
788 | FOR_NB_SCREENS(i) | ||
789 | { | ||
790 | offset[i] = MIN(offset[i], (int)selected); | ||
791 | offset[i] = MAX(offset[i], (int)selected - option_lines[i] + 1); | ||
792 | } | ||
793 | break; | ||
794 | |||
795 | case ACTION_SETTINGS_INC: | ||
796 | switch (selected) { | ||
797 | case TRIGGER_MODE: | ||
798 | global_settings.rec_trigger_mode ++; | ||
799 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
800 | break; | ||
801 | |||
802 | case TRIGGER_TYPE: | ||
803 | global_settings.rec_trigger_type ++; | ||
804 | global_settings.rec_trigger_type %= TRIGGER_TYPE_COUNT; | ||
805 | break; | ||
806 | |||
807 | case PRERECORD_TIME: | ||
808 | global_settings.rec_prerecord_time ++; | ||
809 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
810 | break; | ||
811 | |||
812 | case START_THRESHOLD: | ||
813 | change_threshold(&global_settings.rec_start_thres, 1); | ||
814 | break; | ||
815 | |||
816 | case START_DURATION: | ||
817 | global_settings.rec_start_duration ++; | ||
818 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
819 | break; | ||
820 | |||
821 | case STOP_THRESHOLD: | ||
822 | change_threshold(&global_settings.rec_stop_thres, 1); | ||
823 | break; | ||
824 | |||
825 | case STOP_POSTREC: | ||
826 | global_settings.rec_stop_postrec ++; | ||
827 | global_settings.rec_stop_postrec %= TRIG_DURATION_COUNT; | ||
828 | break; | ||
829 | |||
830 | case STOP_GAP: | ||
831 | global_settings.rec_stop_gap ++; | ||
832 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
833 | break; | ||
834 | |||
835 | case TRIG_OPTION_COUNT: | ||
836 | // avoid compiler warnings | ||
837 | break; | ||
838 | } | ||
839 | peak_meter_trigger(global_settings.rec_trigger_mode!=TRIG_OFF); | ||
840 | settings_apply_trigger(); | ||
841 | break; | ||
842 | |||
843 | case ACTION_SETTINGS_DEC: | ||
844 | switch (selected) { | ||
845 | case TRIGGER_MODE: | ||
846 | global_settings.rec_trigger_mode+=TRIGGER_MODE_COUNT-1; | ||
847 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
848 | break; | ||
849 | |||
850 | case TRIGGER_TYPE: | ||
851 | global_settings.rec_trigger_type+=TRIGGER_TYPE_COUNT-1; | ||
852 | global_settings.rec_trigger_type %= TRIGGER_TYPE_COUNT; | ||
853 | break; | ||
854 | |||
855 | case PRERECORD_TIME: | ||
856 | global_settings.rec_prerecord_time += PRERECORD_TIMES_COUNT - 1; | ||
857 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
858 | break; | ||
859 | |||
860 | case START_THRESHOLD: | ||
861 | change_threshold(&global_settings.rec_start_thres, -1); | ||
862 | break; | ||
863 | |||
864 | case START_DURATION: | ||
865 | global_settings.rec_start_duration += TRIG_DURATION_COUNT-1; | ||
866 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
867 | break; | ||
868 | |||
869 | case STOP_THRESHOLD: | ||
870 | change_threshold(&global_settings.rec_stop_thres, -1); | ||
871 | break; | ||
872 | |||
873 | case STOP_POSTREC: | ||
874 | global_settings.rec_stop_postrec += | ||
875 | TRIG_DURATION_COUNT - 1; | ||
876 | global_settings.rec_stop_postrec %= | ||
877 | TRIG_DURATION_COUNT; | ||
878 | break; | ||
879 | |||
880 | case STOP_GAP: | ||
881 | global_settings.rec_stop_gap += | ||
882 | TRIG_DURATION_COUNT - 1; | ||
883 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
884 | break; | ||
885 | |||
886 | case TRIG_OPTION_COUNT: | ||
887 | // avoid compiler warnings | ||
888 | break; | ||
889 | } | ||
890 | peak_meter_trigger(global_settings.rec_trigger_mode!=TRIG_OFF); | ||
891 | settings_apply_trigger(); | ||
892 | break; | ||
893 | |||
894 | case ACTION_REC_F2: | ||
895 | peak_meter_trigger(true); | ||
896 | break; | ||
897 | |||
898 | case SYS_USB_CONNECTED: | ||
899 | if(default_event_handler(button) == SYS_USB_CONNECTED) { | ||
900 | retval = true; | ||
901 | exit_request = true; | ||
902 | } | ||
903 | break; | ||
904 | } | ||
905 | } | ||
906 | |||
907 | peak_meter_trigger(false); | ||
908 | FOR_NB_SCREENS(i) | ||
909 | { | ||
910 | screens[i].setfont(FONT_UI); | ||
911 | screens[i].setmargins(old_x_margin[i], old_y_margin[i]); | ||
912 | } | ||
913 | action_signalscreenchange(); | ||
914 | return retval; | ||
915 | } | ||
916 | #endif /* !defined(SIMULATOR) && CONFIG_CODEC == MAS3587F */ | ||
917 | |||
918 | bool recording_menu(bool no_source) | ||
919 | { | ||
920 | static const struct menu_item static_items[] = { | ||
921 | #if CONFIG_CODEC == MAS3587F | ||
922 | { ID2P(LANG_RECORDING_QUALITY), recquality }, | ||
923 | #endif | ||
924 | #if CONFIG_CODEC == SWCODEC | ||
925 | { ID2P(LANG_RECORDING_FORMAT), recformat }, | ||
926 | { ID2P(LANG_ENCODER_SETTINGS), enc_global_config_menu }, | ||
927 | #endif | ||
928 | { ID2P(LANG_RECORDING_FREQUENCY), recfrequency }, | ||
929 | { ID2P(LANG_RECORDING_SOURCE), recsource }, /* not shown if no_source */ | ||
930 | { ID2P(LANG_RECORDING_CHANNELS), recchannels }, | ||
931 | #if CONFIG_CODEC == MAS3587F | ||
932 | { ID2P(LANG_RECORDING_EDITABLE), receditable }, | ||
933 | #endif | ||
934 | { ID2P(LANG_RECORD_TIMESPLIT), filesplitoptionsmenu }, | ||
935 | { ID2P(LANG_RECORD_PRERECORD_TIME), recprerecord }, | ||
936 | { ID2P(LANG_RECORD_DIRECTORY), recdirectory }, | ||
937 | #if CONFIG_BACKLIGHT | ||
938 | { ID2P(LANG_CLIP_LIGHT), cliplight }, | ||
939 | #endif | ||
940 | { ID2P(LANG_RECORD_TRIGGER), rectrigger }, | ||
941 | #ifdef HAVE_AGC | ||
942 | { ID2P(LANG_RECORD_AGC_PRESET), agc_preset }, | ||
943 | { ID2P(LANG_RECORD_AGC_CLIPTIME), agc_cliptime }, | ||
944 | #endif | ||
945 | }; | ||
946 | |||
947 | struct menu_item items[ARRAYLEN(static_items)]; | ||
948 | int i, n_items; | ||
949 | int m; | ||
950 | |||
951 | bool result; | ||
952 | |||
953 | for (i = 0, n_items = 0; i < (int)ARRAYLEN(items); i++) | ||
954 | { | ||
955 | const struct menu_item *mi = &static_items[i]; | ||
956 | if (no_source && mi->function == recsource) | ||
957 | continue; | ||
958 | items[n_items++] = *mi; | ||
959 | } | ||
960 | |||
961 | m = menu_init(items, n_items, NULL, NULL, NULL, NULL); | ||
962 | result = menu_run(m); | ||
963 | menu_exit(m); | ||
964 | |||
965 | return result; | ||
966 | } /* recording_menu */ | ||
967 | |||
968 | #endif /* HAVE_RECORDING */ | ||