Fix up configure and buildzip/wpsbuild.pl a bit
[kugel-rb.git] / apps / radio / radio.c
blob17f3d89bfc0fe19b07ff6046e3b748bc1de7a084
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
76 #include "presets.h"
78 #if CONFIG_TUNER
80 #if CONFIG_KEYPAD == RECORDER_PAD
81 #define FM_RECORD
82 #define FM_PRESET_ADD
83 #define FM_PRESET_ACTION
84 #define FM_PRESET
85 #define FM_MODE
87 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
88 #define FM_PRESET
89 #define FM_MODE
90 #define FM_NEXT_PRESET
91 #define FM_PREV_PRESET
93 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
94 #define FM_PRESET
95 #define FM_MODE
97 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
98 #define FM_PRESET
99 #define FM_MODE
100 /* This should be removeable if the whole tuning thing is sorted out since
101 proper tuning quiets the screen almost entirely in that extreme measures
102 have to be taken to hear any interference. */
103 #define HAVE_NOISY_IDLE_MODE
105 #elif CONFIG_KEYPAD == ONDIO_PAD
106 #define FM_RECORD_DBLPRE
107 #define FM_RECORD
109 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD) ||\
110 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD)
111 #define FM_MENU
112 #define FM_PRESET
113 #define FM_STOP
114 #define FM_MODE
115 #define FM_EXIT
116 #define FM_PLAY
118 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
119 #define FM_PRESET
120 #define FM_MODE
122 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
123 #define FM_MENU
124 #define FM_PRESET
125 #define FM_STOP
126 #define FM_MODE
127 #define FM_EXIT
128 #define FM_PLAY
130 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
131 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
132 #define FM_MENU
133 #define FM_STOP
134 #define FM_EXIT
135 #define FM_PLAY
136 #define FM_MODE
138 #endif
140 /* presets.c needs these so keep unstatic or redo the whole thing! */
141 int curr_freq; /* current frequency in Hz */
143 static bool radio_menu(void);
145 int radio_mode = RADIO_SCAN_MODE;
146 static int search_dir = 0;
148 static int radio_status = FMRADIO_OFF;
149 static bool in_screen = false;
152 static void radio_off(void);
154 bool radio_scan_mode(void)
156 return radio_mode == RADIO_SCAN_MODE;
159 bool radio_is_stereo(void)
161 return tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono;
163 int radio_current_frequency(void)
165 return curr_freq;
168 /* Function to manipulate all yesno dialogues.
169 This function needs the output text as an argument. */
170 bool yesno_pop(const char* text)
172 int i;
173 const char *lines[]={text};
174 const struct text_message message={lines, 1};
175 bool ret = (gui_syncyesno_run(&message,NULL,NULL)== YESNO_YES);
176 FOR_NB_SCREENS(i)
177 screens[i].clear_viewport();
178 return ret;
181 void radio_init(void)
183 tuner_init();
184 radio_off();
185 #ifdef HAVE_ALBUMART
186 radioart_init(false);
187 #endif
190 int get_radio_status(void)
192 return radio_status;
195 bool in_radio_screen(void)
197 return in_screen;
200 /* TODO: Move some more of the control functionality to firmware
201 and clean up the mess */
203 /* secret flag for starting paused - prevents unmute */
204 #define FMRADIO_START_PAUSED 0x8000
205 void radio_start(void)
207 const struct fm_region_data *fmr;
208 bool start_paused;
210 if(radio_status == FMRADIO_PLAYING)
211 return;
213 fmr = &fm_region_data[global_settings.fm_region];
215 start_paused = radio_status & FMRADIO_START_PAUSED;
216 /* clear flag before any yielding */
217 radio_status &= ~FMRADIO_START_PAUSED;
219 if(radio_status == FMRADIO_OFF)
220 tuner_power(true);
222 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
224 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
226 if(radio_status == FMRADIO_OFF)
228 #ifdef HAVE_RADIO_REGION
229 tuner_set(RADIO_REGION, global_settings.fm_region);
230 #endif
231 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
234 tuner_set(RADIO_FREQUENCY, curr_freq);
236 #ifdef HAVE_RADIO_MUTE_TIMEOUT
238 unsigned long mute_timeout = current_tick + HZ;
239 if (radio_status != FMRADIO_OFF)
241 /* paused */
242 mute_timeout += HZ;
245 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
247 if(TIME_AFTER(current_tick, mute_timeout))
248 break;
249 yield();
252 #endif
254 /* keep radio from sounding initially */
255 if(!start_paused)
256 tuner_set(RADIO_MUTE, 0);
258 radio_status = FMRADIO_PLAYING;
259 } /* radio_start */
261 void radio_pause(void)
263 if(radio_status == FMRADIO_PAUSED)
264 return;
266 if(radio_status == FMRADIO_OFF)
268 radio_status |= FMRADIO_START_PAUSED;
269 radio_start();
272 tuner_set(RADIO_MUTE, 1);
273 /* For si4700: 2==this is really 'pause'. other tuners treat it
274 * like 'bool'. */
275 tuner_set(RADIO_SLEEP, 2);
277 radio_status = FMRADIO_PAUSED;
278 } /* radio_pause */
280 static void radio_off(void)
282 tuner_set(RADIO_MUTE, 1);
283 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
284 radio_status = FMRADIO_OFF;
285 tuner_power(false); /* status update, power off if avail. */
288 void radio_stop(void)
290 if(radio_status == FMRADIO_OFF)
291 return;
293 radio_off();
294 } /* radio_stop */
296 bool radio_hardware_present(void)
298 return tuner_get(RADIO_PRESENT);
301 /* Keep freq on the grid for the current region */
302 int snap_freq_to_grid(int freq)
304 const struct fm_region_data * const fmr =
305 &fm_region_data[global_settings.fm_region];
307 /* Range clamp if out of range or just round to nearest */
308 if (freq < fmr->freq_min)
309 freq = fmr->freq_min;
310 else if (freq > fmr->freq_max)
311 freq = fmr->freq_max;
312 else
313 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
314 fmr->freq_step * fmr->freq_step + fmr->freq_min;
316 return freq;
319 void remember_frequency(void)
321 const struct fm_region_data * const fmr =
322 &fm_region_data[global_settings.fm_region];
323 global_status.last_frequency = (curr_freq - fmr->freq_min)
324 / fmr->freq_step;
325 status_save();
328 /* Step to the next or previous frequency */
329 static int step_freq(int freq, int direction)
331 const struct fm_region_data * const fmr =
332 &fm_region_data[global_settings.fm_region];
334 freq += direction*fmr->freq_step;
336 /* Wrap first or snapping to grid will not let us on the band extremes */
337 if (freq > fmr->freq_max)
338 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
339 else if (freq < fmr->freq_min)
340 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
341 else
342 freq = snap_freq_to_grid(freq);
344 return freq;
347 /* Step to the next or previous station */
348 void next_station(int direction)
350 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
352 preset_next(direction);
353 return;
356 curr_freq = step_freq(curr_freq, direction);
358 if (radio_status == FMRADIO_PLAYING)
359 tuner_set(RADIO_MUTE, 1);
361 tuner_set(RADIO_FREQUENCY, curr_freq);
363 if (radio_status == FMRADIO_PLAYING)
364 tuner_set(RADIO_MUTE, 0);
366 preset_set_current(preset_find(curr_freq));
367 remember_frequency();
370 /* Ends an in-progress search */
371 static void end_search(void)
373 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
374 tuner_set(RADIO_MUTE, 0);
375 search_dir = 0;
378 /* Speak a frequency. */
379 void talk_freq(int freq, bool enqueue)
381 freq /= 10000;
382 talk_number(freq / 100, enqueue);
383 talk_id(LANG_POINT, true);
384 talk_number(freq % 100 / 10, true);
385 if (freq % 10)
386 talk_number(freq % 10, true);
390 int radio_screen(void)
392 bool done = false;
393 int ret_val = GO_TO_ROOT;
394 int button;
395 int i;
396 bool stereo = false, last_stereo = false;
397 bool update_screen = true, restore = true;
398 bool screen_freeze = false;
399 bool keep_playing = false;
400 bool talk = false;
401 #ifdef FM_RECORD_DBLPRE
402 int lastbutton = BUTTON_NONE;
403 unsigned long rec_lastclick = 0;
404 #endif
405 #if CONFIG_CODEC != SWCODEC
406 bool have_recorded = false;
407 int timeout = current_tick + HZ/10;
408 unsigned int last_seconds = 0;
409 #if !defined(SIMULATOR)
410 unsigned int seconds = 0;
411 struct audio_recording_options rec_options;
412 #endif /* SIMULATOR */
413 #endif /* CONFIG_CODEC != SWCODEC */
414 #ifndef HAVE_NOISY_IDLE_MODE
415 int button_timeout = current_tick + (2*HZ);
416 #endif
418 /* change status to "in screen" */
419 in_screen = true;
421 if(radio_preset_count() <= 0)
423 radio_load_presets(global_settings.fmr_file);
425 fms_get(SCREEN_MAIN)->state->id3 = NULL;
426 #ifdef HAVE_ALBUMART
427 radioart_init(true);
428 #endif
430 if(radio_status == FMRADIO_OFF)
431 audio_stop();
433 #ifndef SIMULATOR
435 #if CONFIG_CODEC != SWCODEC
436 if(rec_create_directory() > 0)
437 have_recorded = true;
439 audio_init_recording(talk_get_bufsize());
441 sound_settings_apply();
442 /* Yes, we use the D/A for monitoring */
443 peak_meter_playback(true);
445 peak_meter_enable(true);
447 rec_init_recording_options(&rec_options);
448 rec_options.rec_source = AUDIO_SRC_LINEIN;
449 rec_set_recording_options(&rec_options);
451 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
452 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
454 #endif /* CONFIG_CODEC != SWCODEC */
455 #endif /* ndef SIMULATOR */
457 /* turn on radio */
458 #if CONFIG_CODEC == SWCODEC
459 /* This should be done before touching audio settings */
460 while (!audio_is_thread_ready())
461 sleep(0);
463 audio_set_input_source(AUDIO_SRC_FMRADIO,
464 (radio_status == FMRADIO_PAUSED) ?
465 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
466 #else
467 if (radio_status == FMRADIO_OFF)
468 radio_start();
469 #endif
471 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
472 presets_scan(NULL);
474 preset_set_current(preset_find(curr_freq));
475 if(radio_current_preset() != -1)
476 radio_mode = RADIO_PRESET_MODE;
478 #ifndef HAVE_NOISY_IDLE_MODE
479 cpu_idle_mode(true);
480 #endif
482 while(!done)
484 if(search_dir != 0)
486 curr_freq = step_freq(curr_freq, search_dir);
487 update_screen = true;
489 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
491 preset_set_current(preset_find(curr_freq));
492 remember_frequency();
493 end_search();
494 talk = true;
496 trigger_cpu_boost();
499 if (!update_screen)
501 cancel_cpu_boost();
504 button = fms_do_button_loop(update_screen);
506 #ifndef HAVE_NOISY_IDLE_MODE
507 if (button != ACTION_NONE)
509 cpu_idle_mode(false);
510 button_timeout = current_tick + (2*HZ);
512 #endif
513 switch(button)
515 case ACTION_FM_STOP:
516 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
517 if(audio_status() == AUDIO_STATUS_RECORD)
519 audio_stop();
521 else
522 #endif
524 done = true;
525 if(presets_have_changed())
527 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
529 presets_save();
533 update_screen = true;
534 break;
536 #ifdef FM_RECORD
537 case ACTION_FM_RECORD:
538 #ifdef FM_RECORD_DBLPRE
539 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
541 rec_lastclick = 0;
542 break;
544 if (current_tick - rec_lastclick > HZ/2)
546 rec_lastclick = current_tick;
547 break;
549 #endif /* FM_RECORD_DBLPRE */
550 #ifndef SIMULATOR
551 if(audio_status() == AUDIO_STATUS_RECORD)
553 rec_command(RECORDING_CMD_START_NEWFILE);
554 update_screen = true;
556 else
558 have_recorded = true;
559 rec_command(RECORDING_CMD_START);
560 update_screen = true;
562 #endif /* SIMULATOR */
563 last_seconds = 0;
564 break;
565 #endif /* #ifdef FM_RECORD */
567 case ACTION_FM_EXIT:
568 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
569 if(audio_status() == AUDIO_STATUS_RECORD)
570 audio_stop();
571 #endif
572 keep_playing = true;
573 done = true;
574 ret_val = GO_TO_ROOT;
575 if(presets_have_changed())
577 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
579 presets_save();
583 break;
585 case ACTION_STD_PREV:
586 case ACTION_STD_NEXT:
587 next_station(button == ACTION_STD_PREV ? -1 : 1);
588 end_search();
589 update_screen = true;
590 talk = true;
591 break;
593 case ACTION_STD_PREVREPEAT:
594 case ACTION_STD_NEXTREPEAT:
596 int dir = search_dir;
597 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
598 if (radio_mode != RADIO_SCAN_MODE)
600 preset_next(search_dir);
601 end_search();
602 update_screen = true;
603 talk = true;
605 else if (dir == 0)
607 /* Starting auto scan */
608 tuner_set(RADIO_MUTE, 1);
609 update_screen = true;
611 break;
614 case ACTION_SETTINGS_INC:
615 case ACTION_SETTINGS_INCREPEAT:
616 global_settings.volume++;
617 setvol();
618 update_screen = true;
619 break;
621 case ACTION_SETTINGS_DEC:
622 case ACTION_SETTINGS_DECREPEAT:
623 global_settings.volume--;
624 setvol();
625 update_screen = true;
626 break;
628 case ACTION_FM_PLAY:
629 if (radio_status == FMRADIO_PLAYING)
630 radio_pause();
631 else
632 radio_start();
634 update_screen = true;
635 talk = false;
636 talk_shutup();
637 break;
639 case ACTION_FM_MENU:
640 fms_fix_displays(FMS_EXIT);
641 radio_menu();
642 preset_set_current(preset_find(curr_freq));
643 update_screen = true;
644 restore = true;
645 break;
647 #ifdef FM_PRESET
648 case ACTION_FM_PRESET:
649 if(radio_preset_count() < 1)
651 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
652 update_screen = true;
653 break;
655 fms_fix_displays(FMS_EXIT);
656 handle_radio_presets();
657 update_screen = true;
658 restore = true;
659 break;
660 #endif /* FM_PRESET */
662 #ifdef FM_FREEZE
663 case ACTION_FM_FREEZE:
664 if(!screen_freeze)
666 splash(HZ, str(LANG_FM_FREEZE));
667 screen_freeze = true;
669 else
671 update_screen = true;
672 screen_freeze = false;
674 break;
675 #endif /* FM_FREEZE */
677 case SYS_USB_CONNECTED:
678 #if CONFIG_CODEC != SWCODEC
679 /* Only accept USB connection when not recording */
680 if(audio_status() != AUDIO_STATUS_RECORD)
681 #endif
683 default_event_handler(SYS_USB_CONNECTED);
684 screen_freeze = true; /* Cosmetic: makes sure the
685 radio screen doesn't redraw */
686 done = true;
688 break;
690 #ifdef FM_MODE
691 case ACTION_FM_MODE:
692 if(radio_mode == RADIO_SCAN_MODE)
694 /* Force scan mode if there are no presets. */
695 if(radio_preset_count() > 0)
696 radio_mode = RADIO_PRESET_MODE;
698 else
699 radio_mode = RADIO_SCAN_MODE;
700 update_screen = true;
701 cond_talk_ids_fq(radio_mode ?
702 LANG_PRESET : LANG_RADIO_SCAN_MODE);
703 talk = true;
704 break;
705 #endif /* FM_MODE */
707 #ifdef FM_NEXT_PRESET
708 case ACTION_FM_NEXT_PRESET:
709 preset_next(1);
710 end_search();
711 update_screen = true;
712 talk = true;
713 break;
714 #endif
716 #ifdef FM_PREV_PRESET
717 case ACTION_FM_PREV_PRESET:
718 preset_next(-1);
719 end_search();
720 update_screen = true;
721 talk = true;
722 break;
723 #endif
724 case ACTION_NONE:
725 update_screen = true; /* so the fms updates */
726 break;
728 default:
729 default_event_handler(button);
730 #ifdef HAVE_RDS_CAP
731 if (tuner_get(RADIO_EVENT))
732 update_screen = true;
733 #endif
734 if (!tuner_get(RADIO_PRESENT))
736 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
737 if(audio_status() == AUDIO_STATUS_RECORD)
738 audio_stop();
739 #endif
740 keep_playing = false;
741 done = true;
742 ret_val = GO_TO_ROOT;
743 if(presets_have_changed())
745 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
747 radio_save_presets();
751 /* Clear the preset list on exit. */
752 preset_list_clear();
754 break;
755 } /*switch(button)*/
757 #ifdef FM_RECORD_DBLPRE
758 if (button != ACTION_NONE)
759 lastbutton = button;
760 #endif
762 #if CONFIG_CODEC != SWCODEC
763 peak_meter_peek();
764 #endif
766 if(!screen_freeze)
768 /* Only display the peak meter when not recording */
769 #if CONFIG_CODEC != SWCODEC
770 if(TIME_AFTER(current_tick, timeout))
772 timeout = current_tick + HZ;
773 #else /* SWCODEC */
775 #endif /* CONFIG_CODEC == SWCODEC */
777 /* keep "mono" from always being displayed when paused */
778 if (radio_status != FMRADIO_PAUSED)
780 stereo = tuner_get(RADIO_STEREO) &&
781 !global_settings.fm_force_mono;
783 if(stereo != last_stereo)
785 update_screen = true;
786 last_stereo = stereo;
791 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
792 seconds = audio_recorded_time() / HZ;
793 if (update_screen || seconds > last_seconds || restore)
795 last_seconds = seconds;
796 #else
797 if (update_screen || restore)
799 #endif
800 if (restore)
801 fms_fix_displays(FMS_ENTER);
802 FOR_NB_SCREENS(i)
803 skin_update(fms_get(i), restore ? SKIN_REFRESH_ALL :
804 SKIN_REFRESH_NON_STATIC);
805 restore = false;
808 update_screen = false;
810 if (global_settings.talk_file && talk
811 && radio_status == FMRADIO_PAUSED)
813 talk = false;
814 bool enqueue = false;
815 if (radio_mode == RADIO_SCAN_MODE)
817 talk_freq(curr_freq, enqueue);
818 enqueue = true;
820 if (radio_current_preset() >= 0)
821 preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
822 enqueue);
825 #if CONFIG_CODEC != SWCODEC
826 if(audio_status() & AUDIO_STATUS_ERROR)
828 done = true;
830 #endif
832 #ifndef HAVE_NOISY_IDLE_MODE
833 if (TIME_AFTER(current_tick, button_timeout))
835 cpu_idle_mode(true);
837 #endif
838 } /*while(!done)*/
840 #ifndef SIMULATOR
841 #if CONFIG_CODEC != SWCODEC
842 if(audio_status() & AUDIO_STATUS_ERROR)
844 splash(0, str(LANG_DISK_FULL));
845 audio_error_clear();
847 while(1)
849 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
850 if(button == ACTION_FM_STOP)
851 break;
855 audio_init_playback();
856 #endif /* CONFIG_CODEC != SWCODEC */
858 sound_settings_apply();
859 #endif /* SIMULATOR */
861 if(keep_playing)
863 /* Catch FMRADIO_PLAYING status for the sim. */
864 #ifndef SIMULATOR
865 #if CONFIG_CODEC != SWCODEC
866 /* Enable the Left and right A/D Converter */
867 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
868 sound_default(SOUND_RIGHT_GAIN),
869 AUDIO_GAIN_LINEIN);
870 mas_codec_writereg(6, 0x4000);
871 #endif
872 end_search();
873 #endif /* SIMULATOR */
875 else
877 #if CONFIG_CODEC == SWCODEC
878 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
879 #else
880 radio_stop();
881 #endif
884 #ifndef HAVE_NOISY_IDLE_MODE
885 cpu_idle_mode(false);
886 #endif
887 fms_fix_displays(FMS_EXIT);
888 in_screen = false;
889 #if CONFIG_CODEC != SWCODEC
890 return have_recorded;
891 #else
892 return false;
893 #endif
894 } /* radio_screen */
896 void toggle_mono_mode(bool mono)
898 tuner_set(RADIO_FORCE_MONO, mono);
901 void set_radio_region(int region)
903 #ifdef HAVE_RADIO_REGION
904 tuner_set(RADIO_REGION, region);
905 #endif
906 next_station(0);
907 remember_frequency();
908 (void)region;
911 MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL);
912 MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL);
914 #ifndef FM_MODE
915 static char* get_mode_text(int selected_item, void * data, char *buffer)
917 (void)selected_item;
918 (void)data;
919 snprintf(buffer, MAX_PATH, "%s %s", str(LANG_MODE),
920 radio_mode ? str(LANG_PRESET) :
921 str(LANG_RADIO_SCAN_MODE));
922 return buffer;
924 static int toggle_radio_mode(void)
926 radio_mode = (radio_mode == RADIO_SCAN_MODE) ?
927 RADIO_PRESET_MODE : RADIO_SCAN_MODE;
928 return 0;
930 MENUITEM_FUNCTION_DYNTEXT(radio_mode_item, 0,
931 toggle_radio_mode, NULL,
932 get_mode_text, NULL, NULL, NULL, Icon_NOICON);
933 #endif
937 #ifdef HAVE_RECORDING
939 #if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
940 #define FM_RECORDING_SCREEN
941 static int fm_recording_screen(void)
943 bool ret;
945 /* switch recording source to FMRADIO for the duration */
946 int rec_source = global_settings.rec_source;
947 global_settings.rec_source = AUDIO_SRC_FMRADIO;
948 ret = recording_screen(true);
950 /* safe to reset as changing sources is prohibited here */
951 global_settings.rec_source = rec_source;
953 return ret;
956 #endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
958 #if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
959 #define FM_RECORDING_SETTINGS
960 static int fm_recording_settings(void)
962 bool ret = recording_menu(true);
964 #if CONFIG_CODEC != SWCODEC
965 if (!ret)
967 struct audio_recording_options rec_options;
968 rec_init_recording_options(&rec_options);
969 rec_options.rec_source = AUDIO_SRC_LINEIN;
970 rec_set_recording_options(&rec_options);
972 #endif
974 return ret;
977 #endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
978 #endif /* HAVE_RECORDING */
980 #ifdef FM_RECORDING_SCREEN
981 MENUITEM_FUNCTION(recscreen_item, 0, ID2P(LANG_RECORDING),
982 fm_recording_screen, NULL, NULL, Icon_Recording);
983 #endif
984 #ifdef FM_RECORDING_SETTINGS
985 MENUITEM_FUNCTION(recsettings_item, 0, ID2P(LANG_RECORDING_SETTINGS),
986 fm_recording_settings, NULL, NULL, Icon_Recording);
987 #endif
988 #ifndef FM_PRESET
989 MENUITEM_FUNCTION(radio_presets_item, 0, ID2P(LANG_PRESET),
990 handle_radio_presets, NULL, NULL, Icon_NOICON);
991 #endif
992 #ifndef FM_PRESET_ADD
993 MENUITEM_FUNCTION(radio_addpreset_item, 0, ID2P(LANG_FM_ADD_PRESET),
994 handle_radio_add_preset, NULL, NULL, Icon_NOICON);
995 #endif
997 MENUITEM_FUNCTION(presetload_item, 0, ID2P(LANG_FM_PRESET_LOAD),
998 preset_list_load, NULL, NULL, Icon_NOICON);
999 MENUITEM_FUNCTION(presetsave_item, 0, ID2P(LANG_FM_PRESET_SAVE),
1000 preset_list_save, NULL, NULL, Icon_NOICON);
1001 MENUITEM_FUNCTION(presetclear_item, 0, ID2P(LANG_FM_PRESET_CLEAR),
1002 preset_list_clear, NULL, NULL, Icon_NOICON);
1003 MENUITEM_FUNCTION(scan_presets_item, MENU_FUNC_USEPARAM,
1004 ID2P(LANG_FM_SCAN_PRESETS),
1005 presets_scan, NULL, NULL, Icon_NOICON);
1007 MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
1008 Icon_Radio_screen,
1009 #ifndef FM_PRESET
1010 &radio_presets_item,
1011 #endif
1012 #ifndef FM_PRESET_ADD
1013 &radio_addpreset_item,
1014 #endif
1015 &presetload_item, &presetsave_item, &presetclear_item,
1016 &force_mono,
1017 #ifndef FM_MODE
1018 &radio_mode_item,
1019 #endif
1020 &set_region, &sound_settings,
1021 #ifdef FM_RECORDING_SCREEN
1022 &recscreen_item,
1023 #endif
1024 #ifdef FM_RECORDING_SETTINGS
1025 &recsettings_item,
1026 #endif
1027 &scan_presets_item);
1028 /* main menu of the radio screen */
1029 static bool radio_menu(void)
1031 return do_menu(&radio_settings_menu, NULL, NULL, false) ==
1032 MENU_ATTACHED_USB;
1035 #endif