Pull yesno_pop out of the radio code as it is a nice simple resuasble yesno api worth...
[kugel-rb.git] / apps / radio / radio.c
blobf88a63382dfd98bb39d9a3a6a2a776ea01ff79ee
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 void radio_init(void)
159 tuner_init();
160 radio_off();
161 #ifdef HAVE_ALBUMART
162 radioart_init(false);
163 #endif
166 int get_radio_status(void)
168 return radio_status;
171 bool in_radio_screen(void)
173 return in_screen;
176 /* TODO: Move some more of the control functionality to firmware
177 and clean up the mess */
179 /* secret flag for starting paused - prevents unmute */
180 #define FMRADIO_START_PAUSED 0x8000
181 void radio_start(void)
183 const struct fm_region_data *fmr;
184 bool start_paused;
186 if(radio_status == FMRADIO_PLAYING)
187 return;
189 fmr = &fm_region_data[global_settings.fm_region];
191 start_paused = radio_status & FMRADIO_START_PAUSED;
192 /* clear flag before any yielding */
193 radio_status &= ~FMRADIO_START_PAUSED;
195 if(radio_status == FMRADIO_OFF)
196 tuner_power(true);
198 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
200 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
202 if(radio_status == FMRADIO_OFF)
204 #ifdef HAVE_RADIO_REGION
205 tuner_set(RADIO_REGION, global_settings.fm_region);
206 #endif
207 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
210 tuner_set(RADIO_FREQUENCY, curr_freq);
212 #ifdef HAVE_RADIO_MUTE_TIMEOUT
214 unsigned long mute_timeout = current_tick + HZ;
215 if (radio_status != FMRADIO_OFF)
217 /* paused */
218 mute_timeout += HZ;
221 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
223 if(TIME_AFTER(current_tick, mute_timeout))
224 break;
225 yield();
228 #endif
230 /* keep radio from sounding initially */
231 if(!start_paused)
232 tuner_set(RADIO_MUTE, 0);
234 radio_status = FMRADIO_PLAYING;
235 } /* radio_start */
237 void radio_pause(void)
239 if(radio_status == FMRADIO_PAUSED)
240 return;
242 if(radio_status == FMRADIO_OFF)
244 radio_status |= FMRADIO_START_PAUSED;
245 radio_start();
248 tuner_set(RADIO_MUTE, 1);
249 /* For si4700: 2==this is really 'pause'. other tuners treat it
250 * like 'bool'. */
251 tuner_set(RADIO_SLEEP, 2);
253 radio_status = FMRADIO_PAUSED;
254 } /* radio_pause */
256 static void radio_off(void)
258 tuner_set(RADIO_MUTE, 1);
259 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
260 radio_status = FMRADIO_OFF;
261 tuner_power(false); /* status update, power off if avail. */
264 void radio_stop(void)
266 if(radio_status == FMRADIO_OFF)
267 return;
269 radio_off();
270 } /* radio_stop */
272 bool radio_hardware_present(void)
274 return tuner_get(RADIO_PRESENT);
277 /* Keep freq on the grid for the current region */
278 int snap_freq_to_grid(int freq)
280 const struct fm_region_data * const fmr =
281 &fm_region_data[global_settings.fm_region];
283 /* Range clamp if out of range or just round to nearest */
284 if (freq < fmr->freq_min)
285 freq = fmr->freq_min;
286 else if (freq > fmr->freq_max)
287 freq = fmr->freq_max;
288 else
289 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
290 fmr->freq_step * fmr->freq_step + fmr->freq_min;
292 return freq;
295 void remember_frequency(void)
297 const struct fm_region_data * const fmr =
298 &fm_region_data[global_settings.fm_region];
299 global_status.last_frequency = (curr_freq - fmr->freq_min)
300 / fmr->freq_step;
301 status_save();
304 /* Step to the next or previous frequency */
305 static int step_freq(int freq, int direction)
307 const struct fm_region_data * const fmr =
308 &fm_region_data[global_settings.fm_region];
310 freq += direction*fmr->freq_step;
312 /* Wrap first or snapping to grid will not let us on the band extremes */
313 if (freq > fmr->freq_max)
314 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
315 else if (freq < fmr->freq_min)
316 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
317 else
318 freq = snap_freq_to_grid(freq);
320 return freq;
323 /* Step to the next or previous station */
324 void next_station(int direction)
326 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
328 preset_next(direction);
329 return;
332 curr_freq = step_freq(curr_freq, direction);
334 if (radio_status == FMRADIO_PLAYING)
335 tuner_set(RADIO_MUTE, 1);
337 tuner_set(RADIO_FREQUENCY, curr_freq);
339 if (radio_status == FMRADIO_PLAYING)
340 tuner_set(RADIO_MUTE, 0);
342 preset_set_current(preset_find(curr_freq));
343 remember_frequency();
346 /* Ends an in-progress search */
347 static void end_search(void)
349 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
350 tuner_set(RADIO_MUTE, 0);
351 search_dir = 0;
354 void radio_screen(void)
356 bool done = false;
357 int button;
358 int i;
359 bool stereo = false, last_stereo = false;
360 int update_type = 0;
361 bool screen_freeze = false;
362 bool keep_playing = false;
363 bool talk = false;
364 #ifdef FM_RECORD_DBLPRE
365 int lastbutton = BUTTON_NONE;
366 unsigned long rec_lastclick = 0;
367 #endif
368 #if CONFIG_CODEC != SWCODEC
369 int timeout = current_tick + HZ/10;
370 #if !defined(SIMULATOR)
371 unsigned int last_seconds = 0;
372 unsigned int seconds = 0;
373 struct audio_recording_options rec_options;
374 #endif /* SIMULATOR */
375 #endif /* CONFIG_CODEC != SWCODEC */
376 #ifndef HAVE_NOISY_IDLE_MODE
377 int button_timeout = current_tick + (2*HZ);
378 #endif
380 /* change status to "in screen" */
381 push_current_activity(ACTIVITY_FM);
382 in_screen = true;
384 if(radio_preset_count() <= 0)
386 radio_load_presets(global_settings.fmr_file);
388 skin_get_global_state()->id3 = NULL;
389 #ifdef HAVE_ALBUMART
390 radioart_init(true);
391 #endif
393 if(radio_status == FMRADIO_OFF)
394 audio_stop();
396 #ifndef SIMULATOR
398 #if CONFIG_CODEC != SWCODEC
399 rec_create_directory();
400 audio_init_recording(talk_get_bufsize());
402 sound_settings_apply();
403 /* Yes, we use the D/A for monitoring */
404 peak_meter_playback(true);
406 peak_meter_enable(true);
408 rec_init_recording_options(&rec_options);
409 rec_options.rec_source = AUDIO_SRC_LINEIN;
410 rec_set_recording_options(&rec_options);
412 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
413 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
415 #endif /* CONFIG_CODEC != SWCODEC */
416 #endif /* ndef SIMULATOR */
418 /* turn on radio */
419 #if CONFIG_CODEC == SWCODEC
420 /* This should be done before touching audio settings */
421 while (!audio_is_thread_ready())
422 sleep(0);
424 audio_set_input_source(AUDIO_SRC_FMRADIO,
425 (radio_status == FMRADIO_PAUSED) ?
426 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
427 #else
428 if (radio_status == FMRADIO_OFF)
429 radio_start();
430 #endif
432 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
433 presets_scan(NULL);
435 fms_fix_displays(FMS_ENTER);
436 FOR_NB_SCREENS(i)
437 skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);
439 preset_set_current(preset_find(curr_freq));
440 if(radio_current_preset() != -1)
441 radio_mode = RADIO_PRESET_MODE;
443 #ifndef HAVE_NOISY_IDLE_MODE
444 cpu_idle_mode(true);
445 #endif
447 while(!done)
449 if(search_dir != 0)
451 curr_freq = step_freq(curr_freq, search_dir);
452 update_type = SKIN_REFRESH_ALL;
454 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
456 preset_set_current(preset_find(curr_freq));
457 remember_frequency();
458 end_search();
459 talk = true;
461 trigger_cpu_boost();
464 if (!update_type)
466 cancel_cpu_boost();
469 button = fms_do_button_loop(update_type>0);
471 #ifndef HAVE_NOISY_IDLE_MODE
472 if (button != ACTION_NONE)
474 cpu_idle_mode(false);
475 button_timeout = current_tick + (2*HZ);
477 #endif
478 switch(button)
480 case ACTION_FM_STOP:
481 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
482 if(audio_status() == AUDIO_STATUS_RECORD)
484 audio_stop();
486 else
487 #endif
489 done = true;
490 if(presets_have_changed())
492 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
494 presets_save();
498 update_type = SKIN_REFRESH_NON_STATIC;
499 break;
501 #ifdef FM_RECORD
502 case ACTION_FM_RECORD:
503 #ifdef FM_RECORD_DBLPRE
504 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
506 rec_lastclick = 0;
507 break;
509 if (current_tick - rec_lastclick > HZ/2)
511 rec_lastclick = current_tick;
512 break;
514 #endif /* FM_RECORD_DBLPRE */
515 #ifndef SIMULATOR
516 if(audio_status() == AUDIO_STATUS_RECORD)
518 rec_command(RECORDING_CMD_START_NEWFILE);
519 update_type = SKIN_REFRESH_ALL;
521 else
523 rec_command(RECORDING_CMD_START);
524 update_type = SKIN_REFRESH_ALL;
526 #if CONFIG_CODEC != SWCODEC
527 last_seconds = 0;
528 #endif
529 #endif /* SIMULATOR */
530 break;
531 #endif /* #ifdef FM_RECORD */
533 case ACTION_FM_EXIT:
534 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
535 if(audio_status() == AUDIO_STATUS_RECORD)
536 audio_stop();
537 #endif
538 keep_playing = true;
539 done = true;
540 if(presets_have_changed())
542 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
544 presets_save();
548 break;
550 case ACTION_STD_PREV:
551 case ACTION_STD_NEXT:
552 next_station(button == ACTION_STD_PREV ? -1 : 1);
553 end_search();
554 update_type = SKIN_REFRESH_ALL;
555 talk = true;
556 break;
558 case ACTION_STD_PREVREPEAT:
559 case ACTION_STD_NEXTREPEAT:
561 int dir = search_dir;
562 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
563 if (radio_mode != RADIO_SCAN_MODE)
565 preset_next(search_dir);
566 end_search();
567 talk = true;
569 else if (dir == 0)
571 /* Starting auto scan */
572 tuner_set(RADIO_MUTE, 1);
574 update_type = SKIN_REFRESH_ALL;
575 break;
578 case ACTION_SETTINGS_INC:
579 case ACTION_SETTINGS_INCREPEAT:
580 global_settings.volume++;
581 setvol();
582 update_type = SKIN_REFRESH_NON_STATIC;
583 break;
585 case ACTION_SETTINGS_DEC:
586 case ACTION_SETTINGS_DECREPEAT:
587 global_settings.volume--;
588 setvol();
589 update_type = SKIN_REFRESH_NON_STATIC;
590 break;
592 case ACTION_FM_PLAY:
593 if (radio_status == FMRADIO_PLAYING)
594 radio_pause();
595 else
596 radio_start();
598 update_type = SKIN_REFRESH_NON_STATIC;
599 talk = false;
600 talk_shutup();
601 break;
603 case ACTION_FM_MENU:
604 fms_fix_displays(FMS_EXIT);
605 do_menu(&radio_settings_menu, NULL, NULL, false);
606 preset_set_current(preset_find(curr_freq));
607 fms_fix_displays(FMS_ENTER);
608 update_type = SKIN_REFRESH_ALL;
609 break;
611 #ifdef FM_PRESET
612 case ACTION_FM_PRESET:
613 if(radio_preset_count() < 1)
615 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
616 update_type = SKIN_REFRESH_ALL;
617 break;
619 fms_fix_displays(FMS_EXIT);
620 handle_radio_presets();
621 fms_fix_displays(FMS_ENTER);
622 update_type = SKIN_REFRESH_ALL;
623 break;
624 #endif /* FM_PRESET */
626 #ifdef FM_FREEZE
627 case ACTION_FM_FREEZE:
628 if(!screen_freeze)
630 splash(HZ, str(LANG_FM_FREEZE));
631 screen_freeze = true;
633 else
635 update_type = SKIN_REFRESH_ALL;
636 screen_freeze = false;
638 break;
639 #endif /* FM_FREEZE */
641 case SYS_USB_CONNECTED:
642 #if CONFIG_CODEC != SWCODEC
643 /* Only accept USB connection when not recording */
644 if(audio_status() != AUDIO_STATUS_RECORD)
645 #endif
647 default_event_handler(SYS_USB_CONNECTED);
648 screen_freeze = true; /* Cosmetic: makes sure the
649 radio screen doesn't redraw */
650 done = true;
652 break;
654 #ifdef FM_MODE
655 case ACTION_FM_MODE:
656 if(radio_mode == RADIO_SCAN_MODE)
658 /* Force scan mode if there are no presets. */
659 if(radio_preset_count() > 0)
660 radio_mode = RADIO_PRESET_MODE;
662 else
663 radio_mode = RADIO_SCAN_MODE;
664 update_type = SKIN_REFRESH_ALL;
665 cond_talk_ids_fq(radio_mode ?
666 LANG_PRESET : LANG_RADIO_SCAN_MODE);
667 talk = true;
668 break;
669 #endif /* FM_MODE */
671 #ifdef FM_NEXT_PRESET
672 case ACTION_FM_NEXT_PRESET:
673 preset_next(1);
674 end_search();
675 update_type = SKIN_REFRESH_ALL;
676 talk = true;
677 break;
678 #endif
680 #ifdef FM_PREV_PRESET
681 case ACTION_FM_PREV_PRESET:
682 preset_next(-1);
683 end_search();
684 update_type = SKIN_REFRESH_ALL;
685 talk = true;
686 break;
687 #endif
688 case ACTION_NONE:
689 update_type = SKIN_REFRESH_NON_STATIC;
690 break;
692 default:
693 default_event_handler(button);
694 #ifdef HAVE_RDS_CAP
695 if (tuner_get(RADIO_EVENT))
696 update_type = SKIN_REFRESH_ALL;
697 #endif
698 if (!tuner_get(RADIO_PRESENT))
700 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
701 if(audio_status() == AUDIO_STATUS_RECORD)
702 audio_stop();
703 #endif
704 keep_playing = false;
705 done = true;
706 if(presets_have_changed())
708 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
710 radio_save_presets();
714 /* Clear the preset list on exit. */
715 preset_list_clear();
717 break;
718 } /*switch(button)*/
720 #ifdef FM_RECORD_DBLPRE
721 if (button != ACTION_NONE)
722 lastbutton = button;
723 #endif
725 #if CONFIG_CODEC != SWCODEC
726 peak_meter_peek();
727 #endif
729 if(!screen_freeze)
731 /* Only display the peak meter when not recording */
732 #if CONFIG_CODEC != SWCODEC
733 if(TIME_AFTER(current_tick, timeout))
735 timeout = current_tick + HZ;
736 #else /* SWCODEC */
738 #endif /* CONFIG_CODEC == SWCODEC */
740 /* keep "mono" from always being displayed when paused */
741 if (radio_status != FMRADIO_PAUSED)
743 stereo = tuner_get(RADIO_STEREO) &&
744 !global_settings.fm_force_mono;
746 if(stereo != last_stereo)
748 update_type = SKIN_REFRESH_ALL;
749 last_stereo = stereo;
754 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
755 seconds = audio_recorded_time() / HZ;
756 if (update_type || seconds > last_seconds)
758 last_seconds = seconds;
759 #else
760 if (update_type)
762 #endif
763 FOR_NB_SCREENS(i)
764 skin_update(FM_SCREEN, i, update_type);
767 update_type = 0;
769 if (global_settings.talk_file && talk
770 && radio_status == FMRADIO_PAUSED)
772 talk = false;
773 bool enqueue = false;
774 if (radio_mode == RADIO_SCAN_MODE)
776 talk_value_decimal(curr_freq, UNIT_INT, 6, enqueue);
777 enqueue = true;
779 if (radio_current_preset() >= 0)
780 preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
781 enqueue);
784 #if CONFIG_CODEC != SWCODEC
785 if(audio_status() & AUDIO_STATUS_ERROR)
787 done = true;
789 #endif
791 #ifndef HAVE_NOISY_IDLE_MODE
792 if (TIME_AFTER(current_tick, button_timeout))
794 cpu_idle_mode(true);
796 #endif
797 } /*while(!done)*/
799 #ifndef SIMULATOR
800 #if CONFIG_CODEC != SWCODEC
801 if(audio_status() & AUDIO_STATUS_ERROR)
803 splash(0, str(LANG_DISK_FULL));
804 audio_error_clear();
806 while(1)
808 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
809 if(button == ACTION_FM_STOP)
810 break;
814 audio_init_playback();
815 #endif /* CONFIG_CODEC != SWCODEC */
817 sound_settings_apply();
818 #endif /* SIMULATOR */
820 if(keep_playing)
822 /* Catch FMRADIO_PLAYING status for the sim. */
823 #ifndef SIMULATOR
824 #if CONFIG_CODEC != SWCODEC
825 /* Enable the Left and right A/D Converter */
826 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
827 sound_default(SOUND_RIGHT_GAIN),
828 AUDIO_GAIN_LINEIN);
829 mas_codec_writereg(6, 0x4000);
830 #endif
831 end_search();
832 #endif /* SIMULATOR */
834 else
836 #if CONFIG_CODEC == SWCODEC
837 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
838 #else
839 radio_stop();
840 #endif
843 #ifndef HAVE_NOISY_IDLE_MODE
844 cpu_idle_mode(false);
845 #endif
846 fms_fix_displays(FMS_EXIT);
847 pop_current_activity();
848 in_screen = false;
849 } /* radio_screen */
851 void toggle_mono_mode(bool mono)
853 tuner_set(RADIO_FORCE_MONO, mono);
856 void set_radio_region(int region)
858 #ifdef HAVE_RADIO_REGION
859 tuner_set(RADIO_REGION, region);
860 #endif
861 next_station(0);
862 remember_frequency();
863 (void)region;
866 #endif