1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Jonathan Gordon
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
30 #include "mp3_playback.h"
32 #include "statusbar.h"
35 #ifdef HAVE_LCD_BITMAP
37 #include "scrollbar.h"
51 #include "peakmeter.h"
55 #if CONFIG_CODEC == SWCODEC
57 #include "menus/eq_menu.h"
60 #include "enc_config.h"
65 #include "recording.h"
68 static bool no_source_in_menu
= false;
69 int recmenu_callback(int action
,const struct menu_item_ex
*this_item
);
71 static int recsource_func(void)
73 int n_opts
= REC_NUM_SOURCES
;
75 static const struct opt_items names
[AUDIO_NUM_SOURCES
] = {
76 HAVE_MIC_REC_([AUDIO_SRC_MIC
]
77 = { STR(LANG_RECORDING_SRC_MIC
) },)
78 HAVE_LINE_REC_([AUDIO_SRC_LINEIN
]
79 = { STR(LANG_LINE_IN
) },)
80 HAVE_SPDIF_REC_([AUDIO_SRC_SPDIF
]
81 = { STR(LANG_RECORDING_SRC_DIGITAL
) },)
82 HAVE_FMRADIO_REC_([AUDIO_SRC_FMRADIO
]
83 = { STR(LANG_FM_RADIO
) },)
86 /* caveat: assumes it's the last item! */
87 #ifdef HAVE_FMRADIO_REC
88 if (!radio_hardware_present())
92 return set_option(str(LANG_RECORDING_SOURCE
),
93 &global_settings
.rec_source
, INT
, names
,
96 MENUITEM_FUNCTION(recsource
, 0, ID2P(LANG_RECORDING_SOURCE
),
97 recsource_func
, NULL
, recmenu_callback
, Icon_Menu_setting
);
99 #if CONFIG_CODEC == SWCODEC
100 /* Makes an options list from a source list of options and indexes */
101 static void make_options_from_indexes(const struct opt_items
*src_names
,
102 const long *src_indexes
,
104 struct opt_items
*dst_names
)
106 while (--n_indexes
>= 0)
107 dst_names
[n_indexes
] = src_names
[src_indexes
[n_indexes
]];
108 } /* make_options_from_indexes */
111 #endif /* CONFIG_CODEC == SWCODEC */
113 static int recfrequency_func(void)
115 #if CONFIG_CODEC == MAS3587F
116 static const struct opt_items names
[6] = {
117 { "44.1kHz", TALK_ID(44, UNIT_KHZ
) },
118 { "48kHz", TALK_ID(48, UNIT_KHZ
) },
119 { "32kHz", TALK_ID(32, UNIT_KHZ
) },
120 { "22.05kHz", TALK_ID(22, UNIT_KHZ
) },
121 { "24kHz", TALK_ID(24, UNIT_KHZ
) },
122 { "16kHz", TALK_ID(16, UNIT_KHZ
) }
124 return set_option(str(LANG_RECORDING_FREQUENCY
),
125 &global_settings
.rec_frequency
, INT
,
127 #endif /* CONFIG_CODEC == MAS3587F */
129 #if CONFIG_CODEC == SWCODEC
130 static const struct opt_items names
[REC_NUM_FREQ
] = {
131 REC_HAVE_96_([REC_FREQ_96
] = { "96kHz", TALK_ID(96, UNIT_KHZ
) },)
132 REC_HAVE_88_([REC_FREQ_88
] = { "88.2kHz", TALK_ID(88, UNIT_KHZ
) },)
133 REC_HAVE_64_([REC_FREQ_64
] = { "64kHz", TALK_ID(64, UNIT_KHZ
) },)
134 REC_HAVE_48_([REC_FREQ_48
] = { "48kHz", TALK_ID(48, UNIT_KHZ
) },)
135 REC_HAVE_44_([REC_FREQ_44
] = { "44.1kHz", TALK_ID(44, UNIT_KHZ
) },)
136 REC_HAVE_32_([REC_FREQ_32
] = { "32kHz", TALK_ID(32, UNIT_KHZ
) },)
137 REC_HAVE_24_([REC_FREQ_24
] = { "24kHz", TALK_ID(24, UNIT_KHZ
) },)
138 REC_HAVE_22_([REC_FREQ_22
] = { "22.05kHz", TALK_ID(22, UNIT_KHZ
) },)
139 REC_HAVE_16_([REC_FREQ_16
] = { "16kHz", TALK_ID(16, UNIT_KHZ
) },)
140 REC_HAVE_12_([REC_FREQ_12
] = { "12kHz", TALK_ID(12, UNIT_KHZ
) },)
141 REC_HAVE_11_([REC_FREQ_11
] = { "11.025kHz", TALK_ID(11, UNIT_KHZ
) },)
142 REC_HAVE_8_( [REC_FREQ_8
] = { "8kHz", TALK_ID( 8, UNIT_KHZ
) },)
145 struct opt_items opts
[REC_NUM_FREQ
];
146 unsigned long table
[REC_NUM_FREQ
];
151 #ifdef HAVE_SPDIF_REC
152 if (global_settings
.rec_source
== REC_SRC_SPDIF
)
154 /* Inform user that frequency follows the source's frequency */
155 opts
[0].string
= ID2P(LANG_SOURCE_FREQUENCY
);
156 opts
[0].voice_id
= LANG_SOURCE_FREQUENCY
;
163 struct encoder_caps caps
;
164 struct encoder_config cfg
;
166 cfg
.rec_format
= global_settings
.rec_format
;
167 global_to_encoder_config(&cfg
);
169 if (!enc_get_caps(&cfg
, &caps
, true))
172 /* Construct samplerate menu based upon encoder settings */
173 n_opts
= make_list_from_caps32(REC_SAMPR_CAPS
, NULL
,
174 caps
.samplerate_caps
, table
);
177 return false; /* No common flags...?? */
179 make_options_from_indexes(names
, table
, n_opts
, opts
);
181 /* Find closest rate that the potentially restricted list
183 make_list_from_caps32(REC_SAMPR_CAPS
, rec_freq_sampr
,
184 caps
.samplerate_caps
, table
);
186 rec_frequency
= round_value_to_list32(
187 rec_freq_sampr
[global_settings
.rec_frequency
],
188 table
, n_opts
, false);
191 ret
= set_option(str(LANG_RECORDING_FREQUENCY
),
192 &rec_frequency
, INT
, opts
, n_opts
, NULL
);
195 HAVE_SPDIF_REC_( && global_settings
.rec_source
!= REC_SRC_SPDIF
)
198 /* Translate back to full index */
199 global_settings
.rec_frequency
=
200 round_value_to_list32(table
[rec_frequency
],
207 #endif /* CONFIG_CODEC == SWCODEC */
209 MENUITEM_FUNCTION(recfrequency
, 0, ID2P(LANG_RECORDING_FREQUENCY
),
210 recfrequency_func
, NULL
, NULL
, Icon_Menu_setting
);
213 static int recchannels_func(void)
215 static const struct opt_items names
[CHN_NUM_MODES
] = {
216 [CHN_MODE_STEREO
] = { STR(LANG_CHANNEL_STEREO
) },
217 [CHN_MODE_MONO
] = { STR(LANG_CHANNEL_MONO
) }
219 #if CONFIG_CODEC == MAS3587F
220 return set_option(str(LANG_CHANNELS
),
221 &global_settings
.rec_channels
, INT
,
222 names
, CHN_NUM_MODES
, NULL
);
223 #endif /* CONFIG_CODEC == MAS3587F */
225 #if CONFIG_CODEC == SWCODEC
226 struct opt_items opts
[CHN_NUM_MODES
];
227 long table
[CHN_NUM_MODES
];
228 struct encoder_caps caps
;
229 struct encoder_config cfg
;
234 cfg
.rec_format
= global_settings
.rec_format
;
235 global_to_encoder_config(&cfg
);
237 if (!enc_get_caps(&cfg
, &caps
, true))
240 n_opts
= make_list_from_caps32(CHN_CAP_ALL
, NULL
,
241 caps
.channel_caps
, table
);
243 rec_channels
= round_value_to_list32(global_settings
.rec_channels
,
244 table
, n_opts
, false);
246 make_options_from_indexes(names
, table
, n_opts
, opts
);
248 ret
= set_option(str(LANG_CHANNELS
), &rec_channels
,
249 INT
, opts
, n_opts
, NULL
);
252 global_settings
.rec_channels
= table
[rec_channels
];
255 #endif /* CONFIG_CODEC == SWCODEC */
257 MENUITEM_FUNCTION(recchannels
, 0, ID2P(LANG_CHANNELS
),
258 recchannels_func
, NULL
, NULL
, Icon_Menu_setting
);
260 #if CONFIG_CODEC == SWCODEC
262 static int recformat_func(void)
264 static const struct opt_items names
[REC_NUM_FORMATS
] = {
265 [REC_FORMAT_AIFF
] = { STR(LANG_AFMT_AIFF
) },
266 [REC_FORMAT_MPA_L3
] = { STR(LANG_AFMT_MPA_L3
) },
267 [REC_FORMAT_WAVPACK
] = { STR(LANG_AFMT_WAVPACK
) },
268 [REC_FORMAT_PCM_WAV
] = { STR(LANG_AFMT_PCM_WAV
) },
271 int rec_format
= global_settings
.rec_format
;
272 bool res
= set_option(str(LANG_RECORDING_FORMAT
), &rec_format
, INT
,
273 names
, REC_NUM_FORMATS
, NULL
);
275 if (rec_format
!= global_settings
.rec_format
)
277 global_settings
.rec_format
= rec_format
;
278 enc_global_settings_apply();
283 MENUITEM_FUNCTION(recformat
, 0, ID2P(LANG_RECORDING_FORMAT
),
284 recformat_func
, NULL
, NULL
, Icon_Menu_setting
);
286 MENUITEM_FUNCTION(enc_global_config_menu_item
, 0, ID2P(LANG_ENCODER_SETTINGS
),
287 (int(*)(void))enc_global_config_menu
,
288 NULL
, NULL
, Icon_Submenu
);
290 #endif /* CONFIG_CODEC == SWCODEC */
293 int recmenu_callback(int action
,const struct menu_item_ex
*this_item
)
297 case ACTION_REQUEST_MENUITEM
:
298 if (this_item
== &recsource
&& no_source_in_menu
)
299 return ACTION_EXIT_MENUITEM
;
304 #if CONFIG_CODEC == MAS3587F
305 MENUITEM_SETTING(rec_quality
, &global_settings
.rec_quality
, NULL
);
306 MENUITEM_SETTING(rec_editable
, &global_settings
.rec_editable
, NULL
);
309 MENUITEM_SETTING(rec_split_type
, &global_settings
.rec_split_type
, NULL
);
310 MENUITEM_SETTING(rec_split_method
, &global_settings
.rec_split_method
, NULL
);
311 MENUITEM_SETTING(rec_timesplit
, &global_settings
.rec_timesplit
, NULL
);
312 MENUITEM_SETTING(rec_sizesplit
, &global_settings
.rec_sizesplit
, NULL
);
313 MAKE_MENU(filesplitoptionsmenu
, ID2P(LANG_RECORD_TIMESPLIT
), NULL
, Icon_NOICON
,
314 &rec_split_method
, &rec_split_type
, &rec_timesplit
, &rec_sizesplit
);
317 MENUITEM_SETTING(rec_prerecord_time
, &global_settings
.rec_prerecord_time
, NULL
);
319 static int clear_rec_directory(void)
321 strcpy(global_settings
.rec_directory
, REC_BASE_DIR
);
322 gui_syncsplash(HZ
, str(LANG_RESET_DONE_CLEAR
));
325 MENUITEM_FUNCTION(clear_rec_directory_item
, 0, ID2P(LANG_CLEAR_REC_DIR
),
326 clear_rec_directory
, NULL
, NULL
, Icon_Folder
);
328 MENUITEM_SETTING(cliplight
, &global_settings
.cliplight
, NULL
);
331 static int agc_preset_func(void)
333 static const struct opt_items names
[] = {
335 { STR(LANG_AGC_SAFETY
) },
336 { STR(LANG_AGC_LIVE
) },
337 { STR(LANG_AGC_DJSET
) },
338 { STR(LANG_AGC_MEDIUM
) },
339 { STR(LANG_AGC_VOICE
) },
341 if (global_settings
.rec_source
)
342 return set_option(str(LANG_RECORD_AGC_PRESET
),
343 &global_settings
.rec_agc_preset_line
,
344 INT
, names
, 6, NULL
);
346 return set_option(str(LANG_RECORD_AGC_PRESET
),
347 &global_settings
.rec_agc_preset_mic
,
348 INT
, names
, 6, NULL
);
351 static int agc_cliptime_func(void)
353 static const struct opt_items names
[] = {
354 { "200ms", TALK_ID(200, UNIT_MS
) },
355 { "400ms", TALK_ID(400, UNIT_MS
) },
356 { "600ms", TALK_ID(600, UNIT_MS
) },
357 { "800ms", TALK_ID(800, UNIT_MS
) },
358 { "1s", TALK_ID(1, UNIT_SEC
) }
360 return set_option(str(LANG_RECORD_AGC_CLIPTIME
),
361 &global_settings
.rec_agc_cliptime
,
362 INT
, names
, 5, NULL
);
364 MENUITEM_FUNCTION(agc_preset
, 0, ID2P(LANG_RECORD_AGC_PRESET
),
365 agc_preset_func
, NULL
, NULL
, Icon_Menu_setting
);
366 MENUITEM_FUNCTION(agc_cliptime
, 0, ID2P(LANG_RECORD_AGC_CLIPTIME
),
367 agc_cliptime_func
, NULL
, NULL
, Icon_Menu_setting
);
368 #endif /* HAVE_AGC */
371 enum trigger_menu_option
384 static char* create_thres_str(int threshold
, long *voice_id
)
386 static char retval
[6];
388 if (threshold
< -88) {
389 snprintf (retval
, sizeof retval
, "%s", str(LANG_DB_INF
));
391 *voice_id
= LANG_DB_INF
;
393 snprintf (retval
, sizeof retval
, "%ddb", threshold
+ 1);
395 *voice_id
= TALK_ID(threshold
+ 1, UNIT_DB
);
398 snprintf (retval
, sizeof retval
, "%d%%", threshold
);
400 *voice_id
= TALK_ID(threshold
, UNIT_PERCENT
);
406 static void change_threshold(int *threshold
, int change
)
408 if (global_settings
.peak_meter_dbfs
) {
409 if (*threshold
>= 0) {
410 int db
= (calc_db(*threshold
* MAX_PEAK
/ 100) - 9000) / 100;
413 *threshold
+= change
;
414 if (*threshold
> -1) {
416 } else if (*threshold
< INF_DB
) {
420 if (*threshold
< 0) {
421 *threshold
= peak_meter_db2sample(*threshold
* 100) * 100 / MAX_PEAK
;
423 *threshold
+= change
;
424 if (*threshold
> 100) {
426 } else if (*threshold
< 0) {
433 * Displays a menu for editing the trigger settings.
435 bool rectrigger(void)
437 int exit_request
= false;
438 enum trigger_menu_option selected
= TRIGGER_MODE
;
440 int old_x_margin
[NB_SCREENS
];
441 int old_y_margin
[NB_SCREENS
];
443 #define TRIGGER_MODE_COUNT 3
444 static const unsigned char *trigger_modes
[] = {
446 ID2P(LANG_RECORD_TRIG_NOREARM
),
450 #define PRERECORD_TIMES_COUNT 31
451 static const struct opt_items prerecord_times
[] = {
453 #define T(x) { (unsigned char *)(#x "s"), TALK_ID(x, UNIT_SEC) }
454 T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9), T(10),
455 T(11), T(12), T(13), T(14), T(15), T(16), T(17), T(18), T(19), T(20),
456 T(21), T(22), T(23), T(24), T(25), T(26), T(27), T(28), T(29), T(30),
460 #define TRIGGER_TYPE_COUNT 3
461 static const unsigned char *trigger_types
[] = {
462 ID2P(LANG_RECORD_TRIGGER_STOP
),
464 ID2P(LANG_RECORD_TRIGGER_NEWFILESTP
),
467 static const unsigned char *option_name
[] = {
468 [TRIGGER_MODE
] = ID2P(LANG_RECORD_TRIGGER
),
469 [TRIGGER_TYPE
] = ID2P(LANG_RECORD_TRIGGER_TYPE
),
470 [PRERECORD_TIME
] = ID2P(LANG_RECORD_PRERECORD_TIME
),
471 [START_THRESHOLD
] = ID2P(LANG_RECORD_START_THRESHOLD
),
472 [START_DURATION
] = ID2P(LANG_MIN_DURATION
),
473 [STOP_THRESHOLD
] = ID2P(LANG_RECORD_STOP_THRESHOLD
),
474 [STOP_POSTREC
] = ID2P(LANG_MIN_DURATION
),
475 [STOP_GAP
] = ID2P(LANG_RECORD_STOP_GAP
)
478 int old_start_thres
= global_settings
.rec_start_thres
;
479 int old_start_duration
= global_settings
.rec_start_duration
;
480 int old_prerecord_time
= global_settings
.rec_prerecord_time
;
481 int old_stop_thres
= global_settings
.rec_stop_thres
;
482 int old_stop_postrec
= global_settings
.rec_stop_postrec
;
483 int old_stop_gap
= global_settings
.rec_stop_gap
;
484 int old_trigger_mode
= global_settings
.rec_trigger_mode
;
485 int old_trigger_type
= global_settings
.rec_trigger_type
;
487 int offset
[NB_SCREENS
];
488 int option_lines
[NB_SCREENS
];
490 int stat_height
= global_settings
.statusbar
? STATUSBAR_HEIGHT
: 0;
491 int pm_y
[NB_SCREENS
];
493 int trig_xpos
[NB_SCREENS
];
494 int trig_ypos
[NB_SCREENS
];
495 int trig_width
[NB_SCREENS
];
497 bool say_field
= true, say_value
= true;
503 trig_ypos
[i
] = screens
[i
].height
- stat_height
- TRIG_HEIGHT
;
504 pm_y
[i
] = screens
[i
].height
- stat_height
;
505 trig_width
[i
] = screens
[i
].width
;
508 /* restart trigger with new values */
509 settings_apply_trigger();
510 peak_meter_trigger (global_settings
.rec_trigger_mode
!= TRIG_MODE_OFF
);
514 screens
[i
].clear_display();
516 old_x_margin
[i
] = screens
[i
].getxmargin();
517 old_y_margin
[i
] = screens
[i
].getymargin();
518 if(global_settings
.statusbar
)
519 screens
[i
].setmargins(0, STATUSBAR_HEIGHT
);
521 screens
[i
].setmargins(0, 0);
523 screens
[i
].getstringsize("M", &w
, &h
);
525 // 16 pixels are reserved for peak meter and trigger status
526 option_lines
[i
] = MIN(((screens
[i
].height
) -
531 while (!exit_request
) {
534 char option_value
[TRIG_OPTION_COUNT
][16];
537 option_value
[TRIGGER_MODE
],
538 sizeof option_value
[TRIGGER_MODE
],
540 P2STR(trigger_modes
[global_settings
.rec_trigger_mode
]));
543 option_value
[TRIGGER_TYPE
],
544 sizeof option_value
[TRIGGER_TYPE
],
546 P2STR(trigger_types
[global_settings
.rec_trigger_type
]));
549 option_value
[PRERECORD_TIME
],
550 sizeof option_value
[PRERECORD_TIME
],
552 prerecord_times
[global_settings
.rec_prerecord_time
].string
);
554 /* due to value range shift (peak_meter_define_trigger) -1 is 0db */
555 if (global_settings
.rec_start_thres
== -1) {
558 str
= create_thres_str(global_settings
.rec_start_thres
, NULL
);
561 option_value
[START_THRESHOLD
],
562 sizeof option_value
[START_THRESHOLD
],
567 option_value
[START_DURATION
],
568 sizeof option_value
[START_DURATION
],
570 trig_durations
[global_settings
.rec_start_duration
].string
);
572 if (global_settings
.rec_stop_thres
<= INF_DB
) {
575 str
= create_thres_str(global_settings
.rec_stop_thres
, NULL
);
578 option_value
[STOP_THRESHOLD
],
579 sizeof option_value
[STOP_THRESHOLD
],
584 option_value
[STOP_POSTREC
],
585 sizeof option_value
[STOP_POSTREC
],
587 trig_durations
[global_settings
.rec_stop_postrec
].string
);
590 option_value
[STOP_GAP
],
591 sizeof option_value
[STOP_GAP
],
593 trig_durations
[global_settings
.rec_stop_gap
].string
);
597 screens
[i
].set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
598 screens
[i
].fillrect(0, stat_height
, screens
[i
].width
,
599 screens
[i
].height
- stat_height
);
600 screens
[i
].set_drawmode(DRMODE_SOLID
);
603 gui_syncstatusbar_draw(&statusbars
, true);
605 /* reselect FONT_SYSFONT as status_draw has changed the font */
606 /*lcd_setfont(FONT_SYSFIXED);*/
610 for (k
= 0; k
< option_lines
[i
]; k
++) {
613 str
= P2STR(option_name
[k
+ offset
[i
]]);
614 screens
[i
].putsxy((option_lines
[i
] < TRIG_OPTION_COUNT
) ? 5 : 0,
615 stat_height
+ k
* h
, str
);
617 str
= option_value
[k
+ offset
[i
]];
618 screens
[i
].getstringsize(str
, &w
, &h
);
619 y
= stat_height
+ k
* h
;
620 x
= screens
[i
].width
- w
;
621 screens
[i
].putsxy(x
, y
, str
);
622 if ((int)selected
== (k
+ offset
[i
])) {
623 screens
[i
].set_drawmode(DRMODE_COMPLEMENT
);
624 screens
[i
].fillrect(x
, y
, w
, h
);
625 screens
[i
].set_drawmode(DRMODE_SOLID
);
628 if (option_lines
[i
] < TRIG_OPTION_COUNT
)
629 gui_scrollbar_draw(&screens
[i
], 0, stat_height
,
630 4, screens
[i
].height
- 16 - stat_height
,
631 TRIG_OPTION_COUNT
, offset
[i
], offset
[i
] + option_lines
[i
],
635 bool enqueue
= false;
637 talk_id(P2ID(option_name
[selected
]), enqueue
);
644 id
= P2ID(trigger_modes
[global_settings
.rec_trigger_mode
]);
647 id
= P2ID(trigger_types
[global_settings
.rec_trigger_type
]);
650 id
= prerecord_times
[global_settings
.rec_prerecord_time
]
653 case START_THRESHOLD
:
654 if (global_settings
.rec_start_thres
== -1)
656 else create_thres_str(global_settings
.rec_start_thres
, &id
);
659 id
= trig_durations
[global_settings
.rec_start_duration
]
663 if (global_settings
.rec_stop_thres
<= INF_DB
)
665 else create_thres_str(global_settings
.rec_stop_thres
, &id
);
668 id
= trig_durations
[global_settings
.rec_stop_postrec
].voice_id
;
671 id
= trig_durations
[global_settings
.rec_stop_gap
].voice_id
;
673 case TRIG_OPTION_COUNT
:
674 // avoid compiler warnings
677 talk_id(id
, enqueue
);
679 say_field
= say_value
= false;
681 peak_meter_draw_trig(trig_xpos
, trig_ypos
, trig_width
, NB_SCREENS
);
682 button
= peak_meter_draw_get_btn(0, pm_y
, 8, NB_SCREENS
);
688 case ACTION_STD_CANCEL
:
689 gui_syncsplash(50, str(LANG_CANCEL
));
690 global_settings
.rec_start_thres
= old_start_thres
;
691 global_settings
.rec_start_duration
= old_start_duration
;
692 global_settings
.rec_prerecord_time
= old_prerecord_time
;
693 global_settings
.rec_stop_thres
= old_stop_thres
;
694 global_settings
.rec_stop_postrec
= old_stop_postrec
;
695 global_settings
.rec_stop_gap
= old_stop_gap
;
696 global_settings
.rec_trigger_mode
= old_trigger_mode
;
697 global_settings
.rec_trigger_type
= old_trigger_type
;
701 case ACTION_REC_PAUSE
:
705 case ACTION_STD_PREV
:
706 selected
+= TRIG_OPTION_COUNT
- 1;
707 selected
%= TRIG_OPTION_COUNT
;
710 offset
[i
] = MIN(offset
[i
], (int)selected
);
711 offset
[i
] = MAX(offset
[i
], (int)selected
- option_lines
[i
] + 1);
713 say_field
= say_value
= true;
716 case ACTION_STD_NEXT
:
718 selected
%= TRIG_OPTION_COUNT
;
721 offset
[i
] = MIN(offset
[i
], (int)selected
);
722 offset
[i
] = MAX(offset
[i
], (int)selected
- option_lines
[i
] + 1);
724 say_field
= say_value
= true;
727 case ACTION_SETTINGS_INC
:
730 global_settings
.rec_trigger_mode
++;
731 global_settings
.rec_trigger_mode
%= TRIGGER_MODE_COUNT
;
735 global_settings
.rec_trigger_type
++;
736 global_settings
.rec_trigger_type
%= TRIGGER_TYPE_COUNT
;
740 global_settings
.rec_prerecord_time
++;
741 global_settings
.rec_prerecord_time
%= PRERECORD_TIMES_COUNT
;
744 case START_THRESHOLD
:
745 change_threshold(&global_settings
.rec_start_thres
, 1);
749 global_settings
.rec_start_duration
++;
750 global_settings
.rec_start_duration
%= TRIG_DURATION_COUNT
;
754 change_threshold(&global_settings
.rec_stop_thres
, 1);
758 global_settings
.rec_stop_postrec
++;
759 global_settings
.rec_stop_postrec
%= TRIG_DURATION_COUNT
;
763 global_settings
.rec_stop_gap
++;
764 global_settings
.rec_stop_gap
%= TRIG_DURATION_COUNT
;
767 case TRIG_OPTION_COUNT
:
768 // avoid compiler warnings
771 peak_meter_trigger(global_settings
.rec_trigger_mode
!=TRIG_OFF
);
772 settings_apply_trigger();
776 case ACTION_SETTINGS_DEC
:
779 global_settings
.rec_trigger_mode
+=TRIGGER_MODE_COUNT
-1;
780 global_settings
.rec_trigger_mode
%= TRIGGER_MODE_COUNT
;
784 global_settings
.rec_trigger_type
+=TRIGGER_TYPE_COUNT
-1;
785 global_settings
.rec_trigger_type
%= TRIGGER_TYPE_COUNT
;
789 global_settings
.rec_prerecord_time
+= PRERECORD_TIMES_COUNT
- 1;
790 global_settings
.rec_prerecord_time
%= PRERECORD_TIMES_COUNT
;
793 case START_THRESHOLD
:
794 change_threshold(&global_settings
.rec_start_thres
, -1);
798 global_settings
.rec_start_duration
+= TRIG_DURATION_COUNT
-1;
799 global_settings
.rec_start_duration
%= TRIG_DURATION_COUNT
;
803 change_threshold(&global_settings
.rec_stop_thres
, -1);
807 global_settings
.rec_stop_postrec
+=
808 TRIG_DURATION_COUNT
- 1;
809 global_settings
.rec_stop_postrec
%=
814 global_settings
.rec_stop_gap
+=
815 TRIG_DURATION_COUNT
- 1;
816 global_settings
.rec_stop_gap
%= TRIG_DURATION_COUNT
;
819 case TRIG_OPTION_COUNT
:
820 // avoid compiler warnings
823 peak_meter_trigger(global_settings
.rec_trigger_mode
!=TRIG_OFF
);
824 settings_apply_trigger();
829 peak_meter_trigger(true);
832 case SYS_USB_CONNECTED
:
833 if(default_event_handler(button
) == SYS_USB_CONNECTED
) {
841 peak_meter_trigger(false);
844 screens
[i
].setfont(FONT_UI
);
845 screens
[i
].setmargins(old_x_margin
[i
], old_y_margin
[i
]);
850 MENUITEM_FUNCTION(rectrigger_item
, 0, ID2P(LANG_RECORD_TRIGGER
),
851 (int(*)(void))rectrigger
, NULL
, NULL
, Icon_Menu_setting
);
858 /* from main_menu.c */
859 struct browse_folder_info
{
863 static struct browse_folder_info rec_config_browse
= {RECPRESETS_DIR
, SHOW_CFG
};
864 int browse_folder(void *param
);
865 MENUITEM_FUNCTION(browse_recconfigs
, MENU_FUNC_USEPARAM
, ID2P(LANG_CUSTOM_CFG
),
866 browse_folder
, (void*)&rec_config_browse
, NULL
, Icon_Config
);
867 static int write_settings_file(void)
869 return settings_save_config(SETTINGS_SAVE_RECPRESETS
);
871 MENUITEM_FUNCTION(save_recpresets_item
, 0, ID2P(LANG_SAVE_SETTINGS
),
872 write_settings_file
, NULL
, NULL
, Icon_Config
);
874 MAKE_MENU(recording_settings_menu
, ID2P(LANG_RECORDING_SETTINGS
),
875 NULL
, Icon_Recording
,
876 #if CONFIG_CODEC == MAS3587F
879 #if CONFIG_CODEC == SWCODEC
880 &recformat
, &enc_global_config_menu_item
,
882 &recfrequency
, &recsource
, /* recsource not shown if no_source */
884 #if CONFIG_CODEC == MAS3587F
887 &filesplitoptionsmenu
,
889 &clear_rec_directory_item
,
890 #ifdef HAVE_BACKLIGHT
895 &agc_preset
, &agc_cliptime
,
897 &browse_recconfigs
, &save_recpresets_item
900 bool recording_menu(bool no_source
)
903 no_source_in_menu
= no_source
;
904 retval
= do_menu(&recording_settings_menu
, NULL
) == MENU_ATTACHED_USB
;
905 no_source_in_menu
= false; /* always fall back to the default */
909 MENUITEM_FUNCTION(recording_settings
, MENU_FUNC_USEPARAM
, ID2P(LANG_RECORDING_SETTINGS
),
910 (int (*)(void*))recording_menu
, 0, NULL
, Icon_Recording
);