1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
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 ****************************************************************************/
28 #include "mp3_playback.h"
30 #include "statusbar.h"
32 #ifdef HAVE_LCD_BITMAP
35 #include "scrollbar.h"
49 #include "peakmeter.h"
53 #if CONFIG_CODEC == SWCODEC
55 #include "menus/eq_menu.h"
58 #include "enc_config.h"
65 static bool recsource(void)
67 int n_opts
= AUDIO_NUM_SOURCES
;
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
) },
73 [AUDIO_SRC_SPDIF
] = { STR(LANG_RECORDING_SRC_DIGITAL
) },
75 #ifdef HAVE_FMRADIO_IN
76 [AUDIO_SRC_FMRADIO
] = { STR(LANG_FM_RADIO
) }
80 /* caveat: assumes it's the last item! */
81 #ifdef HAVE_FMRADIO_IN
82 if (!radio_hardware_present())
86 return set_option(str(LANG_RECORDING_SOURCE
),
87 &global_settings
.rec_source
, INT
, names
,
91 #if CONFIG_CODEC == MAS3587F
92 static bool recquality(void)
94 return set_int(str(LANG_RECORDING_QUALITY
), "", UNIT_INT
,
95 &global_settings
.rec_quality
,
96 NULL
, 1, 0, 7, NULL
);
99 static bool receditable(void)
101 return set_bool(str(LANG_RECORDING_EDITABLE
),
102 &global_settings
.rec_editable
);
104 #endif /* CONFIG_CODEC == MAS3587F */
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
,
111 struct opt_items
*dst_names
)
113 while (--n_indexes
>= 0)
114 dst_names
[n_indexes
] = src_names
[src_indexes
[n_indexes
]];
115 } /* make_options_from_indexes */
117 static bool recformat(void)
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
) },
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
);
130 if (rec_format
!= global_settings
.rec_format
)
132 global_settings
.rec_format
= rec_format
;
133 enc_global_settings_apply();
139 #endif /* CONFIG_CODEC == SWCODEC */
141 static bool recfrequency(void)
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
) }
152 return set_option(str(LANG_RECORDING_FREQUENCY
),
153 &global_settings
.rec_frequency
, INT
,
155 #endif /* CONFIG_CODEC == MAS3587F */
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
) },)
173 struct opt_items opts
[REC_NUM_FREQ
];
174 unsigned long table
[REC_NUM_FREQ
];
180 if (global_settings
.rec_source
== AUDIO_SRC_SPDIF
)
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
;
191 struct encoder_caps caps
;
192 struct encoder_config cfg
;
194 cfg
.rec_format
= global_settings
.rec_format
;
195 global_to_encoder_config(&cfg
);
197 if (!enc_get_caps(&cfg
, &caps
, true))
200 /* Construct samplerate menu based upon encoder settings */
201 n_opts
= make_list_from_caps32(REC_SAMPR_CAPS
, NULL
,
202 caps
.samplerate_caps
, table
);
205 return false; /* No common flags...?? */
207 make_options_from_indexes(names
, table
, n_opts
, opts
);
209 /* Find closest rate that the potentially restricted list
211 make_list_from_caps32(REC_SAMPR_CAPS
, rec_freq_sampr
,
212 caps
.samplerate_caps
, table
);
214 rec_frequency
= round_value_to_list32(
215 rec_freq_sampr
[global_settings
.rec_frequency
],
216 table
, n_opts
, false);
219 ret
= set_option(str(LANG_RECORDING_FREQUENCY
),
220 &rec_frequency
, INT
, opts
, n_opts
, NULL
);
224 && global_settings
.rec_source
!= AUDIO_SRC_SPDIF
228 /* Translate back to full index */
229 global_settings
.rec_frequency
=
230 round_value_to_list32(table
[rec_frequency
],
237 #endif /* CONFIG_CODEC == SWCODEC */
240 static bool recchannels(void)
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
) }
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 */
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
;
261 cfg
.rec_format
= global_settings
.rec_format
;
262 global_to_encoder_config(&cfg
);
264 if (!enc_get_caps(&cfg
, &caps
, true))
267 n_opts
= make_list_from_caps32(CHN_CAP_ALL
, NULL
,
268 caps
.channel_caps
, table
);
270 rec_channels
= round_value_to_list32(global_settings
.rec_channels
,
271 table
, n_opts
, false);
273 make_options_from_indexes(names
, table
, n_opts
, opts
);
275 ret
= set_option(str(LANG_RECORDING_CHANNELS
), &rec_channels
,
276 INT
, opts
, n_opts
, NULL
);
279 global_settings
.rec_channels
= table
[rec_channels
];
282 #endif /* CONFIG_CODEC == SWCODEC */
285 static bool rectimesplit(void)
287 static const struct opt_items names
[] = {
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
) }
305 return set_option(str(LANG_SPLIT_TIME
),
306 &global_settings
.rec_timesplit
, INT
,
310 static bool recsizesplit(void)
312 static const struct opt_items names
[] = {
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
) }
330 return set_option(str(LANG_SPLIT_SIZE
),
331 &global_settings
.rec_sizesplit
, INT
,
335 static bool splitmethod(void)
337 static const struct opt_items names
[] = {
338 { STR(LANG_REC_TIME
) },
339 { STR(LANG_REC_SIZE
) },
342 ret
=set_option( str(LANG_SPLIT_MEASURE
),
343 &global_settings
.rec_split_method
, INT
, names
, 2, NULL
);
347 static bool splittype(void)
349 static const struct opt_items names
[] = {
350 { STR(LANG_START_NEW_FILE
) },
351 { STR(LANG_STOP_RECORDING
) },
354 ret
=set_option( str(LANG_SPLIT_TYPE
),
355 &global_settings
.rec_split_type
, INT
, names
, 2, NULL
);
359 static bool filesplitoptionsmenu(void)
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
}
370 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
372 result
= menu_run(m
);
376 static bool recprerecord(void)
378 static const struct opt_items names
[] = {
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
) }
411 return set_option(str(LANG_RECORD_PRERECORD_TIME
),
412 &global_settings
.rec_prerecord_time
, INT
,
416 static bool recdirectory(void)
418 static const struct opt_items names
[] = {
419 { rec_base_directory
, -1 },
420 { STR(LANG_RECORD_CURRENT_DIR
) }
422 return set_option(str(LANG_RECORD_DIRECTORY
),
423 &global_settings
.rec_directory
, INT
,
428 static bool cliplight(void)
430 static const struct opt_items names
[] = {
432 { STR(LANG_MAIN_UNIT
) }
433 #ifdef HAVE_REMOTE_LCD
434 , { STR(LANG_REMOTE_MAIN
) },
435 { STR(LANG_REMOTE_UNIT
) }
439 return set_option( str(LANG_CLIP_LIGHT
),
440 &global_settings
.cliplight
, INT
, names
,
441 #ifdef HAVE_REMOTE_LCD
447 #endif /*CONFIG_BACKLIGHT */
450 static bool agc_preset(void)
452 static const struct opt_items names
[] = {
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
) },
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
);
465 return set_option(str(LANG_RECORD_AGC_PRESET
),
466 &global_settings
.rec_agc_preset_mic
,
467 INT
, names
, 6, NULL
);
470 static bool agc_cliptime(void)
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
) }
479 return set_option(str(LANG_RECORD_AGC_CLIPTIME
),
480 &global_settings
.rec_agc_cliptime
,
481 INT
, names
, 5, NULL
);
483 #endif /* HAVE_AGC */
484 #endif /* HAVE_RECORDING */
488 #ifdef HAVE_RECORDING
489 enum trigger_menu_option
502 #ifdef HAVE_RECORDING
503 static char* create_thres_str(int threshold
)
505 static char retval
[6];
507 if (threshold
< -88) {
508 snprintf (retval
, sizeof retval
, "%s", str(LANG_DB_INF
));
510 snprintf (retval
, sizeof retval
, "%ddb", threshold
+ 1);
513 snprintf (retval
, sizeof retval
, "%d%%", threshold
);
519 static void change_threshold(int *threshold
, int change
)
521 if (global_settings
.peak_meter_dbfs
) {
522 if (*threshold
>= 0) {
523 int db
= (calc_db(*threshold
* MAX_PEAK
/ 100) - 9000) / 100;
526 *threshold
+= change
;
527 if (*threshold
> -1) {
529 } else if (*threshold
< INF_DB
) {
533 if (*threshold
< 0) {
534 *threshold
= peak_meter_db2sample(*threshold
* 100) * 100 / MAX_PEAK
;
536 *threshold
+= change
;
537 if (*threshold
> 100) {
539 } else if (*threshold
< 0) {
546 * Displays a menu for editing the trigger settings.
548 bool rectrigger(void)
550 int exit_request
= false;
551 enum trigger_menu_option selected
= TRIGGER_MODE
;
553 int old_x_margin
[NB_SCREENS
];
554 int old_y_margin
[NB_SCREENS
];
556 #define TRIGGER_MODE_COUNT 3
557 static const unsigned char *trigger_modes
[] = {
559 ID2P(LANG_RECORD_TRIG_NOREARM
),
560 ID2P(LANG_RECORD_TRIG_REARM
)
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",
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
),
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
)
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
;
598 int offset
[NB_SCREENS
];
599 int option_lines
[NB_SCREENS
];
601 int stat_height
= global_settings
.statusbar
? STATUSBAR_HEIGHT
: 0;
602 int pm_y
[NB_SCREENS
];
604 int trig_xpos
[NB_SCREENS
];
605 int trig_ypos
[NB_SCREENS
];
606 int trig_width
[NB_SCREENS
];
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
;
617 /* restart trigger with new values */
618 settings_apply_trigger();
619 peak_meter_trigger (global_settings
.rec_trigger_mode
!= TRIG_MODE_OFF
);
623 screens
[i
].clear_display();
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
);
630 screens
[i
].setmargins(0, 0);
632 screens
[i
].getstringsize("M", &w
, &h
);
634 // 16 pixels are reserved for peak meter and trigger status
635 option_lines
[i
] = MIN(((screens
[i
].height
) -
640 while (!exit_request
) {
643 char option_value
[TRIG_OPTION_COUNT
][9];
646 option_value
[TRIGGER_MODE
],
647 sizeof option_value
[TRIGGER_MODE
],
649 P2STR(trigger_modes
[global_settings
.rec_trigger_mode
]));
652 option_value
[TRIGGER_TYPE
],
653 sizeof option_value
[TRIGGER_TYPE
],
655 P2STR(trigger_types
[global_settings
.rec_trigger_type
]));
658 option_value
[TRIGGER_TYPE
],
659 sizeof option_value
[TRIGGER_TYPE
],
661 P2STR(trigger_types
[global_settings
.rec_trigger_type
]));
664 option_value
[PRERECORD_TIME
],
665 sizeof option_value
[PRERECORD_TIME
],
667 P2STR(prerecord_times
[global_settings
.rec_prerecord_time
]));
669 /* due to value range shift (peak_meter_define_trigger) -1 is 0db */
670 if (global_settings
.rec_start_thres
== -1) {
673 str
= create_thres_str(global_settings
.rec_start_thres
);
676 option_value
[START_THRESHOLD
],
677 sizeof option_value
[START_THRESHOLD
],
682 option_value
[START_DURATION
],
683 sizeof option_value
[START_DURATION
],
685 trig_durations
[global_settings
.rec_start_duration
]);
688 if (global_settings
.rec_stop_thres
<= INF_DB
) {
691 str
= create_thres_str(global_settings
.rec_stop_thres
);
694 option_value
[STOP_THRESHOLD
],
695 sizeof option_value
[STOP_THRESHOLD
],
700 option_value
[STOP_POSTREC
],
701 sizeof option_value
[STOP_POSTREC
],
703 trig_durations
[global_settings
.rec_stop_postrec
]);
706 option_value
[STOP_GAP
],
707 sizeof option_value
[STOP_GAP
],
709 trig_durations
[global_settings
.rec_stop_gap
]);
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
);
719 gui_syncstatusbar_draw(&statusbars
, true);
721 /* reselect FONT_SYSFONT as status_draw has changed the font */
722 /*lcd_setfont(FONT_SYSFIXED);*/
726 for (k
= 0; k
< option_lines
[i
]; k
++) {
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
);
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
);
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
],
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
);
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
;
771 case ACTION_REC_PAUSE
:
775 case ACTION_STD_PREV
:
776 selected
+= TRIG_OPTION_COUNT
- 1;
777 selected
%= TRIG_OPTION_COUNT
;
780 offset
[i
] = MIN(offset
[i
], (int)selected
);
781 offset
[i
] = MAX(offset
[i
], (int)selected
- option_lines
[i
] + 1);
785 case ACTION_STD_NEXT
:
787 selected
%= TRIG_OPTION_COUNT
;
790 offset
[i
] = MIN(offset
[i
], (int)selected
);
791 offset
[i
] = MAX(offset
[i
], (int)selected
- option_lines
[i
] + 1);
795 case ACTION_SETTINGS_INC
:
798 global_settings
.rec_trigger_mode
++;
799 global_settings
.rec_trigger_mode
%= TRIGGER_MODE_COUNT
;
803 global_settings
.rec_trigger_type
++;
804 global_settings
.rec_trigger_type
%= TRIGGER_TYPE_COUNT
;
808 global_settings
.rec_prerecord_time
++;
809 global_settings
.rec_prerecord_time
%= PRERECORD_TIMES_COUNT
;
812 case START_THRESHOLD
:
813 change_threshold(&global_settings
.rec_start_thres
, 1);
817 global_settings
.rec_start_duration
++;
818 global_settings
.rec_start_duration
%= TRIG_DURATION_COUNT
;
822 change_threshold(&global_settings
.rec_stop_thres
, 1);
826 global_settings
.rec_stop_postrec
++;
827 global_settings
.rec_stop_postrec
%= TRIG_DURATION_COUNT
;
831 global_settings
.rec_stop_gap
++;
832 global_settings
.rec_stop_gap
%= TRIG_DURATION_COUNT
;
835 case TRIG_OPTION_COUNT
:
836 // avoid compiler warnings
839 peak_meter_trigger(global_settings
.rec_trigger_mode
!=TRIG_OFF
);
840 settings_apply_trigger();
843 case ACTION_SETTINGS_DEC
:
846 global_settings
.rec_trigger_mode
+=TRIGGER_MODE_COUNT
-1;
847 global_settings
.rec_trigger_mode
%= TRIGGER_MODE_COUNT
;
851 global_settings
.rec_trigger_type
+=TRIGGER_TYPE_COUNT
-1;
852 global_settings
.rec_trigger_type
%= TRIGGER_TYPE_COUNT
;
856 global_settings
.rec_prerecord_time
+= PRERECORD_TIMES_COUNT
- 1;
857 global_settings
.rec_prerecord_time
%= PRERECORD_TIMES_COUNT
;
860 case START_THRESHOLD
:
861 change_threshold(&global_settings
.rec_start_thres
, -1);
865 global_settings
.rec_start_duration
+= TRIG_DURATION_COUNT
-1;
866 global_settings
.rec_start_duration
%= TRIG_DURATION_COUNT
;
870 change_threshold(&global_settings
.rec_stop_thres
, -1);
874 global_settings
.rec_stop_postrec
+=
875 TRIG_DURATION_COUNT
- 1;
876 global_settings
.rec_stop_postrec
%=
881 global_settings
.rec_stop_gap
+=
882 TRIG_DURATION_COUNT
- 1;
883 global_settings
.rec_stop_gap
%= TRIG_DURATION_COUNT
;
886 case TRIG_OPTION_COUNT
:
887 // avoid compiler warnings
890 peak_meter_trigger(global_settings
.rec_trigger_mode
!=TRIG_OFF
);
891 settings_apply_trigger();
895 peak_meter_trigger(true);
898 case SYS_USB_CONNECTED
:
899 if(default_event_handler(button
) == SYS_USB_CONNECTED
) {
907 peak_meter_trigger(false);
910 screens
[i
].setfont(FONT_UI
);
911 screens
[i
].setmargins(old_x_margin
[i
], old_y_margin
[i
]);
913 action_signalscreenchange();
916 #endif /* !defined(SIMULATOR) && CONFIG_CODEC == MAS3587F */
918 bool recording_menu(bool no_source
)
920 static const struct menu_item static_items
[] = {
921 #if CONFIG_CODEC == MAS3587F
922 { ID2P(LANG_RECORDING_QUALITY
), recquality
},
924 #if CONFIG_CODEC == SWCODEC
925 { ID2P(LANG_RECORDING_FORMAT
), recformat
},
926 { ID2P(LANG_ENCODER_SETTINGS
), enc_global_config_menu
},
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
},
934 { ID2P(LANG_RECORD_TIMESPLIT
), filesplitoptionsmenu
},
935 { ID2P(LANG_RECORD_PRERECORD_TIME
), recprerecord
},
936 { ID2P(LANG_RECORD_DIRECTORY
), recdirectory
},
938 { ID2P(LANG_CLIP_LIGHT
), cliplight
},
940 { ID2P(LANG_RECORD_TRIGGER
), rectrigger
},
942 { ID2P(LANG_RECORD_AGC_PRESET
), agc_preset
},
943 { ID2P(LANG_RECORD_AGC_CLIPTIME
), agc_cliptime
},
947 struct menu_item items
[ARRAYLEN(static_items
)];
953 for (i
= 0, n_items
= 0; i
< (int)ARRAYLEN(items
); i
++)
955 const struct menu_item
*mi
= &static_items
[i
];
956 if (no_source
&& mi
->function
== recsource
)
958 items
[n_items
++] = *mi
;
961 m
= menu_init(items
, n_items
, NULL
, NULL
, NULL
, NULL
);
962 result
= menu_run(m
);
966 } /* recording_menu */
968 #endif /* HAVE_RECORDING */