libmad: Optimize away 2 instructions from coldfire III_imdct, no measurable speed...
[kugel-rb.git] / apps / radio / radio.c
blob5b09ad2fe83f970691f1c3d50432f170b242e18d
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include "config.h"
23 #include <stdio.h>
24 #include <stdbool.h>
25 #include <stdlib.h>
26 #include "mas.h"
27 #include "settings.h"
28 #include "button.h"
29 #include "status.h"
30 #include "thread.h"
31 #include "audio.h"
32 #include "mp3_playback.h"
33 #include "ctype.h"
34 #include "file.h"
35 #include "general.h"
36 #include "errno.h"
37 #include "string-extra.h"
38 #include "system.h"
39 #include "radio.h"
40 #include "menu.h"
41 #include "misc.h"
42 #include "keyboard.h"
43 #include "screens.h"
44 #include "peakmeter.h"
45 #include "lang.h"
46 #include "font.h"
47 #include "sound_menu.h"
48 #ifdef HAVE_RECORDING
49 #include "recording.h"
50 #endif
51 #ifdef IPOD_ACCESSORY_PROTOCOL
52 #include "iap.h"
53 #endif
54 #include "appevents.h"
55 #include "talk.h"
56 #include "tuner.h"
57 #include "power.h"
58 #include "sound.h"
59 #include "screen_access.h"
60 #include "splash.h"
61 #include "yesno.h"
62 #include "buttonbar.h"
63 #include "tree.h"
64 #include "dir.h"
65 #include "action.h"
66 #include "list.h"
67 #include "menus/exported_menus.h"
68 #include "root_menu.h"
69 #include "viewport.h"
70 #include "skin_engine/skin_engine.h"
71 #include "statusbar-skinned.h"
72 #include "buffering.h"
73 #if CONFIG_CODEC == SWCODEC
74 #include "playback.h"
75 #endif
77 #if CONFIG_TUNER
79 #if CONFIG_KEYPAD == RECORDER_PAD
80 #define FM_RECORD
81 #define FM_PRESET_ADD
82 #define FM_PRESET_ACTION
83 #define FM_PRESET
84 #define FM_MODE
86 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
87 #define FM_PRESET
88 #define FM_MODE
89 #define FM_NEXT_PRESET
90 #define FM_PREV_PRESET
92 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
93 #define FM_PRESET
94 #define FM_MODE
96 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
97 #define FM_PRESET
98 #define FM_MODE
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
106 #define FM_RECORD
107 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD)
108 #define FM_MENU
109 #define FM_PRESET
110 #define FM_STOP
111 #define FM_MODE
112 #define FM_EXIT
113 #define FM_PLAY
115 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
116 #define FM_PRESET
117 #define FM_MODE
119 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
120 #define FM_MENU
121 #define FM_PRESET
122 #define FM_STOP
123 #define FM_MODE
124 #define FM_EXIT
125 #define FM_PLAY
127 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
128 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
129 #define FM_MENU
130 #define FM_STOP
131 #define FM_EXIT
132 #define FM_PLAY
133 #define FM_MODE
135 #endif
137 /* presets.c needs these so keep unstatic or redo the whole thing! */
138 int curr_freq; /* current frequency in Hz */
139 /* these are all in presets.c... someone PLEASE rework this ! */
140 int handle_radio_presets(void);
141 static bool radio_menu(void);
142 int radio_add_preset(void);
143 int save_preset_list(void);
144 int load_preset_list(void);
145 int clear_preset_list(void);
146 void next_preset(int direction);
147 void set_current_preset(int preset);
148 int scan_presets(void *viewports);
149 int find_preset(int freq);
150 void radio_save_presets(void);
151 bool has_presets_changed(void);
152 void talk_preset(int preset, bool fallback, bool enqueue);
153 void presets_save(void);
157 int radio_mode = RADIO_SCAN_MODE;
158 static int search_dir = 0;
160 static int radio_status = FMRADIO_OFF;
161 static bool in_screen = false;
164 static void radio_off(void);
166 bool radio_scan_mode(void)
168 return radio_mode == RADIO_SCAN_MODE;
171 bool radio_is_stereo(void)
173 return tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono;
175 int radio_current_frequency(void)
177 return curr_freq;
180 /* Function to manipulate all yesno dialogues.
181 This function needs the output text as an argument. */
182 bool yesno_pop(const char* text)
184 int i;
185 const char *lines[]={text};
186 const struct text_message message={lines, 1};
187 bool ret = (gui_syncyesno_run(&message,NULL,NULL)== YESNO_YES);
188 FOR_NB_SCREENS(i)
189 screens[i].clear_viewport();
190 return ret;
193 void radio_init(void)
195 tuner_init();
196 radio_off();
197 #ifdef HAVE_ALBUMART
198 radioart_init(false);
199 #endif
202 int get_radio_status(void)
204 return radio_status;
207 bool in_radio_screen(void)
209 return in_screen;
212 /* TODO: Move some more of the control functionality to firmware
213 and clean up the mess */
215 /* secret flag for starting paused - prevents unmute */
216 #define FMRADIO_START_PAUSED 0x8000
217 void radio_start(void)
219 const struct fm_region_data *fmr;
220 bool start_paused;
222 if(radio_status == FMRADIO_PLAYING)
223 return;
225 fmr = &fm_region_data[global_settings.fm_region];
227 start_paused = radio_status & FMRADIO_START_PAUSED;
228 /* clear flag before any yielding */
229 radio_status &= ~FMRADIO_START_PAUSED;
231 if(radio_status == FMRADIO_OFF)
232 tuner_power(true);
234 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
236 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
238 if(radio_status == FMRADIO_OFF)
240 #ifdef HAVE_RADIO_REGION
241 tuner_set(RADIO_REGION, global_settings.fm_region);
242 #endif
243 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
246 tuner_set(RADIO_FREQUENCY, curr_freq);
248 #ifdef HAVE_RADIO_MUTE_TIMEOUT
250 unsigned long mute_timeout = current_tick + HZ;
251 if (radio_status != FMRADIO_OFF)
253 /* paused */
254 mute_timeout += HZ;
257 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
259 if(TIME_AFTER(current_tick, mute_timeout))
260 break;
261 yield();
264 #endif
266 /* keep radio from sounding initially */
267 if(!start_paused)
268 tuner_set(RADIO_MUTE, 0);
270 radio_status = FMRADIO_PLAYING;
271 } /* radio_start */
273 void radio_pause(void)
275 if(radio_status == FMRADIO_PAUSED)
276 return;
278 if(radio_status == FMRADIO_OFF)
280 radio_status |= FMRADIO_START_PAUSED;
281 radio_start();
284 tuner_set(RADIO_MUTE, 1);
285 /* For si4700: 2==this is really 'pause'. other tuners treat it
286 * like 'bool'. */
287 tuner_set(RADIO_SLEEP, 2);
289 radio_status = FMRADIO_PAUSED;
290 } /* radio_pause */
292 static void radio_off(void)
294 tuner_set(RADIO_MUTE, 1);
295 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
296 radio_status = FMRADIO_OFF;
297 tuner_power(false); /* status update, power off if avail. */
300 void radio_stop(void)
302 if(radio_status == FMRADIO_OFF)
303 return;
305 radio_off();
306 } /* radio_stop */
308 bool radio_hardware_present(void)
310 return tuner_get(RADIO_PRESENT);
313 /* Keep freq on the grid for the current region */
314 int snap_freq_to_grid(int freq)
316 const struct fm_region_data * const fmr =
317 &fm_region_data[global_settings.fm_region];
319 /* Range clamp if out of range or just round to nearest */
320 if (freq < fmr->freq_min)
321 freq = fmr->freq_min;
322 else if (freq > fmr->freq_max)
323 freq = fmr->freq_max;
324 else
325 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
326 fmr->freq_step * fmr->freq_step + fmr->freq_min;
328 return freq;
331 void remember_frequency(void)
333 const struct fm_region_data * const fmr =
334 &fm_region_data[global_settings.fm_region];
335 global_status.last_frequency = (curr_freq - fmr->freq_min)
336 / fmr->freq_step;
337 status_save();
340 /* Step to the next or previous frequency */
341 static int step_freq(int freq, int direction)
343 const struct fm_region_data * const fmr =
344 &fm_region_data[global_settings.fm_region];
346 freq += direction*fmr->freq_step;
348 /* Wrap first or snapping to grid will not let us on the band extremes */
349 if (freq > fmr->freq_max)
350 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
351 else if (freq < fmr->freq_min)
352 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
353 else
354 freq = snap_freq_to_grid(freq);
356 return freq;
359 /* Step to the next or previous station */
360 void next_station(int direction)
362 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
364 next_preset(direction);
365 return;
368 curr_freq = step_freq(curr_freq, direction);
370 if (radio_status == FMRADIO_PLAYING)
371 tuner_set(RADIO_MUTE, 1);
373 tuner_set(RADIO_FREQUENCY, curr_freq);
375 if (radio_status == FMRADIO_PLAYING)
376 tuner_set(RADIO_MUTE, 0);
378 set_current_preset(find_preset(curr_freq));
379 remember_frequency();
382 /* Ends an in-progress search */
383 static void end_search(void)
385 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
386 tuner_set(RADIO_MUTE, 0);
387 search_dir = 0;
390 /* Speak a frequency. */
391 void talk_freq(int freq, bool enqueue)
393 freq /= 10000;
394 talk_number(freq / 100, enqueue);
395 talk_id(LANG_POINT, true);
396 talk_number(freq % 100 / 10, true);
397 if (freq % 10)
398 talk_number(freq % 10, true);
402 int radio_screen(void)
404 bool done = false;
405 int ret_val = GO_TO_ROOT;
406 int button;
407 int i;
408 bool stereo = false, last_stereo = false;
409 bool update_screen = true, restore = true;
410 bool screen_freeze = false;
411 bool keep_playing = false;
412 bool talk = false;
413 #ifdef FM_RECORD_DBLPRE
414 int lastbutton = BUTTON_NONE;
415 unsigned long rec_lastclick = 0;
416 #endif
417 #if CONFIG_CODEC != SWCODEC
418 bool have_recorded = false;
419 int timeout = current_tick + HZ/10;
420 unsigned int last_seconds = 0;
421 #ifndef SIMULATOR
422 unsigned int seconds = 0;
423 struct audio_recording_options rec_options;
424 #endif
425 #endif /* CONFIG_CODEC != SWCODEC */
426 #ifndef HAVE_NOISY_IDLE_MODE
427 int button_timeout = current_tick + (2*HZ);
428 #endif
430 /* change status to "in screen" */
431 in_screen = true;
433 if(radio_preset_count() <= 0)
435 radio_load_presets(global_settings.fmr_file);
437 #ifdef HAVE_ALBUMART
438 radioart_init(true);
439 #endif
441 if(radio_status == FMRADIO_OFF)
442 audio_stop();
444 #ifndef SIMULATOR
446 #if CONFIG_CODEC != SWCODEC
447 if(rec_create_directory() > 0)
448 have_recorded = true;
450 audio_init_recording(talk_get_bufsize());
452 sound_settings_apply();
453 /* Yes, we use the D/A for monitoring */
454 peak_meter_playback(true);
456 peak_meter_enable(true);
458 rec_init_recording_options(&rec_options);
459 rec_options.rec_source = AUDIO_SRC_LINEIN;
460 rec_set_recording_options(&rec_options);
462 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
463 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
465 #endif /* CONFIG_CODEC != SWCODEC */
466 #endif /* ndef SIMULATOR */
468 /* turn on radio */
469 #if CONFIG_CODEC == SWCODEC
470 /* This should be done before touching audio settings */
471 while (!audio_is_thread_ready())
472 sleep(0);
474 audio_set_input_source(AUDIO_SRC_FMRADIO,
475 (radio_status == FMRADIO_PAUSED) ?
476 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
477 #else
478 if (radio_status == FMRADIO_OFF)
479 radio_start();
480 #endif
482 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
483 scan_presets(NULL);
485 set_current_preset(find_preset(curr_freq));
486 if(radio_current_preset() != -1)
487 radio_mode = RADIO_PRESET_MODE;
489 #ifndef HAVE_NOISY_IDLE_MODE
490 cpu_idle_mode(true);
491 #endif
493 while(!done)
495 if(search_dir != 0)
497 curr_freq = step_freq(curr_freq, search_dir);
498 update_screen = true;
500 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
502 set_current_preset(find_preset(curr_freq));
503 remember_frequency();
504 end_search();
505 talk = true;
507 trigger_cpu_boost();
510 if (!update_screen)
512 cancel_cpu_boost();
515 button = fms_do_button_loop(update_screen);
517 #ifndef HAVE_NOISY_IDLE_MODE
518 if (button != ACTION_NONE)
520 cpu_idle_mode(false);
521 button_timeout = current_tick + (2*HZ);
523 #endif
524 switch(button)
526 case ACTION_FM_STOP:
527 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
528 if(audio_status() == AUDIO_STATUS_RECORD)
530 audio_stop();
532 else
533 #endif
535 done = true;
536 if(has_presets_changed())
538 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
540 presets_save();
544 update_screen = true;
545 break;
547 #ifdef FM_RECORD
548 case ACTION_FM_RECORD:
549 #ifdef FM_RECORD_DBLPRE
550 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
552 rec_lastclick = 0;
553 break;
555 if (current_tick - rec_lastclick > HZ/2)
557 rec_lastclick = current_tick;
558 break;
560 #endif /* FM_RECORD_DBLPRE */
561 #ifndef SIMULATOR
562 if(audio_status() == AUDIO_STATUS_RECORD)
564 rec_command(RECORDING_CMD_START_NEWFILE);
565 update_screen = true;
567 else
569 have_recorded = true;
570 rec_command(RECORDING_CMD_START);
571 update_screen = true;
573 #endif /* SIMULATOR */
574 last_seconds = 0;
575 break;
576 #endif /* #ifdef FM_RECORD */
578 case ACTION_FM_EXIT:
579 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
580 if(audio_status() == AUDIO_STATUS_RECORD)
581 audio_stop();
582 #endif
583 keep_playing = true;
584 done = true;
585 ret_val = GO_TO_ROOT;
586 if(has_presets_changed())
588 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
590 presets_save();
594 break;
596 case ACTION_STD_PREV:
597 case ACTION_STD_NEXT:
598 next_station(button == ACTION_STD_PREV ? -1 : 1);
599 end_search();
600 update_screen = true;
601 talk = true;
602 break;
604 case ACTION_STD_PREVREPEAT:
605 case ACTION_STD_NEXTREPEAT:
607 int dir = search_dir;
608 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
609 if (radio_mode != RADIO_SCAN_MODE)
611 next_preset(search_dir);
612 end_search();
613 update_screen = true;
614 talk = true;
616 else if (dir == 0)
618 /* Starting auto scan */
619 tuner_set(RADIO_MUTE, 1);
620 update_screen = true;
622 break;
625 case ACTION_SETTINGS_INC:
626 case ACTION_SETTINGS_INCREPEAT:
627 global_settings.volume++;
628 setvol();
629 update_screen = true;
630 break;
632 case ACTION_SETTINGS_DEC:
633 case ACTION_SETTINGS_DECREPEAT:
634 global_settings.volume--;
635 setvol();
636 update_screen = true;
637 break;
639 case ACTION_FM_PLAY:
640 if (radio_status == FMRADIO_PLAYING)
641 radio_pause();
642 else
643 radio_start();
645 update_screen = true;
646 talk = false;
647 talk_shutup();
648 break;
650 case ACTION_FM_MENU:
651 fms_fix_displays(FMS_EXIT);
652 radio_menu();
653 set_current_preset(find_preset(curr_freq));
654 update_screen = true;
655 restore = true;
656 break;
658 #ifdef FM_PRESET
659 case ACTION_FM_PRESET:
660 if(radio_preset_count() < 1)
662 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
663 update_screen = true;
664 break;
666 fms_fix_displays(FMS_EXIT);
667 handle_radio_presets();
668 update_screen = true;
669 restore = true;
670 break;
671 #endif /* FM_PRESET */
673 #ifdef FM_FREEZE
674 case ACTION_FM_FREEZE:
675 if(!screen_freeze)
677 splash(HZ, str(LANG_FM_FREEZE));
678 screen_freeze = true;
680 else
682 update_screen = true;
683 screen_freeze = false;
685 break;
686 #endif /* FM_FREEZE */
688 case SYS_USB_CONNECTED:
689 #if CONFIG_CODEC != SWCODEC
690 /* Only accept USB connection when not recording */
691 if(audio_status() != AUDIO_STATUS_RECORD)
692 #endif
694 default_event_handler(SYS_USB_CONNECTED);
695 screen_freeze = true; /* Cosmetic: makes sure the
696 radio screen doesn't redraw */
697 done = true;
699 break;
701 #ifdef FM_MODE
702 case ACTION_FM_MODE:
703 if(radio_mode == RADIO_SCAN_MODE)
705 /* Force scan mode if there are no presets. */
706 if(radio_preset_count() > 0)
707 radio_mode = RADIO_PRESET_MODE;
709 else
710 radio_mode = RADIO_SCAN_MODE;
711 update_screen = true;
712 cond_talk_ids_fq(radio_mode ?
713 LANG_PRESET : LANG_RADIO_SCAN_MODE);
714 talk = true;
715 break;
716 #endif /* FM_MODE */
718 #ifdef FM_NEXT_PRESET
719 case ACTION_FM_NEXT_PRESET:
720 next_preset(1);
721 end_search();
722 update_screen = true;
723 talk = true;
724 break;
725 #endif
727 #ifdef FM_PREV_PRESET
728 case ACTION_FM_PREV_PRESET:
729 next_preset(-1);
730 end_search();
731 update_screen = true;
732 talk = true;
733 break;
734 #endif
736 default:
737 default_event_handler(button);
738 #ifdef HAVE_RDS_CAP
739 if (tuner_get(RADIO_EVENT))
740 update_screen = true;
741 #endif
742 if (!tuner_get(RADIO_PRESENT))
744 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
745 if(audio_status() == AUDIO_STATUS_RECORD)
746 audio_stop();
747 #endif
748 keep_playing = false;
749 done = true;
750 ret_val = GO_TO_ROOT;
751 if(has_presets_changed())
753 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
755 radio_save_presets();
759 /* Clear the preset list on exit. */
760 clear_preset_list();
762 break;
763 } /*switch(button)*/
765 #ifdef FM_RECORD_DBLPRE
766 if (button != ACTION_NONE)
767 lastbutton = button;
768 #endif
770 #if CONFIG_CODEC != SWCODEC
771 peak_meter_peek();
772 #endif
774 if(!screen_freeze)
776 /* Only display the peak meter when not recording */
777 #if CONFIG_CODEC != SWCODEC
778 if(TIME_AFTER(current_tick, timeout))
780 timeout = current_tick + HZ;
781 #else /* SWCODEC */
783 #endif /* CONFIG_CODEC == SWCODEC */
785 /* keep "mono" from always being displayed when paused */
786 if (radio_status != FMRADIO_PAUSED)
788 stereo = tuner_get(RADIO_STEREO) &&
789 !global_settings.fm_force_mono;
791 if(stereo != last_stereo)
793 update_screen = true;
794 last_stereo = stereo;
799 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
800 seconds = audio_recorded_time() / HZ;
801 if (update_screen || seconds > last_seconds || restore)
803 last_seconds = seconds;
804 #else
805 if (update_screen || restore)
807 #endif
808 if (restore)
809 fms_fix_displays(FMS_ENTER);
810 FOR_NB_SCREENS(i)
811 skin_update(fms_get(i), WPS_REFRESH_ALL);
812 restore = false;
815 update_screen = false;
817 if (global_settings.talk_file && talk
818 && radio_status == FMRADIO_PAUSED)
820 talk = false;
821 bool enqueue = false;
822 if (radio_mode == RADIO_SCAN_MODE)
824 talk_freq(curr_freq, enqueue);
825 enqueue = true;
827 if (radio_current_preset() >= 0)
828 talk_preset(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
829 enqueue);
832 #if CONFIG_CODEC != SWCODEC
833 if(audio_status() & AUDIO_STATUS_ERROR)
835 done = true;
837 #endif
839 #ifndef HAVE_NOISY_IDLE_MODE
840 if (TIME_AFTER(current_tick, button_timeout))
842 cpu_idle_mode(true);
844 #endif
845 } /*while(!done)*/
847 #ifndef SIMULATOR
848 #if CONFIG_CODEC != SWCODEC
849 if(audio_status() & AUDIO_STATUS_ERROR)
851 splash(0, str(LANG_DISK_FULL));
852 audio_error_clear();
854 while(1)
856 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
857 if(button == ACTION_FM_STOP)
858 break;
862 audio_init_playback();
863 #endif /* CONFIG_CODEC != SWCODEC */
865 sound_settings_apply();
866 #endif /* SIMULATOR */
868 if(keep_playing)
870 /* Catch FMRADIO_PLAYING status for the sim. */
871 #ifndef SIMULATOR
872 #if CONFIG_CODEC != SWCODEC
873 /* Enable the Left and right A/D Converter */
874 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
875 sound_default(SOUND_RIGHT_GAIN),
876 AUDIO_GAIN_LINEIN);
877 mas_codec_writereg(6, 0x4000);
878 #endif
879 end_search();
880 #endif /* SIMULATOR */
882 else
884 #if CONFIG_CODEC == SWCODEC
885 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
886 #else
887 radio_stop();
888 #endif
891 #ifndef HAVE_NOISY_IDLE_MODE
892 cpu_idle_mode(false);
893 #endif
894 fms_fix_displays(FMS_EXIT);
895 in_screen = false;
896 #if CONFIG_CODEC != SWCODEC
897 return have_recorded;
898 #else
899 return false;
900 #endif
901 } /* radio_screen */
903 void toggle_mono_mode(bool mono)
905 tuner_set(RADIO_FORCE_MONO, mono);
908 void set_radio_region(int region)
910 #ifdef HAVE_RADIO_REGION
911 tuner_set(RADIO_REGION, region);
912 #endif
913 next_station(0);
914 remember_frequency();
915 (void)region;
918 MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL);
919 MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL);
921 #ifndef FM_MODE
922 static char* get_mode_text(int selected_item, void * data, char *buffer)
924 (void)selected_item;
925 (void)data;
926 snprintf(buffer, MAX_PATH, "%s %s", str(LANG_MODE),
927 radio_mode ? str(LANG_PRESET) :
928 str(LANG_RADIO_SCAN_MODE));
929 return buffer;
931 static int toggle_radio_mode(void)
933 radio_mode = (radio_mode == RADIO_SCAN_MODE) ?
934 RADIO_PRESET_MODE : RADIO_SCAN_MODE;
935 return 0;
937 MENUITEM_FUNCTION_DYNTEXT(radio_mode_item, 0,
938 toggle_radio_mode, NULL,
939 get_mode_text, NULL, NULL, NULL, Icon_NOICON);
940 #endif
944 #ifdef HAVE_RECORDING
946 #if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
947 #define FM_RECORDING_SCREEN
948 static int fm_recording_screen(void)
950 bool ret;
952 /* switch recording source to FMRADIO for the duration */
953 int rec_source = global_settings.rec_source;
954 global_settings.rec_source = AUDIO_SRC_FMRADIO;
955 ret = recording_screen(true);
957 /* safe to reset as changing sources is prohibited here */
958 global_settings.rec_source = rec_source;
960 return ret;
963 #endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
965 #if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
966 #define FM_RECORDING_SETTINGS
967 static int fm_recording_settings(void)
969 bool ret = recording_menu(true);
971 #if CONFIG_CODEC != SWCODEC
972 if (!ret)
974 struct audio_recording_options rec_options;
975 rec_init_recording_options(&rec_options);
976 rec_options.rec_source = AUDIO_SRC_LINEIN;
977 rec_set_recording_options(&rec_options);
979 #endif
981 return ret;
984 #endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
985 #endif /* HAVE_RECORDING */
987 #ifdef FM_RECORDING_SCREEN
988 MENUITEM_FUNCTION(recscreen_item, 0, ID2P(LANG_RECORDING),
989 fm_recording_screen, NULL, NULL, Icon_Recording);
990 #endif
991 #ifdef FM_RECORDING_SETTINGS
992 MENUITEM_FUNCTION(recsettings_item, 0, ID2P(LANG_RECORDING_SETTINGS),
993 fm_recording_settings, NULL, NULL, Icon_Recording);
994 #endif
995 #ifndef FM_PRESET
996 int handle_radio_presets_menu(void)
998 return handle_radio_presets();
1000 MENUITEM_FUNCTION(radio_presets_item, 0, ID2P(LANG_PRESET),
1001 handle_radio_presets_menu, NULL, NULL, Icon_NOICON);
1002 #endif
1003 #ifndef FM_PRESET_ADD
1004 int handle_radio_addpreset_menu(void)
1006 return radio_add_preset();
1008 MENUITEM_FUNCTION(radio_addpreset_item, 0, ID2P(LANG_FM_ADD_PRESET),
1009 radio_add_preset, NULL, NULL, Icon_NOICON);
1010 #endif
1013 MENUITEM_FUNCTION(presetload_item, 0, ID2P(LANG_FM_PRESET_LOAD),
1014 load_preset_list, NULL, NULL, Icon_NOICON);
1015 MENUITEM_FUNCTION(presetsave_item, 0, ID2P(LANG_FM_PRESET_SAVE),
1016 save_preset_list, NULL, NULL, Icon_NOICON);
1017 MENUITEM_FUNCTION(presetclear_item, 0, ID2P(LANG_FM_PRESET_CLEAR),
1018 clear_preset_list, NULL, NULL, Icon_NOICON);
1019 MENUITEM_FUNCTION(scan_presets_item, MENU_FUNC_USEPARAM,
1020 ID2P(LANG_FM_SCAN_PRESETS),
1021 scan_presets, NULL, NULL, Icon_NOICON);
1023 MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
1024 Icon_Radio_screen,
1025 #ifndef FM_PRESET
1026 &radio_presets_item,
1027 #endif
1028 #ifndef FM_PRESET_ADD
1029 &radio_addpreset_item,
1030 #endif
1031 &presetload_item, &presetsave_item, &presetclear_item,
1032 &force_mono,
1033 #ifndef FM_MODE
1034 &radio_mode_item,
1035 #endif
1036 &set_region, &sound_settings,
1037 #ifdef FM_RECORDING_SCREEN
1038 &recscreen_item,
1039 #endif
1040 #ifdef FM_RECORDING_SETTINGS
1041 &recsettings_item,
1042 #endif
1043 &scan_presets_item);
1044 /* main menu of the radio screen */
1045 static bool radio_menu(void)
1047 return do_menu(&radio_settings_menu, NULL, NULL, false) ==
1048 MENU_ATTACHED_USB;
1051 #endif