Move buffer.h to firmware/include.h to replace a useless malloc header.
[kugel-rb.git] / apps / radio / radio.c
blob4da37b2ca5530122c3da9ab1cb546cfb2c54a12f
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 <stdio.h>
23 #include <stdbool.h>
24 #include <stdlib.h>
25 #include "config.h"
26 #include "system.h"
27 #include "settings.h"
28 #include "status.h"
29 #include "audio.h"
30 #include "general.h"
31 #include "radio.h"
32 #include "menu.h"
33 #include "menus/exported_menus.h"
34 #include "misc.h"
35 #include "screens.h"
36 #include "peakmeter.h"
37 #include "lang.h"
38 #ifdef HAVE_RECORDING
39 #include "recording.h"
40 #endif
41 #ifdef IPOD_ACCESSORY_PROTOCOL
42 #include "iap.h"
43 #endif
44 #include "talk.h"
45 #include "tuner.h"
46 #include "power.h"
47 #include "sound.h"
48 #include "screen_access.h"
49 #include "splash.h"
50 #include "yesno.h"
51 #include "tree.h"
52 #include "dir.h"
53 #include "action.h"
54 #include "viewport.h"
55 #include "skin_engine/skin_engine.h"
56 #include "statusbar-skinned.h"
57 #if CONFIG_CODEC == SWCODEC
58 #include "playback.h"
59 #endif
60 #include "presets.h"
62 #if CONFIG_TUNER
64 #if CONFIG_KEYPAD == RECORDER_PAD
65 #define FM_RECORD
66 #define FM_PRESET_ADD
67 #define FM_PRESET_ACTION
68 #define FM_PRESET
69 #define FM_MODE
71 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
72 #define FM_PRESET
73 #define FM_MODE
74 #define FM_NEXT_PRESET
75 #define FM_PREV_PRESET
77 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
78 #define FM_PRESET
79 #define FM_MODE
81 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
82 #define FM_PRESET
83 #define FM_MODE
84 /* This should be removeable if the whole tuning thing is sorted out since
85 proper tuning quiets the screen almost entirely in that extreme measures
86 have to be taken to hear any interference. */
87 #define HAVE_NOISY_IDLE_MODE
89 #elif CONFIG_KEYPAD == ONDIO_PAD
90 #define FM_RECORD_DBLPRE
91 #define FM_RECORD
93 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD) ||\
94 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD)
95 #define FM_MENU
96 #define FM_PRESET
97 #define FM_STOP
98 #define FM_MODE
99 #define FM_EXIT
100 #define FM_PLAY
102 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
103 #define FM_PRESET
104 #define FM_MODE
106 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
107 #define FM_MENU
108 #define FM_PRESET
109 #define FM_STOP
110 #define FM_MODE
111 #define FM_EXIT
112 #define FM_PLAY
114 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
115 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
116 #define FM_MENU
117 #define FM_STOP
118 #define FM_EXIT
119 #define FM_PLAY
120 #define FM_MODE
122 #elif (CONFIG_KEYPAD == MPIO_HD200_PAD)
123 #define FM_MENU
124 #define FM_STOP
125 #define FM_EXIT
126 #define FM_PLAY
127 #define FM_MODE
128 #define FM_STOP
130 #endif
132 /* presets.c needs these so keep unstatic or redo the whole thing! */
133 int curr_freq; /* current frequency in Hz */
134 int radio_mode = RADIO_SCAN_MODE;
136 static int search_dir = 0;
137 static int radio_status = FMRADIO_OFF;
138 static bool in_screen = false;
141 static void radio_off(void);
143 bool radio_scan_mode(void)
145 return radio_mode == RADIO_SCAN_MODE;
148 bool radio_is_stereo(void)
150 return tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono;
152 int radio_current_frequency(void)
154 return curr_freq;
157 /* Function to manipulate all yesno dialogues.
158 This function needs the output text as an argument. */
159 bool yesno_pop(const char* text)
161 int i;
162 const char *lines[]={text};
163 const struct text_message message={lines, 1};
164 bool ret = (gui_syncyesno_run(&message,NULL,NULL)== YESNO_YES);
165 FOR_NB_SCREENS(i)
166 screens[i].clear_viewport();
167 return ret;
170 void radio_init(void)
172 tuner_init();
173 radio_off();
174 #ifdef HAVE_ALBUMART
175 radioart_init(false);
176 #endif
179 int get_radio_status(void)
181 return radio_status;
184 bool in_radio_screen(void)
186 return in_screen;
189 /* TODO: Move some more of the control functionality to firmware
190 and clean up the mess */
192 /* secret flag for starting paused - prevents unmute */
193 #define FMRADIO_START_PAUSED 0x8000
194 void radio_start(void)
196 const struct fm_region_data *fmr;
197 bool start_paused;
199 if(radio_status == FMRADIO_PLAYING)
200 return;
202 fmr = &fm_region_data[global_settings.fm_region];
204 start_paused = radio_status & FMRADIO_START_PAUSED;
205 /* clear flag before any yielding */
206 radio_status &= ~FMRADIO_START_PAUSED;
208 if(radio_status == FMRADIO_OFF)
209 tuner_power(true);
211 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
213 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
215 if(radio_status == FMRADIO_OFF)
217 #ifdef HAVE_RADIO_REGION
218 tuner_set(RADIO_REGION, global_settings.fm_region);
219 #endif
220 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
223 tuner_set(RADIO_FREQUENCY, curr_freq);
225 #ifdef HAVE_RADIO_MUTE_TIMEOUT
227 unsigned long mute_timeout = current_tick + HZ;
228 if (radio_status != FMRADIO_OFF)
230 /* paused */
231 mute_timeout += HZ;
234 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
236 if(TIME_AFTER(current_tick, mute_timeout))
237 break;
238 yield();
241 #endif
243 /* keep radio from sounding initially */
244 if(!start_paused)
245 tuner_set(RADIO_MUTE, 0);
247 radio_status = FMRADIO_PLAYING;
248 } /* radio_start */
250 void radio_pause(void)
252 if(radio_status == FMRADIO_PAUSED)
253 return;
255 if(radio_status == FMRADIO_OFF)
257 radio_status |= FMRADIO_START_PAUSED;
258 radio_start();
261 tuner_set(RADIO_MUTE, 1);
262 /* For si4700: 2==this is really 'pause'. other tuners treat it
263 * like 'bool'. */
264 tuner_set(RADIO_SLEEP, 2);
266 radio_status = FMRADIO_PAUSED;
267 } /* radio_pause */
269 static void radio_off(void)
271 tuner_set(RADIO_MUTE, 1);
272 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
273 radio_status = FMRADIO_OFF;
274 tuner_power(false); /* status update, power off if avail. */
277 void radio_stop(void)
279 if(radio_status == FMRADIO_OFF)
280 return;
282 radio_off();
283 } /* radio_stop */
285 bool radio_hardware_present(void)
287 return tuner_get(RADIO_PRESENT);
290 /* Keep freq on the grid for the current region */
291 int snap_freq_to_grid(int freq)
293 const struct fm_region_data * const fmr =
294 &fm_region_data[global_settings.fm_region];
296 /* Range clamp if out of range or just round to nearest */
297 if (freq < fmr->freq_min)
298 freq = fmr->freq_min;
299 else if (freq > fmr->freq_max)
300 freq = fmr->freq_max;
301 else
302 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
303 fmr->freq_step * fmr->freq_step + fmr->freq_min;
305 return freq;
308 void remember_frequency(void)
310 const struct fm_region_data * const fmr =
311 &fm_region_data[global_settings.fm_region];
312 global_status.last_frequency = (curr_freq - fmr->freq_min)
313 / fmr->freq_step;
314 status_save();
317 /* Step to the next or previous frequency */
318 static int step_freq(int freq, int direction)
320 const struct fm_region_data * const fmr =
321 &fm_region_data[global_settings.fm_region];
323 freq += direction*fmr->freq_step;
325 /* Wrap first or snapping to grid will not let us on the band extremes */
326 if (freq > fmr->freq_max)
327 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
328 else if (freq < fmr->freq_min)
329 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
330 else
331 freq = snap_freq_to_grid(freq);
333 return freq;
336 /* Step to the next or previous station */
337 void next_station(int direction)
339 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
341 preset_next(direction);
342 return;
345 curr_freq = step_freq(curr_freq, direction);
347 if (radio_status == FMRADIO_PLAYING)
348 tuner_set(RADIO_MUTE, 1);
350 tuner_set(RADIO_FREQUENCY, curr_freq);
352 if (radio_status == FMRADIO_PLAYING)
353 tuner_set(RADIO_MUTE, 0);
355 preset_set_current(preset_find(curr_freq));
356 remember_frequency();
359 /* Ends an in-progress search */
360 static void end_search(void)
362 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
363 tuner_set(RADIO_MUTE, 0);
364 search_dir = 0;
367 /* Speak a frequency. */
368 void talk_freq(int freq, bool enqueue)
370 freq /= 10000;
371 talk_number(freq / 100, enqueue);
372 talk_id(LANG_POINT, true);
373 talk_number(freq % 100 / 10, true);
374 if (freq % 10)
375 talk_number(freq % 10, true);
379 void radio_screen(void)
381 bool done = false;
382 int button;
383 int i;
384 bool stereo = false, last_stereo = false;
385 int update_type = 0;
386 bool screen_freeze = false;
387 bool keep_playing = false;
388 bool talk = false;
389 #ifdef FM_RECORD_DBLPRE
390 int lastbutton = BUTTON_NONE;
391 unsigned long rec_lastclick = 0;
392 #endif
393 #if CONFIG_CODEC != SWCODEC
394 int timeout = current_tick + HZ/10;
395 #if !defined(SIMULATOR)
396 unsigned int last_seconds = 0;
397 unsigned int seconds = 0;
398 struct audio_recording_options rec_options;
399 #endif /* SIMULATOR */
400 #endif /* CONFIG_CODEC != SWCODEC */
401 #ifndef HAVE_NOISY_IDLE_MODE
402 int button_timeout = current_tick + (2*HZ);
403 #endif
405 /* change status to "in screen" */
406 push_current_activity(ACTIVITY_FM);
407 in_screen = true;
409 if(radio_preset_count() <= 0)
411 radio_load_presets(global_settings.fmr_file);
413 skin_get_global_state()->id3 = NULL;
414 #ifdef HAVE_ALBUMART
415 radioart_init(true);
416 #endif
418 if(radio_status == FMRADIO_OFF)
419 audio_stop();
421 #ifndef SIMULATOR
423 #if CONFIG_CODEC != SWCODEC
424 rec_create_directory();
425 audio_init_recording(talk_get_bufsize());
427 sound_settings_apply();
428 /* Yes, we use the D/A for monitoring */
429 peak_meter_playback(true);
431 peak_meter_enable(true);
433 rec_init_recording_options(&rec_options);
434 rec_options.rec_source = AUDIO_SRC_LINEIN;
435 rec_set_recording_options(&rec_options);
437 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
438 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
440 #endif /* CONFIG_CODEC != SWCODEC */
441 #endif /* ndef SIMULATOR */
443 /* turn on radio */
444 #if CONFIG_CODEC == SWCODEC
445 /* This should be done before touching audio settings */
446 while (!audio_is_thread_ready())
447 sleep(0);
449 audio_set_input_source(AUDIO_SRC_FMRADIO,
450 (radio_status == FMRADIO_PAUSED) ?
451 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
452 #else
453 if (radio_status == FMRADIO_OFF)
454 radio_start();
455 #endif
457 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
458 presets_scan(NULL);
460 fms_fix_displays(FMS_ENTER);
461 FOR_NB_SCREENS(i)
462 skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);
464 preset_set_current(preset_find(curr_freq));
465 if(radio_current_preset() != -1)
466 radio_mode = RADIO_PRESET_MODE;
468 #ifndef HAVE_NOISY_IDLE_MODE
469 cpu_idle_mode(true);
470 #endif
472 while(!done)
474 if(search_dir != 0)
476 curr_freq = step_freq(curr_freq, search_dir);
477 update_type = SKIN_REFRESH_ALL;
479 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
481 preset_set_current(preset_find(curr_freq));
482 remember_frequency();
483 end_search();
484 talk = true;
486 trigger_cpu_boost();
489 if (!update_type)
491 cancel_cpu_boost();
494 button = fms_do_button_loop(update_type>0);
496 #ifndef HAVE_NOISY_IDLE_MODE
497 if (button != ACTION_NONE)
499 cpu_idle_mode(false);
500 button_timeout = current_tick + (2*HZ);
502 #endif
503 switch(button)
505 case ACTION_FM_STOP:
506 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
507 if(audio_status() == AUDIO_STATUS_RECORD)
509 audio_stop();
511 else
512 #endif
514 done = true;
515 if(presets_have_changed())
517 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
519 presets_save();
523 update_type = SKIN_REFRESH_NON_STATIC;
524 break;
526 #ifdef FM_RECORD
527 case ACTION_FM_RECORD:
528 #ifdef FM_RECORD_DBLPRE
529 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
531 rec_lastclick = 0;
532 break;
534 if (current_tick - rec_lastclick > HZ/2)
536 rec_lastclick = current_tick;
537 break;
539 #endif /* FM_RECORD_DBLPRE */
540 #ifndef SIMULATOR
541 if(audio_status() == AUDIO_STATUS_RECORD)
543 rec_command(RECORDING_CMD_START_NEWFILE);
544 update_type = SKIN_REFRESH_ALL;
546 else
548 rec_command(RECORDING_CMD_START);
549 update_type = SKIN_REFRESH_ALL;
551 #if CONFIG_CODEC != SWCODEC
552 last_seconds = 0;
553 #endif
554 #endif /* SIMULATOR */
555 break;
556 #endif /* #ifdef FM_RECORD */
558 case ACTION_FM_EXIT:
559 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
560 if(audio_status() == AUDIO_STATUS_RECORD)
561 audio_stop();
562 #endif
563 keep_playing = true;
564 done = true;
565 if(presets_have_changed())
567 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
569 presets_save();
573 break;
575 case ACTION_STD_PREV:
576 case ACTION_STD_NEXT:
577 next_station(button == ACTION_STD_PREV ? -1 : 1);
578 end_search();
579 update_type = SKIN_REFRESH_ALL;
580 talk = true;
581 break;
583 case ACTION_STD_PREVREPEAT:
584 case ACTION_STD_NEXTREPEAT:
586 int dir = search_dir;
587 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
588 if (radio_mode != RADIO_SCAN_MODE)
590 preset_next(search_dir);
591 end_search();
592 talk = true;
594 else if (dir == 0)
596 /* Starting auto scan */
597 tuner_set(RADIO_MUTE, 1);
599 update_type = SKIN_REFRESH_ALL;
600 break;
603 case ACTION_SETTINGS_INC:
604 case ACTION_SETTINGS_INCREPEAT:
605 global_settings.volume++;
606 setvol();
607 update_type = SKIN_REFRESH_NON_STATIC;
608 break;
610 case ACTION_SETTINGS_DEC:
611 case ACTION_SETTINGS_DECREPEAT:
612 global_settings.volume--;
613 setvol();
614 update_type = SKIN_REFRESH_NON_STATIC;
615 break;
617 case ACTION_FM_PLAY:
618 if (radio_status == FMRADIO_PLAYING)
619 radio_pause();
620 else
621 radio_start();
623 update_type = SKIN_REFRESH_NON_STATIC;
624 talk = false;
625 talk_shutup();
626 break;
628 case ACTION_FM_MENU:
629 fms_fix_displays(FMS_EXIT);
630 do_menu(&radio_settings_menu, NULL, NULL, false);
631 preset_set_current(preset_find(curr_freq));
632 fms_fix_displays(FMS_ENTER);
633 update_type = SKIN_REFRESH_ALL;
634 break;
636 #ifdef FM_PRESET
637 case ACTION_FM_PRESET:
638 if(radio_preset_count() < 1)
640 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
641 update_type = SKIN_REFRESH_ALL;
642 break;
644 fms_fix_displays(FMS_EXIT);
645 handle_radio_presets();
646 fms_fix_displays(FMS_ENTER);
647 update_type = SKIN_REFRESH_ALL;
648 break;
649 #endif /* FM_PRESET */
651 #ifdef FM_FREEZE
652 case ACTION_FM_FREEZE:
653 if(!screen_freeze)
655 splash(HZ, str(LANG_FM_FREEZE));
656 screen_freeze = true;
658 else
660 update_type = SKIN_REFRESH_ALL;
661 screen_freeze = false;
663 break;
664 #endif /* FM_FREEZE */
666 case SYS_USB_CONNECTED:
667 #if CONFIG_CODEC != SWCODEC
668 /* Only accept USB connection when not recording */
669 if(audio_status() != AUDIO_STATUS_RECORD)
670 #endif
672 default_event_handler(SYS_USB_CONNECTED);
673 screen_freeze = true; /* Cosmetic: makes sure the
674 radio screen doesn't redraw */
675 done = true;
677 break;
679 #ifdef FM_MODE
680 case ACTION_FM_MODE:
681 if(radio_mode == RADIO_SCAN_MODE)
683 /* Force scan mode if there are no presets. */
684 if(radio_preset_count() > 0)
685 radio_mode = RADIO_PRESET_MODE;
687 else
688 radio_mode = RADIO_SCAN_MODE;
689 update_type = SKIN_REFRESH_ALL;
690 cond_talk_ids_fq(radio_mode ?
691 LANG_PRESET : LANG_RADIO_SCAN_MODE);
692 talk = true;
693 break;
694 #endif /* FM_MODE */
696 #ifdef FM_NEXT_PRESET
697 case ACTION_FM_NEXT_PRESET:
698 preset_next(1);
699 end_search();
700 update_type = SKIN_REFRESH_ALL;
701 talk = true;
702 break;
703 #endif
705 #ifdef FM_PREV_PRESET
706 case ACTION_FM_PREV_PRESET:
707 preset_next(-1);
708 end_search();
709 update_type = SKIN_REFRESH_ALL;
710 talk = true;
711 break;
712 #endif
713 case ACTION_NONE:
714 update_type = SKIN_REFRESH_NON_STATIC;
715 break;
717 default:
718 default_event_handler(button);
719 #ifdef HAVE_RDS_CAP
720 if (tuner_get(RADIO_EVENT))
721 update_type = SKIN_REFRESH_ALL;
722 #endif
723 if (!tuner_get(RADIO_PRESENT))
725 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
726 if(audio_status() == AUDIO_STATUS_RECORD)
727 audio_stop();
728 #endif
729 keep_playing = false;
730 done = true;
731 if(presets_have_changed())
733 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
735 radio_save_presets();
739 /* Clear the preset list on exit. */
740 preset_list_clear();
742 break;
743 } /*switch(button)*/
745 #ifdef FM_RECORD_DBLPRE
746 if (button != ACTION_NONE)
747 lastbutton = button;
748 #endif
750 #if CONFIG_CODEC != SWCODEC
751 peak_meter_peek();
752 #endif
754 if(!screen_freeze)
756 /* Only display the peak meter when not recording */
757 #if CONFIG_CODEC != SWCODEC
758 if(TIME_AFTER(current_tick, timeout))
760 timeout = current_tick + HZ;
761 #else /* SWCODEC */
763 #endif /* CONFIG_CODEC == SWCODEC */
765 /* keep "mono" from always being displayed when paused */
766 if (radio_status != FMRADIO_PAUSED)
768 stereo = tuner_get(RADIO_STEREO) &&
769 !global_settings.fm_force_mono;
771 if(stereo != last_stereo)
773 update_type = SKIN_REFRESH_ALL;
774 last_stereo = stereo;
779 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
780 seconds = audio_recorded_time() / HZ;
781 if (update_type || seconds > last_seconds)
783 last_seconds = seconds;
784 #else
785 if (update_type)
787 #endif
788 FOR_NB_SCREENS(i)
789 skin_update(FM_SCREEN, i, update_type);
792 update_type = 0;
794 if (global_settings.talk_file && talk
795 && radio_status == FMRADIO_PAUSED)
797 talk = false;
798 bool enqueue = false;
799 if (radio_mode == RADIO_SCAN_MODE)
801 talk_freq(curr_freq, enqueue);
802 enqueue = true;
804 if (radio_current_preset() >= 0)
805 preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
806 enqueue);
809 #if CONFIG_CODEC != SWCODEC
810 if(audio_status() & AUDIO_STATUS_ERROR)
812 done = true;
814 #endif
816 #ifndef HAVE_NOISY_IDLE_MODE
817 if (TIME_AFTER(current_tick, button_timeout))
819 cpu_idle_mode(true);
821 #endif
822 } /*while(!done)*/
824 #ifndef SIMULATOR
825 #if CONFIG_CODEC != SWCODEC
826 if(audio_status() & AUDIO_STATUS_ERROR)
828 splash(0, str(LANG_DISK_FULL));
829 audio_error_clear();
831 while(1)
833 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
834 if(button == ACTION_FM_STOP)
835 break;
839 audio_init_playback();
840 #endif /* CONFIG_CODEC != SWCODEC */
842 sound_settings_apply();
843 #endif /* SIMULATOR */
845 if(keep_playing)
847 /* Catch FMRADIO_PLAYING status for the sim. */
848 #ifndef SIMULATOR
849 #if CONFIG_CODEC != SWCODEC
850 /* Enable the Left and right A/D Converter */
851 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
852 sound_default(SOUND_RIGHT_GAIN),
853 AUDIO_GAIN_LINEIN);
854 mas_codec_writereg(6, 0x4000);
855 #endif
856 end_search();
857 #endif /* SIMULATOR */
859 else
861 #if CONFIG_CODEC == SWCODEC
862 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
863 #else
864 radio_stop();
865 #endif
868 #ifndef HAVE_NOISY_IDLE_MODE
869 cpu_idle_mode(false);
870 #endif
871 fms_fix_displays(FMS_EXIT);
872 pop_current_activity();
873 in_screen = false;
874 } /* radio_screen */
876 void toggle_mono_mode(bool mono)
878 tuner_set(RADIO_FORCE_MONO, mono);
881 void set_radio_region(int region)
883 #ifdef HAVE_RADIO_REGION
884 tuner_set(RADIO_REGION, region);
885 #endif
886 next_station(0);
887 remember_frequency();
888 (void)region;
891 #endif