1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2003 Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
31 #include "mp3_playback.h"
36 #include "string-extra.h"
43 #include "peakmeter.h"
46 #include "sound_menu.h"
48 #include "recording.h"
50 #ifdef IPOD_ACCESSORY_PROTOCOL
53 #include "appevents.h"
58 #include "screen_access.h"
61 #include "buttonbar.h"
66 #include "menus/exported_menus.h"
67 #include "root_menu.h"
69 #include "skin_engine/skin_engine.h"
70 #include "statusbar-skinned.h"
71 #include "buffering.h"
72 #if CONFIG_CODEC == SWCODEC
79 #if CONFIG_KEYPAD == RECORDER_PAD
82 #define FM_PRESET_ACTION
86 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
89 #define FM_NEXT_PRESET
90 #define FM_PREV_PRESET
92 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
96 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
99 /* This should be removeable if the whole tuning thing is sorted out since
100 proper tuning quiets the screen almost entirely in that extreme measures
101 have to be taken to hear any interference. */
102 #define HAVE_NOISY_IDLE_MODE
104 #elif CONFIG_KEYPAD == ONDIO_PAD
105 #define FM_RECORD_DBLPRE
108 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD) ||\
109 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD)
117 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
121 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
129 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
130 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
137 #elif (CONFIG_KEYPAD == MPIO_HD200_PAD)
147 /* presets.c needs these so keep unstatic or redo the whole thing! */
148 int curr_freq
; /* current frequency in Hz */
150 static bool radio_menu(void);
152 int radio_mode
= RADIO_SCAN_MODE
;
153 static int search_dir
= 0;
155 static int radio_status
= FMRADIO_OFF
;
156 static bool in_screen
= false;
159 static void radio_off(void);
161 bool radio_scan_mode(void)
163 return radio_mode
== RADIO_SCAN_MODE
;
166 bool radio_is_stereo(void)
168 return tuner_get(RADIO_STEREO
) && !global_settings
.fm_force_mono
;
170 int radio_current_frequency(void)
175 /* Function to manipulate all yesno dialogues.
176 This function needs the output text as an argument. */
177 bool yesno_pop(const char* text
)
180 const char *lines
[]={text
};
181 const struct text_message message
={lines
, 1};
182 bool ret
= (gui_syncyesno_run(&message
,NULL
,NULL
)== YESNO_YES
);
184 screens
[i
].clear_viewport();
188 void radio_init(void)
193 radioart_init(false);
197 int get_radio_status(void)
202 bool in_radio_screen(void)
207 /* TODO: Move some more of the control functionality to firmware
208 and clean up the mess */
210 /* secret flag for starting paused - prevents unmute */
211 #define FMRADIO_START_PAUSED 0x8000
212 void radio_start(void)
214 const struct fm_region_data
*fmr
;
217 if(radio_status
== FMRADIO_PLAYING
)
220 fmr
= &fm_region_data
[global_settings
.fm_region
];
222 start_paused
= radio_status
& FMRADIO_START_PAUSED
;
223 /* clear flag before any yielding */
224 radio_status
&= ~FMRADIO_START_PAUSED
;
226 if(radio_status
== FMRADIO_OFF
)
229 curr_freq
= global_status
.last_frequency
* fmr
->freq_step
+ fmr
->freq_min
;
231 tuner_set(RADIO_SLEEP
, 0); /* wake up the tuner */
233 if(radio_status
== FMRADIO_OFF
)
235 #ifdef HAVE_RADIO_REGION
236 tuner_set(RADIO_REGION
, global_settings
.fm_region
);
238 tuner_set(RADIO_FORCE_MONO
, global_settings
.fm_force_mono
);
241 tuner_set(RADIO_FREQUENCY
, curr_freq
);
243 #ifdef HAVE_RADIO_MUTE_TIMEOUT
245 unsigned long mute_timeout
= current_tick
+ HZ
;
246 if (radio_status
!= FMRADIO_OFF
)
252 while(!tuner_get(RADIO_STEREO
) && !tuner_get(RADIO_TUNED
))
254 if(TIME_AFTER(current_tick
, mute_timeout
))
261 /* keep radio from sounding initially */
263 tuner_set(RADIO_MUTE
, 0);
265 radio_status
= FMRADIO_PLAYING
;
268 void radio_pause(void)
270 if(radio_status
== FMRADIO_PAUSED
)
273 if(radio_status
== FMRADIO_OFF
)
275 radio_status
|= FMRADIO_START_PAUSED
;
279 tuner_set(RADIO_MUTE
, 1);
280 /* For si4700: 2==this is really 'pause'. other tuners treat it
282 tuner_set(RADIO_SLEEP
, 2);
284 radio_status
= FMRADIO_PAUSED
;
287 static void radio_off(void)
289 tuner_set(RADIO_MUTE
, 1);
290 tuner_set(RADIO_SLEEP
, 1); /* low power mode, if available */
291 radio_status
= FMRADIO_OFF
;
292 tuner_power(false); /* status update, power off if avail. */
295 void radio_stop(void)
297 if(radio_status
== FMRADIO_OFF
)
303 bool radio_hardware_present(void)
305 return tuner_get(RADIO_PRESENT
);
308 /* Keep freq on the grid for the current region */
309 int snap_freq_to_grid(int freq
)
311 const struct fm_region_data
* const fmr
=
312 &fm_region_data
[global_settings
.fm_region
];
314 /* Range clamp if out of range or just round to nearest */
315 if (freq
< fmr
->freq_min
)
316 freq
= fmr
->freq_min
;
317 else if (freq
> fmr
->freq_max
)
318 freq
= fmr
->freq_max
;
320 freq
= (freq
- fmr
->freq_min
+ fmr
->freq_step
/2) /
321 fmr
->freq_step
* fmr
->freq_step
+ fmr
->freq_min
;
326 void remember_frequency(void)
328 const struct fm_region_data
* const fmr
=
329 &fm_region_data
[global_settings
.fm_region
];
330 global_status
.last_frequency
= (curr_freq
- fmr
->freq_min
)
335 /* Step to the next or previous frequency */
336 static int step_freq(int freq
, int direction
)
338 const struct fm_region_data
* const fmr
=
339 &fm_region_data
[global_settings
.fm_region
];
341 freq
+= direction
*fmr
->freq_step
;
343 /* Wrap first or snapping to grid will not let us on the band extremes */
344 if (freq
> fmr
->freq_max
)
345 freq
= direction
> 0 ? fmr
->freq_min
: fmr
->freq_max
;
346 else if (freq
< fmr
->freq_min
)
347 freq
= direction
< 0 ? fmr
->freq_max
: fmr
->freq_min
;
349 freq
= snap_freq_to_grid(freq
);
354 /* Step to the next or previous station */
355 void next_station(int direction
)
357 if (direction
!= 0 && radio_mode
!= RADIO_SCAN_MODE
)
359 preset_next(direction
);
363 curr_freq
= step_freq(curr_freq
, direction
);
365 if (radio_status
== FMRADIO_PLAYING
)
366 tuner_set(RADIO_MUTE
, 1);
368 tuner_set(RADIO_FREQUENCY
, curr_freq
);
370 if (radio_status
== FMRADIO_PLAYING
)
371 tuner_set(RADIO_MUTE
, 0);
373 preset_set_current(preset_find(curr_freq
));
374 remember_frequency();
377 /* Ends an in-progress search */
378 static void end_search(void)
380 if (search_dir
!= 0 && radio_status
== FMRADIO_PLAYING
)
381 tuner_set(RADIO_MUTE
, 0);
385 /* Speak a frequency. */
386 void talk_freq(int freq
, bool enqueue
)
389 talk_number(freq
/ 100, enqueue
);
390 talk_id(LANG_POINT
, true);
391 talk_number(freq
% 100 / 10, true);
393 talk_number(freq
% 10, true);
397 void radio_screen(void)
402 bool stereo
= false, last_stereo
= false;
404 bool screen_freeze
= false;
405 bool keep_playing
= false;
407 #ifdef FM_RECORD_DBLPRE
408 int lastbutton
= BUTTON_NONE
;
409 unsigned long rec_lastclick
= 0;
411 #if CONFIG_CODEC != SWCODEC
412 int timeout
= current_tick
+ HZ
/10;
413 unsigned int last_seconds
= 0;
414 #if !defined(SIMULATOR)
415 unsigned int seconds
= 0;
416 struct audio_recording_options rec_options
;
417 #endif /* SIMULATOR */
418 #endif /* CONFIG_CODEC != SWCODEC */
419 #ifndef HAVE_NOISY_IDLE_MODE
420 int button_timeout
= current_tick
+ (2*HZ
);
423 /* change status to "in screen" */
426 if(radio_preset_count() <= 0)
428 radio_load_presets(global_settings
.fmr_file
);
430 skin_get_global_state()->id3
= NULL
;
435 if(radio_status
== FMRADIO_OFF
)
440 #if CONFIG_CODEC != SWCODEC
441 rec_create_directory();
442 audio_init_recording(talk_get_bufsize());
444 sound_settings_apply();
445 /* Yes, we use the D/A for monitoring */
446 peak_meter_playback(true);
448 peak_meter_enable(true);
450 rec_init_recording_options(&rec_options
);
451 rec_options
.rec_source
= AUDIO_SRC_LINEIN
;
452 rec_set_recording_options(&rec_options
);
454 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN
),
455 sound_default(SOUND_RIGHT_GAIN
), AUDIO_GAIN_LINEIN
);
457 #endif /* CONFIG_CODEC != SWCODEC */
458 #endif /* ndef SIMULATOR */
461 #if CONFIG_CODEC == SWCODEC
462 /* This should be done before touching audio settings */
463 while (!audio_is_thread_ready())
466 audio_set_input_source(AUDIO_SRC_FMRADIO
,
467 (radio_status
== FMRADIO_PAUSED
) ?
468 SRCF_FMRADIO_PAUSED
: SRCF_FMRADIO_PLAYING
);
470 if (radio_status
== FMRADIO_OFF
)
474 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN
)))
477 fms_fix_displays(FMS_ENTER
);
479 skin_update(FM_SCREEN
, i
, SKIN_REFRESH_ALL
);
481 preset_set_current(preset_find(curr_freq
));
482 if(radio_current_preset() != -1)
483 radio_mode
= RADIO_PRESET_MODE
;
485 #ifndef HAVE_NOISY_IDLE_MODE
493 curr_freq
= step_freq(curr_freq
, search_dir
);
494 update_type
= SKIN_REFRESH_ALL
;
496 if(tuner_set(RADIO_SCAN_FREQUENCY
, curr_freq
))
498 preset_set_current(preset_find(curr_freq
));
499 remember_frequency();
511 button
= fms_do_button_loop(update_type
>0);
513 #ifndef HAVE_NOISY_IDLE_MODE
514 if (button
!= ACTION_NONE
)
516 cpu_idle_mode(false);
517 button_timeout
= current_tick
+ (2*HZ
);
523 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
524 if(audio_status() == AUDIO_STATUS_RECORD
)
532 if(presets_have_changed())
534 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES
)))
540 update_type
= SKIN_REFRESH_NON_STATIC
;
544 case ACTION_FM_RECORD
:
545 #ifdef FM_RECORD_DBLPRE
546 if (lastbutton
!= ACTION_FM_RECORD_DBLPRE
)
551 if (current_tick
- rec_lastclick
> HZ
/2)
553 rec_lastclick
= current_tick
;
556 #endif /* FM_RECORD_DBLPRE */
558 if(audio_status() == AUDIO_STATUS_RECORD
)
560 rec_command(RECORDING_CMD_START_NEWFILE
);
561 update_type
= SKIN_REFRESH_ALL
;
565 rec_command(RECORDING_CMD_START
);
566 update_type
= SKIN_REFRESH_ALL
;
568 #endif /* SIMULATOR */
571 #endif /* #ifdef FM_RECORD */
574 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
575 if(audio_status() == AUDIO_STATUS_RECORD
)
580 if(presets_have_changed())
582 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES
)))
590 case ACTION_STD_PREV
:
591 case ACTION_STD_NEXT
:
592 next_station(button
== ACTION_STD_PREV
? -1 : 1);
594 update_type
= SKIN_REFRESH_ALL
;
598 case ACTION_STD_PREVREPEAT
:
599 case ACTION_STD_NEXTREPEAT
:
601 int dir
= search_dir
;
602 search_dir
= button
== ACTION_STD_PREVREPEAT
? -1 : 1;
603 if (radio_mode
!= RADIO_SCAN_MODE
)
605 preset_next(search_dir
);
611 /* Starting auto scan */
612 tuner_set(RADIO_MUTE
, 1);
614 update_type
= SKIN_REFRESH_ALL
;
618 case ACTION_SETTINGS_INC
:
619 case ACTION_SETTINGS_INCREPEAT
:
620 global_settings
.volume
++;
622 update_type
= SKIN_REFRESH_NON_STATIC
;
625 case ACTION_SETTINGS_DEC
:
626 case ACTION_SETTINGS_DECREPEAT
:
627 global_settings
.volume
--;
629 update_type
= SKIN_REFRESH_NON_STATIC
;
633 if (radio_status
== FMRADIO_PLAYING
)
638 update_type
= SKIN_REFRESH_NON_STATIC
;
644 fms_fix_displays(FMS_EXIT
);
646 preset_set_current(preset_find(curr_freq
));
647 fms_fix_displays(FMS_ENTER
);
648 update_type
= SKIN_REFRESH_ALL
;
652 case ACTION_FM_PRESET
:
653 if(radio_preset_count() < 1)
655 splash(HZ
, ID2P(LANG_FM_NO_PRESETS
));
656 update_type
= SKIN_REFRESH_ALL
;
659 fms_fix_displays(FMS_EXIT
);
660 handle_radio_presets();
661 fms_fix_displays(FMS_ENTER
);
662 update_type
= SKIN_REFRESH_ALL
;
664 #endif /* FM_PRESET */
667 case ACTION_FM_FREEZE
:
670 splash(HZ
, str(LANG_FM_FREEZE
));
671 screen_freeze
= true;
675 update_type
= SKIN_REFRESH_ALL
;
676 screen_freeze
= false;
679 #endif /* FM_FREEZE */
681 case SYS_USB_CONNECTED
:
682 #if CONFIG_CODEC != SWCODEC
683 /* Only accept USB connection when not recording */
684 if(audio_status() != AUDIO_STATUS_RECORD
)
687 default_event_handler(SYS_USB_CONNECTED
);
688 screen_freeze
= true; /* Cosmetic: makes sure the
689 radio screen doesn't redraw */
696 if(radio_mode
== RADIO_SCAN_MODE
)
698 /* Force scan mode if there are no presets. */
699 if(radio_preset_count() > 0)
700 radio_mode
= RADIO_PRESET_MODE
;
703 radio_mode
= RADIO_SCAN_MODE
;
704 update_type
= SKIN_REFRESH_ALL
;
705 cond_talk_ids_fq(radio_mode
?
706 LANG_PRESET
: LANG_RADIO_SCAN_MODE
);
711 #ifdef FM_NEXT_PRESET
712 case ACTION_FM_NEXT_PRESET
:
715 update_type
= SKIN_REFRESH_ALL
;
720 #ifdef FM_PREV_PRESET
721 case ACTION_FM_PREV_PRESET
:
724 update_type
= SKIN_REFRESH_ALL
;
729 update_type
= SKIN_REFRESH_NON_STATIC
;
733 default_event_handler(button
);
735 if (tuner_get(RADIO_EVENT
))
736 update_type
= SKIN_REFRESH_ALL
;
738 if (!tuner_get(RADIO_PRESENT
))
740 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
741 if(audio_status() == AUDIO_STATUS_RECORD
)
744 keep_playing
= false;
746 if(presets_have_changed())
748 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES
)))
750 radio_save_presets();
754 /* Clear the preset list on exit. */
760 #ifdef FM_RECORD_DBLPRE
761 if (button
!= ACTION_NONE
)
765 #if CONFIG_CODEC != SWCODEC
771 /* Only display the peak meter when not recording */
772 #if CONFIG_CODEC != SWCODEC
773 if(TIME_AFTER(current_tick
, timeout
))
775 timeout
= current_tick
+ HZ
;
778 #endif /* CONFIG_CODEC == SWCODEC */
780 /* keep "mono" from always being displayed when paused */
781 if (radio_status
!= FMRADIO_PAUSED
)
783 stereo
= tuner_get(RADIO_STEREO
) &&
784 !global_settings
.fm_force_mono
;
786 if(stereo
!= last_stereo
)
788 update_type
= SKIN_REFRESH_ALL
;
789 last_stereo
= stereo
;
794 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
795 seconds
= audio_recorded_time() / HZ
;
796 if (update_type
|| seconds
> last_seconds
)
798 last_seconds
= seconds
;
804 skin_update(FM_SCREEN
, i
, update_type
);
809 if (global_settings
.talk_file
&& talk
810 && radio_status
== FMRADIO_PAUSED
)
813 bool enqueue
= false;
814 if (radio_mode
== RADIO_SCAN_MODE
)
816 talk_freq(curr_freq
, enqueue
);
819 if (radio_current_preset() >= 0)
820 preset_talk(radio_current_preset(), radio_mode
== RADIO_PRESET_MODE
,
824 #if CONFIG_CODEC != SWCODEC
825 if(audio_status() & AUDIO_STATUS_ERROR
)
831 #ifndef HAVE_NOISY_IDLE_MODE
832 if (TIME_AFTER(current_tick
, button_timeout
))
840 #if CONFIG_CODEC != SWCODEC
841 if(audio_status() & AUDIO_STATUS_ERROR
)
843 splash(0, str(LANG_DISK_FULL
));
848 button
= get_action(CONTEXT_FM
, TIMEOUT_BLOCK
);
849 if(button
== ACTION_FM_STOP
)
854 audio_init_playback();
855 #endif /* CONFIG_CODEC != SWCODEC */
857 sound_settings_apply();
858 #endif /* SIMULATOR */
862 /* Catch FMRADIO_PLAYING status for the sim. */
864 #if CONFIG_CODEC != SWCODEC
865 /* Enable the Left and right A/D Converter */
866 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN
),
867 sound_default(SOUND_RIGHT_GAIN
),
869 mas_codec_writereg(6, 0x4000);
872 #endif /* SIMULATOR */
876 #if CONFIG_CODEC == SWCODEC
877 audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
883 #ifndef HAVE_NOISY_IDLE_MODE
884 cpu_idle_mode(false);
886 fms_fix_displays(FMS_EXIT
);
890 void toggle_mono_mode(bool mono
)
892 tuner_set(RADIO_FORCE_MONO
, mono
);
895 void set_radio_region(int region
)
897 #ifdef HAVE_RADIO_REGION
898 tuner_set(RADIO_REGION
, region
);
901 remember_frequency();
905 MENUITEM_SETTING(set_region
, &global_settings
.fm_region
, NULL
);
906 MENUITEM_SETTING(force_mono
, &global_settings
.fm_force_mono
, NULL
);
909 static char* get_mode_text(int selected_item
, void * data
, char *buffer
)
913 snprintf(buffer
, MAX_PATH
, "%s %s", str(LANG_MODE
),
914 radio_mode
? str(LANG_PRESET
) :
915 str(LANG_RADIO_SCAN_MODE
));
918 static int toggle_radio_mode(void)
920 radio_mode
= (radio_mode
== RADIO_SCAN_MODE
) ?
921 RADIO_PRESET_MODE
: RADIO_SCAN_MODE
;
924 MENUITEM_FUNCTION_DYNTEXT(radio_mode_item
, 0,
925 toggle_radio_mode
, NULL
,
926 get_mode_text
, NULL
, NULL
, NULL
, Icon_NOICON
);
931 #ifdef HAVE_RECORDING
933 #if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
934 #define FM_RECORDING_SCREEN
935 static int fm_recording_screen(void)
939 /* switch recording source to FMRADIO for the duration */
940 int rec_source
= global_settings
.rec_source
;
941 global_settings
.rec_source
= AUDIO_SRC_FMRADIO
;
942 ret
= recording_screen(true);
944 /* safe to reset as changing sources is prohibited here */
945 global_settings
.rec_source
= rec_source
;
950 #endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
952 #if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
953 #define FM_RECORDING_SETTINGS
954 static int fm_recording_settings(void)
956 bool ret
= recording_menu(true);
958 #if CONFIG_CODEC != SWCODEC
961 struct audio_recording_options rec_options
;
962 rec_init_recording_options(&rec_options
);
963 rec_options
.rec_source
= AUDIO_SRC_LINEIN
;
964 rec_set_recording_options(&rec_options
);
971 #endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
972 #endif /* HAVE_RECORDING */
974 #ifdef FM_RECORDING_SCREEN
975 MENUITEM_FUNCTION(recscreen_item
, 0, ID2P(LANG_RECORDING
),
976 fm_recording_screen
, NULL
, NULL
, Icon_Recording
);
978 #ifdef FM_RECORDING_SETTINGS
979 MENUITEM_FUNCTION(recsettings_item
, 0, ID2P(LANG_RECORDING_SETTINGS
),
980 fm_recording_settings
, NULL
, NULL
, Icon_Recording
);
983 MENUITEM_FUNCTION(radio_presets_item
, 0, ID2P(LANG_PRESET
),
984 handle_radio_presets
, NULL
, NULL
, Icon_NOICON
);
986 #ifndef FM_PRESET_ADD
987 MENUITEM_FUNCTION(radio_addpreset_item
, 0, ID2P(LANG_FM_ADD_PRESET
),
988 handle_radio_add_preset
, NULL
, NULL
, Icon_NOICON
);
991 MENUITEM_FUNCTION(presetload_item
, 0, ID2P(LANG_FM_PRESET_LOAD
),
992 preset_list_load
, NULL
, NULL
, Icon_NOICON
);
993 MENUITEM_FUNCTION(presetsave_item
, 0, ID2P(LANG_FM_PRESET_SAVE
),
994 preset_list_save
, NULL
, NULL
, Icon_NOICON
);
995 MENUITEM_FUNCTION(presetclear_item
, 0, ID2P(LANG_FM_PRESET_CLEAR
),
996 preset_list_clear
, NULL
, NULL
, Icon_NOICON
);
997 MENUITEM_FUNCTION(scan_presets_item
, MENU_FUNC_USEPARAM
,
998 ID2P(LANG_FM_SCAN_PRESETS
),
999 presets_scan
, NULL
, NULL
, Icon_NOICON
);
1001 MAKE_MENU(radio_settings_menu
, ID2P(LANG_FM_MENU
), NULL
,
1004 &radio_presets_item
,
1006 #ifndef FM_PRESET_ADD
1007 &radio_addpreset_item
,
1009 &presetload_item
, &presetsave_item
, &presetclear_item
,
1014 &set_region
, &sound_settings
,
1015 #ifdef FM_RECORDING_SCREEN
1018 #ifdef FM_RECORDING_SETTINGS
1021 &scan_presets_item
);
1022 /* main menu of the radio screen */
1023 static bool radio_menu(void)
1025 return do_menu(&radio_settings_menu
, NULL
, NULL
, false) ==