SWCODEC: Wait for audio init to complete before starting radio or recording; hardware...
[maemo-rb.git] / apps / radio / radio.c
blob51c8982b074796f154e85f4e69ee22fd40cde6e3
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"
74 #if CONFIG_TUNER
76 #if CONFIG_KEYPAD == RECORDER_PAD
77 #define FM_RECORD
78 #define FM_PRESET_ADD
79 #define FM_PRESET_ACTION
80 #define FM_PRESET
81 #define FM_MODE
83 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
84 #define FM_PRESET
85 #define FM_MODE
86 #define FM_NEXT_PRESET
87 #define FM_PREV_PRESET
89 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
90 #define FM_PRESET
91 #define FM_MODE
93 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
94 #define FM_PRESET
95 #define FM_MODE
96 /* This should be removeable if the whole tuning thing is sorted out since
97 proper tuning quiets the screen almost entirely in that extreme measures
98 have to be taken to hear any interference. */
99 #define HAVE_NOISY_IDLE_MODE
101 #elif CONFIG_KEYPAD == ONDIO_PAD
102 #define FM_RECORD_DBLPRE
103 #define FM_RECORD
104 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD)
105 #define FM_MENU
106 #define FM_PRESET
107 #define FM_STOP
108 #define FM_MODE
109 #define FM_EXIT
110 #define FM_PLAY
112 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
113 #define FM_PRESET
114 #define FM_MODE
116 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
117 #define FM_MENU
118 #define FM_PRESET
119 #define FM_STOP
120 #define FM_MODE
121 #define FM_EXIT
122 #define FM_PLAY
124 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
125 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
126 #define FM_MENU
127 #define FM_STOP
128 #define FM_EXIT
129 #define FM_PLAY
130 #define FM_MODE
132 #endif
134 /* presets.c needs these so keep unstatic or redo the whole thing! */
135 int curr_freq; /* current frequency in Hz */
136 /* these are all in presets.c... someone PLEASE rework this ! */
137 int handle_radio_presets(void);
138 static bool radio_menu(void);
139 int radio_add_preset(void);
140 int save_preset_list(void);
141 int load_preset_list(void);
142 int clear_preset_list(void);
143 void next_preset(int direction);
144 void set_current_preset(int preset);
145 int scan_presets(void *viewports);
146 int find_preset(int freq);
147 void radio_save_presets(void);
148 bool has_presets_changed(void);
149 void talk_preset(int preset, bool fallback, bool enqueue);
150 void presets_save(void);
154 int radio_mode = RADIO_SCAN_MODE;
155 static int search_dir = 0;
157 static int radio_status = FMRADIO_OFF;
158 static bool in_screen = false;
161 static void radio_off(void);
163 bool radio_scan_mode(void)
165 return radio_mode == RADIO_SCAN_MODE;
168 bool radio_is_stereo(void)
170 return tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono;
172 int radio_current_frequency(void)
174 return curr_freq;
177 /* Function to manipulate all yesno dialogues.
178 This function needs the output text as an argument. */
179 bool yesno_pop(const char* text)
181 int i;
182 const char *lines[]={text};
183 const struct text_message message={lines, 1};
184 bool ret = (gui_syncyesno_run(&message,NULL,NULL)== YESNO_YES);
185 FOR_NB_SCREENS(i)
186 screens[i].clear_viewport();
187 return ret;
190 void radio_init(void)
192 tuner_init();
193 radio_off();
194 #ifdef HAVE_ALBUMART
195 radioart_init(false);
196 #endif
199 int get_radio_status(void)
201 return radio_status;
204 bool in_radio_screen(void)
206 return in_screen;
209 /* TODO: Move some more of the control functionality to firmware
210 and clean up the mess */
212 /* secret flag for starting paused - prevents unmute */
213 #define FMRADIO_START_PAUSED 0x8000
214 void radio_start(void)
216 const struct fm_region_data *fmr;
217 bool start_paused;
219 if(radio_status == FMRADIO_PLAYING)
220 return;
222 fmr = &fm_region_data[global_settings.fm_region];
224 start_paused = radio_status & FMRADIO_START_PAUSED;
225 /* clear flag before any yielding */
226 radio_status &= ~FMRADIO_START_PAUSED;
228 if(radio_status == FMRADIO_OFF)
229 tuner_power(true);
231 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
233 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
235 if(radio_status == FMRADIO_OFF)
237 #ifdef HAVE_RADIO_REGION
238 tuner_set(RADIO_REGION, global_settings.fm_region);
239 #endif
240 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
243 tuner_set(RADIO_FREQUENCY, curr_freq);
245 #ifdef HAVE_RADIO_MUTE_TIMEOUT
247 unsigned long mute_timeout = current_tick + HZ;
248 if (radio_status != FMRADIO_OFF)
250 /* paused */
251 mute_timeout += HZ;
254 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
256 if(TIME_AFTER(current_tick, mute_timeout))
257 break;
258 yield();
261 #endif
263 /* keep radio from sounding initially */
264 if(!start_paused)
265 tuner_set(RADIO_MUTE, 0);
267 radio_status = FMRADIO_PLAYING;
268 } /* radio_start */
270 void radio_pause(void)
272 if(radio_status == FMRADIO_PAUSED)
273 return;
275 if(radio_status == FMRADIO_OFF)
277 radio_status |= FMRADIO_START_PAUSED;
278 radio_start();
281 tuner_set(RADIO_MUTE, 1);
282 /* For si4700: 2==this is really 'pause'. other tuners treat it
283 * like 'bool'. */
284 tuner_set(RADIO_SLEEP, 2);
286 radio_status = FMRADIO_PAUSED;
287 } /* radio_pause */
289 static void radio_off(void)
291 tuner_set(RADIO_MUTE, 1);
292 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
293 radio_status = FMRADIO_OFF;
294 tuner_power(false); /* status update, power off if avail. */
297 void radio_stop(void)
299 if(radio_status == FMRADIO_OFF)
300 return;
302 radio_off();
303 } /* radio_stop */
305 bool radio_hardware_present(void)
307 return tuner_get(RADIO_PRESENT);
310 /* Keep freq on the grid for the current region */
311 int snap_freq_to_grid(int freq)
313 const struct fm_region_data * const fmr =
314 &fm_region_data[global_settings.fm_region];
316 /* Range clamp if out of range or just round to nearest */
317 if (freq < fmr->freq_min)
318 freq = fmr->freq_min;
319 else if (freq > fmr->freq_max)
320 freq = fmr->freq_max;
321 else
322 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
323 fmr->freq_step * fmr->freq_step + fmr->freq_min;
325 return freq;
328 void remember_frequency(void)
330 const struct fm_region_data * const fmr =
331 &fm_region_data[global_settings.fm_region];
332 global_status.last_frequency = (curr_freq - fmr->freq_min)
333 / fmr->freq_step;
334 status_save();
337 /* Step to the next or previous frequency */
338 static int step_freq(int freq, int direction)
340 const struct fm_region_data * const fmr =
341 &fm_region_data[global_settings.fm_region];
343 freq += direction*fmr->freq_step;
345 /* Wrap first or snapping to grid will not let us on the band extremes */
346 if (freq > fmr->freq_max)
347 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
348 else if (freq < fmr->freq_min)
349 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
350 else
351 freq = snap_freq_to_grid(freq);
353 return freq;
356 /* Step to the next or previous station */
357 void next_station(int direction)
359 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
361 next_preset(direction);
362 return;
365 curr_freq = step_freq(curr_freq, direction);
367 if (radio_status == FMRADIO_PLAYING)
368 tuner_set(RADIO_MUTE, 1);
370 tuner_set(RADIO_FREQUENCY, curr_freq);
372 if (radio_status == FMRADIO_PLAYING)
373 tuner_set(RADIO_MUTE, 0);
375 set_current_preset(find_preset(curr_freq));
376 remember_frequency();
379 /* Ends an in-progress search */
380 static void end_search(void)
382 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
383 tuner_set(RADIO_MUTE, 0);
384 search_dir = 0;
387 /* Speak a frequency. */
388 void talk_freq(int freq, bool enqueue)
390 freq /= 10000;
391 talk_number(freq / 100, enqueue);
392 talk_id(LANG_POINT, true);
393 talk_number(freq % 100 / 10, true);
394 if (freq % 10)
395 talk_number(freq % 10, true);
399 int radio_screen(void)
401 bool done = false;
402 int ret_val = GO_TO_ROOT;
403 int button;
404 int i;
405 bool stereo = false, last_stereo = false;
406 bool update_screen = true, restore = true;
407 bool screen_freeze = false;
408 bool keep_playing = false;
409 bool talk = false;
410 #ifdef FM_RECORD_DBLPRE
411 int lastbutton = BUTTON_NONE;
412 unsigned long rec_lastclick = 0;
413 #endif
414 #if CONFIG_CODEC != SWCODEC
415 bool have_recorded = false;
416 int timeout = current_tick + HZ/10;
417 unsigned int last_seconds = 0;
418 #ifndef SIMULATOR
419 unsigned int seconds = 0;
420 struct audio_recording_options rec_options;
421 #endif
422 #endif /* CONFIG_CODEC != SWCODEC */
423 #ifndef HAVE_NOISY_IDLE_MODE
424 int button_timeout = current_tick + (2*HZ);
425 #endif
427 /* change status to "in screen" */
428 in_screen = true;
430 if(radio_preset_count() <= 0)
432 radio_load_presets(global_settings.fmr_file);
434 #ifdef HAVE_ALBUMART
435 radioart_init(true);
436 #endif
438 if(radio_status == FMRADIO_OFF)
439 audio_stop();
441 #ifndef SIMULATOR
443 #if CONFIG_CODEC != SWCODEC
444 if(rec_create_directory() > 0)
445 have_recorded = true;
447 audio_init_recording(talk_get_bufsize());
449 sound_settings_apply();
450 /* Yes, we use the D/A for monitoring */
451 peak_meter_playback(true);
453 peak_meter_enable(true);
455 rec_init_recording_options(&rec_options);
456 rec_options.rec_source = AUDIO_SRC_LINEIN;
457 rec_set_recording_options(&rec_options);
459 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
460 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
462 #endif /* CONFIG_CODEC != SWCODEC */
463 #endif /* ndef SIMULATOR */
465 /* turn on radio */
466 #if CONFIG_CODEC == SWCODEC
467 /* This should be done before touching audio settings */
468 while (!audio_is_thread_ready())
469 sleep(0);
471 audio_set_input_source(AUDIO_SRC_FMRADIO,
472 (radio_status == FMRADIO_PAUSED) ?
473 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
474 #else
475 if (radio_status == FMRADIO_OFF)
476 radio_start();
477 #endif
479 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
480 scan_presets(NULL);
482 set_current_preset(find_preset(curr_freq));
483 if(radio_current_preset() != -1)
484 radio_mode = RADIO_PRESET_MODE;
486 #ifndef HAVE_NOISY_IDLE_MODE
487 cpu_idle_mode(true);
488 #endif
490 while(!done)
492 if(search_dir != 0)
494 curr_freq = step_freq(curr_freq, search_dir);
495 update_screen = true;
497 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
499 set_current_preset(find_preset(curr_freq));
500 remember_frequency();
501 end_search();
502 talk = true;
504 trigger_cpu_boost();
507 if (!update_screen)
509 cancel_cpu_boost();
512 button = fms_do_button_loop(update_screen);
514 #ifndef HAVE_NOISY_IDLE_MODE
515 if (button != ACTION_NONE)
517 cpu_idle_mode(false);
518 button_timeout = current_tick + (2*HZ);
520 #endif
521 switch(button)
523 case ACTION_FM_STOP:
524 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
525 if(audio_status() == AUDIO_STATUS_RECORD)
527 audio_stop();
529 else
530 #endif
532 done = true;
533 if(has_presets_changed())
535 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
537 presets_save();
541 update_screen = true;
542 break;
544 #ifdef FM_RECORD
545 case ACTION_FM_RECORD:
546 #ifdef FM_RECORD_DBLPRE
547 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
549 rec_lastclick = 0;
550 break;
552 if (current_tick - rec_lastclick > HZ/2)
554 rec_lastclick = current_tick;
555 break;
557 #endif /* FM_RECORD_DBLPRE */
558 #ifndef SIMULATOR
559 if(audio_status() == AUDIO_STATUS_RECORD)
561 rec_command(RECORDING_CMD_START_NEWFILE);
562 update_screen = true;
564 else
566 have_recorded = true;
567 rec_command(RECORDING_CMD_START);
568 update_screen = true;
570 #endif /* SIMULATOR */
571 last_seconds = 0;
572 break;
573 #endif /* #ifdef FM_RECORD */
575 case ACTION_FM_EXIT:
576 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
577 if(audio_status() == AUDIO_STATUS_RECORD)
578 audio_stop();
579 #endif
580 keep_playing = true;
581 done = true;
582 ret_val = GO_TO_ROOT;
583 if(has_presets_changed())
585 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
587 presets_save();
591 break;
593 case ACTION_STD_PREV:
594 case ACTION_STD_NEXT:
595 next_station(button == ACTION_STD_PREV ? -1 : 1);
596 end_search();
597 update_screen = true;
598 talk = true;
599 break;
601 case ACTION_STD_PREVREPEAT:
602 case ACTION_STD_NEXTREPEAT:
604 int dir = search_dir;
605 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
606 if (radio_mode != RADIO_SCAN_MODE)
608 next_preset(search_dir);
609 end_search();
610 update_screen = true;
611 talk = true;
613 else if (dir == 0)
615 /* Starting auto scan */
616 tuner_set(RADIO_MUTE, 1);
617 update_screen = true;
619 break;
622 case ACTION_SETTINGS_INC:
623 case ACTION_SETTINGS_INCREPEAT:
624 global_settings.volume++;
625 setvol();
626 update_screen = true;
627 break;
629 case ACTION_SETTINGS_DEC:
630 case ACTION_SETTINGS_DECREPEAT:
631 global_settings.volume--;
632 setvol();
633 update_screen = true;
634 break;
636 case ACTION_FM_PLAY:
637 if (radio_status == FMRADIO_PLAYING)
638 radio_pause();
639 else
640 radio_start();
642 update_screen = true;
643 talk = false;
644 talk_shutup();
645 break;
647 case ACTION_FM_MENU:
648 fms_fix_displays(FMS_EXIT);
649 radio_menu();
650 set_current_preset(find_preset(curr_freq));
651 update_screen = true;
652 restore = true;
653 break;
655 #ifdef FM_PRESET
656 case ACTION_FM_PRESET:
657 if(radio_preset_count() < 1)
659 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
660 update_screen = true;
661 break;
663 fms_fix_displays(FMS_EXIT);
664 handle_radio_presets();
665 update_screen = true;
666 restore = true;
667 break;
668 #endif /* FM_PRESET */
670 #ifdef FM_FREEZE
671 case ACTION_FM_FREEZE:
672 if(!screen_freeze)
674 splash(HZ, str(LANG_FM_FREEZE));
675 screen_freeze = true;
677 else
679 update_screen = true;
680 screen_freeze = false;
682 break;
683 #endif /* FM_FREEZE */
685 case SYS_USB_CONNECTED:
686 #if CONFIG_CODEC != SWCODEC
687 /* Only accept USB connection when not recording */
688 if(audio_status() != AUDIO_STATUS_RECORD)
689 #endif
691 default_event_handler(SYS_USB_CONNECTED);
692 screen_freeze = true; /* Cosmetic: makes sure the
693 radio screen doesn't redraw */
694 done = true;
696 break;
698 #ifdef FM_MODE
699 case ACTION_FM_MODE:
700 if(radio_mode == RADIO_SCAN_MODE)
702 /* Force scan mode if there are no presets. */
703 if(radio_preset_count() > 0)
704 radio_mode = RADIO_PRESET_MODE;
706 else
707 radio_mode = RADIO_SCAN_MODE;
708 update_screen = true;
709 cond_talk_ids_fq(radio_mode ?
710 LANG_PRESET : LANG_RADIO_SCAN_MODE);
711 talk = true;
712 break;
713 #endif /* FM_MODE */
715 #ifdef FM_NEXT_PRESET
716 case ACTION_FM_NEXT_PRESET:
717 next_preset(1);
718 end_search();
719 update_screen = true;
720 talk = true;
721 break;
722 #endif
724 #ifdef FM_PREV_PRESET
725 case ACTION_FM_PREV_PRESET:
726 next_preset(-1);
727 end_search();
728 update_screen = true;
729 talk = true;
730 break;
731 #endif
733 default:
734 default_event_handler(button);
735 #ifdef HAVE_RDS_CAP
736 if (tuner_get(RADIO_EVENT))
737 update_screen = true;
738 #endif
739 if (!tuner_get(RADIO_PRESENT))
741 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
742 if(audio_status() == AUDIO_STATUS_RECORD)
743 audio_stop();
744 #endif
745 keep_playing = false;
746 done = true;
747 ret_val = GO_TO_ROOT;
748 if(has_presets_changed())
750 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
752 radio_save_presets();
756 /* Clear the preset list on exit. */
757 clear_preset_list();
759 break;
760 } /*switch(button)*/
762 #ifdef FM_RECORD_DBLPRE
763 if (button != ACTION_NONE)
764 lastbutton = button;
765 #endif
767 #if CONFIG_CODEC != SWCODEC
768 peak_meter_peek();
769 #endif
771 if(!screen_freeze)
773 /* Only display the peak meter when not recording */
774 #if CONFIG_CODEC != SWCODEC
775 if(TIME_AFTER(current_tick, timeout))
777 timeout = current_tick + HZ;
778 #else /* SWCODEC */
780 #endif /* CONFIG_CODEC == SWCODEC */
782 /* keep "mono" from always being displayed when paused */
783 if (radio_status != FMRADIO_PAUSED)
785 stereo = tuner_get(RADIO_STEREO) &&
786 !global_settings.fm_force_mono;
788 if(stereo != last_stereo)
790 update_screen = true;
791 last_stereo = stereo;
796 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
797 seconds = audio_recorded_time() / HZ;
798 if (update_screen || seconds > last_seconds || restore)
800 last_seconds = seconds;
801 #else
802 if (update_screen || restore)
804 #endif
805 if (restore)
806 fms_fix_displays(FMS_ENTER);
807 FOR_NB_SCREENS(i)
808 skin_update(fms_get(i), WPS_REFRESH_ALL);
809 restore = false;
812 update_screen = false;
814 if (global_settings.talk_file && talk
815 && radio_status == FMRADIO_PAUSED)
817 talk = false;
818 bool enqueue = false;
819 if (radio_mode == RADIO_SCAN_MODE)
821 talk_freq(curr_freq, enqueue);
822 enqueue = true;
824 if (radio_current_preset() >= 0)
825 talk_preset(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
826 enqueue);
829 #if CONFIG_CODEC != SWCODEC
830 if(audio_status() & AUDIO_STATUS_ERROR)
832 done = true;
834 #endif
836 #ifndef HAVE_NOISY_IDLE_MODE
837 if (TIME_AFTER(current_tick, button_timeout))
839 cpu_idle_mode(true);
841 #endif
842 } /*while(!done)*/
844 #ifndef SIMULATOR
845 #if CONFIG_CODEC != SWCODEC
846 if(audio_status() & AUDIO_STATUS_ERROR)
848 splash(0, str(LANG_DISK_FULL));
849 audio_error_clear();
851 while(1)
853 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
854 if(button == ACTION_FM_STOP)
855 break;
859 audio_init_playback();
860 #endif /* CONFIG_CODEC != SWCODEC */
862 sound_settings_apply();
863 #endif /* SIMULATOR */
865 if(keep_playing)
867 /* Catch FMRADIO_PLAYING status for the sim. */
868 #ifndef SIMULATOR
869 #if CONFIG_CODEC != SWCODEC
870 /* Enable the Left and right A/D Converter */
871 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
872 sound_default(SOUND_RIGHT_GAIN),
873 AUDIO_GAIN_LINEIN);
874 mas_codec_writereg(6, 0x4000);
875 #endif
876 end_search();
877 #endif /* SIMULATOR */
879 else
881 #if CONFIG_CODEC == SWCODEC
882 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
883 #else
884 radio_stop();
885 #endif
888 #ifndef HAVE_NOISY_IDLE_MODE
889 cpu_idle_mode(false);
890 #endif
891 fms_fix_displays(FMS_EXIT);
892 in_screen = false;
893 #if CONFIG_CODEC != SWCODEC
894 return have_recorded;
895 #else
896 return false;
897 #endif
898 } /* radio_screen */
900 void toggle_mono_mode(bool mono)
902 tuner_set(RADIO_FORCE_MONO, mono);
905 void set_radio_region(int region)
907 #ifdef HAVE_RADIO_REGION
908 tuner_set(RADIO_REGION, region);
909 #endif
910 next_station(0);
911 remember_frequency();
912 (void)region;
915 MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL);
916 MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL);
918 #ifndef FM_MODE
919 static char* get_mode_text(int selected_item, void * data, char *buffer)
921 (void)selected_item;
922 (void)data;
923 snprintf(buffer, MAX_PATH, "%s %s", str(LANG_MODE),
924 radio_mode ? str(LANG_PRESET) :
925 str(LANG_RADIO_SCAN_MODE));
926 return buffer;
928 static int toggle_radio_mode(void)
930 radio_mode = (radio_mode == RADIO_SCAN_MODE) ?
931 RADIO_PRESET_MODE : RADIO_SCAN_MODE;
932 return 0;
934 MENUITEM_FUNCTION_DYNTEXT(radio_mode_item, 0,
935 toggle_radio_mode, NULL,
936 get_mode_text, NULL, NULL, NULL, Icon_NOICON);
937 #endif
941 #ifdef HAVE_RECORDING
943 #if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
944 #define FM_RECORDING_SCREEN
945 static int fm_recording_screen(void)
947 bool ret;
949 /* switch recording source to FMRADIO for the duration */
950 int rec_source = global_settings.rec_source;
951 global_settings.rec_source = AUDIO_SRC_FMRADIO;
952 ret = recording_screen(true);
954 /* safe to reset as changing sources is prohibited here */
955 global_settings.rec_source = rec_source;
957 return ret;
960 #endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
962 #if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
963 #define FM_RECORDING_SETTINGS
964 static int fm_recording_settings(void)
966 bool ret = recording_menu(true);
968 #if CONFIG_CODEC != SWCODEC
969 if (!ret)
971 struct audio_recording_options rec_options;
972 rec_init_recording_options(&rec_options);
973 rec_options.rec_source = AUDIO_SRC_LINEIN;
974 rec_set_recording_options(&rec_options);
976 #endif
978 return ret;
981 #endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
982 #endif /* HAVE_RECORDING */
984 #ifdef FM_RECORDING_SCREEN
985 MENUITEM_FUNCTION(recscreen_item, 0, ID2P(LANG_RECORDING),
986 fm_recording_screen, NULL, NULL, Icon_Recording);
987 #endif
988 #ifdef FM_RECORDING_SETTINGS
989 MENUITEM_FUNCTION(recsettings_item, 0, ID2P(LANG_RECORDING_SETTINGS),
990 fm_recording_settings, NULL, NULL, Icon_Recording);
991 #endif
992 #ifndef FM_PRESET
993 int handle_radio_presets_menu(void)
995 return handle_radio_presets();
997 MENUITEM_FUNCTION(radio_presets_item, 0, ID2P(LANG_PRESET),
998 handle_radio_presets_menu, NULL, NULL, Icon_NOICON);
999 #endif
1000 #ifndef FM_PRESET_ADD
1001 int handle_radio_addpreset_menu(void)
1003 return radio_add_preset();
1005 MENUITEM_FUNCTION(radio_addpreset_item, 0, ID2P(LANG_FM_ADD_PRESET),
1006 radio_add_preset, NULL, NULL, Icon_NOICON);
1007 #endif
1010 MENUITEM_FUNCTION(presetload_item, 0, ID2P(LANG_FM_PRESET_LOAD),
1011 load_preset_list, NULL, NULL, Icon_NOICON);
1012 MENUITEM_FUNCTION(presetsave_item, 0, ID2P(LANG_FM_PRESET_SAVE),
1013 save_preset_list, NULL, NULL, Icon_NOICON);
1014 MENUITEM_FUNCTION(presetclear_item, 0, ID2P(LANG_FM_PRESET_CLEAR),
1015 clear_preset_list, NULL, NULL, Icon_NOICON);
1016 MENUITEM_FUNCTION(scan_presets_item, MENU_FUNC_USEPARAM,
1017 ID2P(LANG_FM_SCAN_PRESETS),
1018 scan_presets, NULL, NULL, Icon_NOICON);
1020 MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
1021 Icon_Radio_screen,
1022 #ifndef FM_PRESET
1023 &radio_presets_item,
1024 #endif
1025 #ifndef FM_PRESET_ADD
1026 &radio_addpreset_item,
1027 #endif
1028 &presetload_item, &presetsave_item, &presetclear_item,
1029 &force_mono,
1030 #ifndef FM_MODE
1031 &radio_mode_item,
1032 #endif
1033 &set_region, &sound_settings,
1034 #ifdef FM_RECORDING_SCREEN
1035 &recscreen_item,
1036 #endif
1037 #ifdef FM_RECORDING_SETTINGS
1038 &recsettings_item,
1039 #endif
1040 &scan_presets_item);
1041 /* main menu of the radio screen */
1042 static bool radio_menu(void)
1044 return do_menu(&radio_settings_menu, NULL, NULL, false) ==
1045 MENU_ATTACHED_USB;
1048 #endif