Add parse_testcodec.pl, a script for parsing and comparing test_codec.c logs and...
[kugel-rb.git] / apps / radio / radio.c
blobb67506200b05906158fe89c4e12f8f7e36f35d5b
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 #ifdef HAVE_ALBUMART
426 radioart_init(true);
427 #endif
429 if(radio_status == FMRADIO_OFF)
430 audio_stop();
432 #ifndef SIMULATOR
434 #if CONFIG_CODEC != SWCODEC
435 if(rec_create_directory() > 0)
436 have_recorded = true;
438 audio_init_recording(talk_get_bufsize());
440 sound_settings_apply();
441 /* Yes, we use the D/A for monitoring */
442 peak_meter_playback(true);
444 peak_meter_enable(true);
446 rec_init_recording_options(&rec_options);
447 rec_options.rec_source = AUDIO_SRC_LINEIN;
448 rec_set_recording_options(&rec_options);
450 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
451 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
453 #endif /* CONFIG_CODEC != SWCODEC */
454 #endif /* ndef SIMULATOR */
456 /* turn on radio */
457 #if CONFIG_CODEC == SWCODEC
458 /* This should be done before touching audio settings */
459 while (!audio_is_thread_ready())
460 sleep(0);
462 audio_set_input_source(AUDIO_SRC_FMRADIO,
463 (radio_status == FMRADIO_PAUSED) ?
464 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
465 #else
466 if (radio_status == FMRADIO_OFF)
467 radio_start();
468 #endif
470 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
471 presets_scan(NULL);
473 preset_set_current(preset_find(curr_freq));
474 if(radio_current_preset() != -1)
475 radio_mode = RADIO_PRESET_MODE;
477 #ifndef HAVE_NOISY_IDLE_MODE
478 cpu_idle_mode(true);
479 #endif
481 while(!done)
483 if(search_dir != 0)
485 curr_freq = step_freq(curr_freq, search_dir);
486 update_screen = true;
488 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
490 preset_set_current(preset_find(curr_freq));
491 remember_frequency();
492 end_search();
493 talk = true;
495 trigger_cpu_boost();
498 if (!update_screen)
500 cancel_cpu_boost();
503 button = fms_do_button_loop(update_screen);
505 #ifndef HAVE_NOISY_IDLE_MODE
506 if (button != ACTION_NONE)
508 cpu_idle_mode(false);
509 button_timeout = current_tick + (2*HZ);
511 #endif
512 switch(button)
514 case ACTION_FM_STOP:
515 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
516 if(audio_status() == AUDIO_STATUS_RECORD)
518 audio_stop();
520 else
521 #endif
523 done = true;
524 if(presets_have_changed())
526 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
528 presets_save();
532 update_screen = true;
533 break;
535 #ifdef FM_RECORD
536 case ACTION_FM_RECORD:
537 #ifdef FM_RECORD_DBLPRE
538 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
540 rec_lastclick = 0;
541 break;
543 if (current_tick - rec_lastclick > HZ/2)
545 rec_lastclick = current_tick;
546 break;
548 #endif /* FM_RECORD_DBLPRE */
549 #ifndef SIMULATOR
550 if(audio_status() == AUDIO_STATUS_RECORD)
552 rec_command(RECORDING_CMD_START_NEWFILE);
553 update_screen = true;
555 else
557 have_recorded = true;
558 rec_command(RECORDING_CMD_START);
559 update_screen = true;
561 #endif /* SIMULATOR */
562 last_seconds = 0;
563 break;
564 #endif /* #ifdef FM_RECORD */
566 case ACTION_FM_EXIT:
567 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
568 if(audio_status() == AUDIO_STATUS_RECORD)
569 audio_stop();
570 #endif
571 keep_playing = true;
572 done = true;
573 ret_val = GO_TO_ROOT;
574 if(presets_have_changed())
576 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
578 presets_save();
582 break;
584 case ACTION_STD_PREV:
585 case ACTION_STD_NEXT:
586 next_station(button == ACTION_STD_PREV ? -1 : 1);
587 end_search();
588 update_screen = true;
589 talk = true;
590 break;
592 case ACTION_STD_PREVREPEAT:
593 case ACTION_STD_NEXTREPEAT:
595 int dir = search_dir;
596 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
597 if (radio_mode != RADIO_SCAN_MODE)
599 preset_next(search_dir);
600 end_search();
601 update_screen = true;
602 talk = true;
604 else if (dir == 0)
606 /* Starting auto scan */
607 tuner_set(RADIO_MUTE, 1);
608 update_screen = true;
610 break;
613 case ACTION_SETTINGS_INC:
614 case ACTION_SETTINGS_INCREPEAT:
615 global_settings.volume++;
616 setvol();
617 update_screen = true;
618 break;
620 case ACTION_SETTINGS_DEC:
621 case ACTION_SETTINGS_DECREPEAT:
622 global_settings.volume--;
623 setvol();
624 update_screen = true;
625 break;
627 case ACTION_FM_PLAY:
628 if (radio_status == FMRADIO_PLAYING)
629 radio_pause();
630 else
631 radio_start();
633 update_screen = true;
634 talk = false;
635 talk_shutup();
636 break;
638 case ACTION_FM_MENU:
639 fms_fix_displays(FMS_EXIT);
640 radio_menu();
641 preset_set_current(preset_find(curr_freq));
642 update_screen = true;
643 restore = true;
644 break;
646 #ifdef FM_PRESET
647 case ACTION_FM_PRESET:
648 if(radio_preset_count() < 1)
650 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
651 update_screen = true;
652 break;
654 fms_fix_displays(FMS_EXIT);
655 handle_radio_presets();
656 update_screen = true;
657 restore = true;
658 break;
659 #endif /* FM_PRESET */
661 #ifdef FM_FREEZE
662 case ACTION_FM_FREEZE:
663 if(!screen_freeze)
665 splash(HZ, str(LANG_FM_FREEZE));
666 screen_freeze = true;
668 else
670 update_screen = true;
671 screen_freeze = false;
673 break;
674 #endif /* FM_FREEZE */
676 case SYS_USB_CONNECTED:
677 #if CONFIG_CODEC != SWCODEC
678 /* Only accept USB connection when not recording */
679 if(audio_status() != AUDIO_STATUS_RECORD)
680 #endif
682 default_event_handler(SYS_USB_CONNECTED);
683 screen_freeze = true; /* Cosmetic: makes sure the
684 radio screen doesn't redraw */
685 done = true;
687 break;
689 #ifdef FM_MODE
690 case ACTION_FM_MODE:
691 if(radio_mode == RADIO_SCAN_MODE)
693 /* Force scan mode if there are no presets. */
694 if(radio_preset_count() > 0)
695 radio_mode = RADIO_PRESET_MODE;
697 else
698 radio_mode = RADIO_SCAN_MODE;
699 update_screen = true;
700 cond_talk_ids_fq(radio_mode ?
701 LANG_PRESET : LANG_RADIO_SCAN_MODE);
702 talk = true;
703 break;
704 #endif /* FM_MODE */
706 #ifdef FM_NEXT_PRESET
707 case ACTION_FM_NEXT_PRESET:
708 preset_next(1);
709 end_search();
710 update_screen = true;
711 talk = true;
712 break;
713 #endif
715 #ifdef FM_PREV_PRESET
716 case ACTION_FM_PREV_PRESET:
717 preset_next(-1);
718 end_search();
719 update_screen = true;
720 talk = true;
721 break;
722 #endif
723 case ACTION_NONE:
724 update_screen = true; /* so the fms updates */
725 break;
727 default:
728 default_event_handler(button);
729 #ifdef HAVE_RDS_CAP
730 if (tuner_get(RADIO_EVENT))
731 update_screen = true;
732 #endif
733 if (!tuner_get(RADIO_PRESENT))
735 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
736 if(audio_status() == AUDIO_STATUS_RECORD)
737 audio_stop();
738 #endif
739 keep_playing = false;
740 done = true;
741 ret_val = GO_TO_ROOT;
742 if(presets_have_changed())
744 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
746 radio_save_presets();
750 /* Clear the preset list on exit. */
751 preset_list_clear();
753 break;
754 } /*switch(button)*/
756 #ifdef FM_RECORD_DBLPRE
757 if (button != ACTION_NONE)
758 lastbutton = button;
759 #endif
761 #if CONFIG_CODEC != SWCODEC
762 peak_meter_peek();
763 #endif
765 if(!screen_freeze)
767 /* Only display the peak meter when not recording */
768 #if CONFIG_CODEC != SWCODEC
769 if(TIME_AFTER(current_tick, timeout))
771 timeout = current_tick + HZ;
772 #else /* SWCODEC */
774 #endif /* CONFIG_CODEC == SWCODEC */
776 /* keep "mono" from always being displayed when paused */
777 if (radio_status != FMRADIO_PAUSED)
779 stereo = tuner_get(RADIO_STEREO) &&
780 !global_settings.fm_force_mono;
782 if(stereo != last_stereo)
784 update_screen = true;
785 last_stereo = stereo;
790 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
791 seconds = audio_recorded_time() / HZ;
792 if (update_screen || seconds > last_seconds || restore)
794 last_seconds = seconds;
795 #else
796 if (update_screen || restore)
798 #endif
799 if (restore)
800 fms_fix_displays(FMS_ENTER);
801 FOR_NB_SCREENS(i)
802 skin_update(fms_get(i), restore ? WPS_REFRESH_ALL :
803 WPS_REFRESH_NON_STATIC);
804 restore = false;
807 update_screen = false;
809 if (global_settings.talk_file && talk
810 && radio_status == FMRADIO_PAUSED)
812 talk = false;
813 bool enqueue = false;
814 if (radio_mode == RADIO_SCAN_MODE)
816 talk_freq(curr_freq, enqueue);
817 enqueue = true;
819 if (radio_current_preset() >= 0)
820 preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
821 enqueue);
824 #if CONFIG_CODEC != SWCODEC
825 if(audio_status() & AUDIO_STATUS_ERROR)
827 done = true;
829 #endif
831 #ifndef HAVE_NOISY_IDLE_MODE
832 if (TIME_AFTER(current_tick, button_timeout))
834 cpu_idle_mode(true);
836 #endif
837 } /*while(!done)*/
839 #ifndef SIMULATOR
840 #if CONFIG_CODEC != SWCODEC
841 if(audio_status() & AUDIO_STATUS_ERROR)
843 splash(0, str(LANG_DISK_FULL));
844 audio_error_clear();
846 while(1)
848 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
849 if(button == ACTION_FM_STOP)
850 break;
854 audio_init_playback();
855 #endif /* CONFIG_CODEC != SWCODEC */
857 sound_settings_apply();
858 #endif /* SIMULATOR */
860 if(keep_playing)
862 /* Catch FMRADIO_PLAYING status for the sim. */
863 #ifndef SIMULATOR
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),
868 AUDIO_GAIN_LINEIN);
869 mas_codec_writereg(6, 0x4000);
870 #endif
871 end_search();
872 #endif /* SIMULATOR */
874 else
876 #if CONFIG_CODEC == SWCODEC
877 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
878 #else
879 radio_stop();
880 #endif
883 #ifndef HAVE_NOISY_IDLE_MODE
884 cpu_idle_mode(false);
885 #endif
886 fms_fix_displays(FMS_EXIT);
887 in_screen = false;
888 #if CONFIG_CODEC != SWCODEC
889 return have_recorded;
890 #else
891 return false;
892 #endif
893 } /* radio_screen */
895 void toggle_mono_mode(bool mono)
897 tuner_set(RADIO_FORCE_MONO, mono);
900 void set_radio_region(int region)
902 #ifdef HAVE_RADIO_REGION
903 tuner_set(RADIO_REGION, region);
904 #endif
905 next_station(0);
906 remember_frequency();
907 (void)region;
910 MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL);
911 MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL);
913 #ifndef FM_MODE
914 static char* get_mode_text(int selected_item, void * data, char *buffer)
916 (void)selected_item;
917 (void)data;
918 snprintf(buffer, MAX_PATH, "%s %s", str(LANG_MODE),
919 radio_mode ? str(LANG_PRESET) :
920 str(LANG_RADIO_SCAN_MODE));
921 return buffer;
923 static int toggle_radio_mode(void)
925 radio_mode = (radio_mode == RADIO_SCAN_MODE) ?
926 RADIO_PRESET_MODE : RADIO_SCAN_MODE;
927 return 0;
929 MENUITEM_FUNCTION_DYNTEXT(radio_mode_item, 0,
930 toggle_radio_mode, NULL,
931 get_mode_text, NULL, NULL, NULL, Icon_NOICON);
932 #endif
936 #ifdef HAVE_RECORDING
938 #if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
939 #define FM_RECORDING_SCREEN
940 static int fm_recording_screen(void)
942 bool ret;
944 /* switch recording source to FMRADIO for the duration */
945 int rec_source = global_settings.rec_source;
946 global_settings.rec_source = AUDIO_SRC_FMRADIO;
947 ret = recording_screen(true);
949 /* safe to reset as changing sources is prohibited here */
950 global_settings.rec_source = rec_source;
952 return ret;
955 #endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
957 #if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
958 #define FM_RECORDING_SETTINGS
959 static int fm_recording_settings(void)
961 bool ret = recording_menu(true);
963 #if CONFIG_CODEC != SWCODEC
964 if (!ret)
966 struct audio_recording_options rec_options;
967 rec_init_recording_options(&rec_options);
968 rec_options.rec_source = AUDIO_SRC_LINEIN;
969 rec_set_recording_options(&rec_options);
971 #endif
973 return ret;
976 #endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
977 #endif /* HAVE_RECORDING */
979 #ifdef FM_RECORDING_SCREEN
980 MENUITEM_FUNCTION(recscreen_item, 0, ID2P(LANG_RECORDING),
981 fm_recording_screen, NULL, NULL, Icon_Recording);
982 #endif
983 #ifdef FM_RECORDING_SETTINGS
984 MENUITEM_FUNCTION(recsettings_item, 0, ID2P(LANG_RECORDING_SETTINGS),
985 fm_recording_settings, NULL, NULL, Icon_Recording);
986 #endif
987 #ifndef FM_PRESET
988 MENUITEM_FUNCTION(radio_presets_item, 0, ID2P(LANG_PRESET),
989 handle_radio_presets, NULL, NULL, Icon_NOICON);
990 #endif
991 #ifndef FM_PRESET_ADD
992 MENUITEM_FUNCTION(radio_addpreset_item, 0, ID2P(LANG_FM_ADD_PRESET),
993 handle_radio_add_preset, NULL, NULL, Icon_NOICON);
994 #endif
996 MENUITEM_FUNCTION(presetload_item, 0, ID2P(LANG_FM_PRESET_LOAD),
997 preset_list_load, NULL, NULL, Icon_NOICON);
998 MENUITEM_FUNCTION(presetsave_item, 0, ID2P(LANG_FM_PRESET_SAVE),
999 preset_list_save, NULL, NULL, Icon_NOICON);
1000 MENUITEM_FUNCTION(presetclear_item, 0, ID2P(LANG_FM_PRESET_CLEAR),
1001 preset_list_clear, NULL, NULL, Icon_NOICON);
1002 MENUITEM_FUNCTION(scan_presets_item, MENU_FUNC_USEPARAM,
1003 ID2P(LANG_FM_SCAN_PRESETS),
1004 presets_scan, NULL, NULL, Icon_NOICON);
1006 MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
1007 Icon_Radio_screen,
1008 #ifndef FM_PRESET
1009 &radio_presets_item,
1010 #endif
1011 #ifndef FM_PRESET_ADD
1012 &radio_addpreset_item,
1013 #endif
1014 &presetload_item, &presetsave_item, &presetclear_item,
1015 &force_mono,
1016 #ifndef FM_MODE
1017 &radio_mode_item,
1018 #endif
1019 &set_region, &sound_settings,
1020 #ifdef FM_RECORDING_SCREEN
1021 &recscreen_item,
1022 #endif
1023 #ifdef FM_RECORDING_SETTINGS
1024 &recsettings_item,
1025 #endif
1026 &scan_presets_item);
1027 /* main menu of the radio screen */
1028 static bool radio_menu(void)
1030 return do_menu(&radio_settings_menu, NULL, NULL, false) ==
1031 MENU_ATTACHED_USB;
1034 #endif