Bump version numbers for 3.13
[maemo-rb.git] / apps / radio / radio.c
blob326e6a3bb02e0a1a06401af496e42d88d97cf273
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 #elif (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
131 #define FM_MENU
132 #define FM_PRESET
133 #define FM_STOP
134 #define FM_MODE
135 #define FM_EXIT
136 #define FM_PLAY
137 #define FM_PREV_PRESET
138 #define FM_NEXT_PRESET
140 #endif
142 /* presets.c needs these so keep unstatic or redo the whole thing! */
143 int curr_freq; /* current frequency in Hz */
144 int radio_mode = RADIO_SCAN_MODE;
146 static int search_dir = 0;
147 static int radio_status = FMRADIO_OFF;
148 static bool in_screen = false;
151 static void radio_off(void);
153 bool radio_scan_mode(void)
155 return radio_mode == RADIO_SCAN_MODE;
158 bool radio_is_stereo(void)
160 return tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono;
162 int radio_current_frequency(void)
164 return curr_freq;
167 void radio_init(void)
169 tuner_init();
170 radio_off();
171 #ifdef HAVE_ALBUMART
172 radioart_init(false);
173 #endif
176 int get_radio_status(void)
178 return radio_status;
181 bool in_radio_screen(void)
183 return in_screen;
186 /* TODO: Move some more of the control functionality to firmware
187 and clean up the mess */
189 /* secret flag for starting paused - prevents unmute */
190 #define FMRADIO_START_PAUSED 0x8000
191 void radio_start(void)
193 const struct fm_region_data *fmr;
194 bool start_paused;
196 if(radio_status == FMRADIO_PLAYING)
197 return;
199 fmr = &fm_region_data[global_settings.fm_region];
201 start_paused = radio_status & FMRADIO_START_PAUSED;
202 /* clear flag before any yielding */
203 radio_status &= ~FMRADIO_START_PAUSED;
205 curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min;
207 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
209 if(radio_status == FMRADIO_OFF)
211 #ifdef HAVE_RADIO_REGION
212 tuner_set(RADIO_REGION, global_settings.fm_region);
213 #endif
214 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
217 tuner_set(RADIO_FREQUENCY, curr_freq);
219 #ifdef HAVE_RADIO_MUTE_TIMEOUT
221 unsigned long mute_timeout = current_tick + HZ;
222 if (radio_status != FMRADIO_OFF)
224 /* paused */
225 mute_timeout += HZ;
228 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
230 if(TIME_AFTER(current_tick, mute_timeout))
231 break;
232 yield();
235 #endif
237 /* keep radio from sounding initially */
238 if(!start_paused)
239 tuner_set(RADIO_MUTE, 0);
241 radio_status = FMRADIO_PLAYING;
242 } /* radio_start */
244 void radio_pause(void)
246 if(radio_status == FMRADIO_PAUSED)
247 return;
249 if(radio_status == FMRADIO_OFF)
251 radio_status |= FMRADIO_START_PAUSED;
252 radio_start();
255 tuner_set(RADIO_MUTE, 1);
257 radio_status = FMRADIO_PAUSED;
258 } /* radio_pause */
260 static void radio_off(void)
262 tuner_set(RADIO_MUTE, 1);
263 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
264 radio_status = FMRADIO_OFF;
267 void radio_stop(void)
269 if(radio_status == FMRADIO_OFF)
270 return;
272 radio_off();
273 } /* radio_stop */
275 bool radio_hardware_present(void)
277 return tuner_get(RADIO_PRESENT);
280 /* Keep freq on the grid for the current region */
281 int snap_freq_to_grid(int freq)
283 const struct fm_region_data * const fmr =
284 &fm_region_data[global_settings.fm_region];
286 /* Range clamp if out of range or just round to nearest */
287 if (freq < fmr->freq_min)
288 freq = fmr->freq_min;
289 else if (freq > fmr->freq_max)
290 freq = fmr->freq_max;
291 else
292 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
293 fmr->freq_step * fmr->freq_step + fmr->freq_min;
295 return freq;
298 void remember_frequency(void)
300 const struct fm_region_data * const fmr =
301 &fm_region_data[global_settings.fm_region];
302 global_status.last_frequency = (curr_freq - fmr->freq_min)
303 / fmr->freq_step;
304 status_save();
307 /* Step to the next or previous frequency */
308 static int step_freq(int freq, int direction)
310 const struct fm_region_data * const fmr =
311 &fm_region_data[global_settings.fm_region];
313 freq += direction*fmr->freq_step;
315 /* Wrap first or snapping to grid will not let us on the band extremes */
316 if (freq > fmr->freq_max)
317 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
318 else if (freq < fmr->freq_min)
319 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
320 else
321 freq = snap_freq_to_grid(freq);
323 return freq;
326 /* Step to the next or previous station */
327 void next_station(int direction)
329 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
331 preset_next(direction);
332 return;
335 curr_freq = step_freq(curr_freq, direction);
337 if (radio_status == FMRADIO_PLAYING)
338 tuner_set(RADIO_MUTE, 1);
340 tuner_set(RADIO_FREQUENCY, curr_freq);
342 if (radio_status == FMRADIO_PLAYING)
343 tuner_set(RADIO_MUTE, 0);
345 preset_set_current(preset_find(curr_freq));
346 remember_frequency();
349 /* Ends an in-progress search */
350 static void end_search(void)
352 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
353 tuner_set(RADIO_MUTE, 0);
354 search_dir = 0;
357 void radio_screen(void)
359 bool done = false;
360 int button;
361 bool stereo = false, last_stereo = false;
362 int update_type = 0;
363 bool screen_freeze = false;
364 bool keep_playing = false;
365 bool talk = false;
366 #ifdef FM_RECORD_DBLPRE
367 int lastbutton = BUTTON_NONE;
368 unsigned long rec_lastclick = 0;
369 #endif
370 #if CONFIG_CODEC != SWCODEC
371 int timeout = current_tick + HZ/10;
372 #if !defined(SIMULATOR)
373 unsigned int last_seconds = 0;
374 unsigned int seconds = 0;
375 struct audio_recording_options rec_options;
376 #endif /* SIMULATOR */
377 #endif /* CONFIG_CODEC != SWCODEC */
378 #ifndef HAVE_NOISY_IDLE_MODE
379 int button_timeout = current_tick + (2*HZ);
380 #endif
382 /* change status to "in screen" */
383 push_current_activity(ACTIVITY_FM);
384 in_screen = true;
386 if(radio_preset_count() <= 0)
388 radio_load_presets(global_settings.fmr_file);
390 skin_get_global_state()->id3 = NULL;
391 #ifdef HAVE_ALBUMART
392 radioart_init(true);
393 #endif
395 if(radio_status == FMRADIO_OFF)
396 audio_stop();
398 #ifndef SIMULATOR
400 #if CONFIG_CODEC != SWCODEC
401 rec_create_directory();
402 audio_init_recording();
404 sound_settings_apply();
405 /* Yes, we use the D/A for monitoring */
406 peak_meter_playback(true);
408 peak_meter_enable(true);
410 rec_init_recording_options(&rec_options);
411 rec_options.rec_source = AUDIO_SRC_LINEIN;
412 rec_set_recording_options(&rec_options);
414 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
415 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
417 #endif /* CONFIG_CODEC != SWCODEC */
418 #endif /* ndef SIMULATOR */
419 /* turn on radio */
420 #if CONFIG_CODEC == SWCODEC
421 /* This should be done before touching audio settings */
422 while (!pcm_is_initialized())
423 sleep(0);
425 audio_set_input_source(AUDIO_SRC_FMRADIO,
426 (radio_status == FMRADIO_PAUSED) ?
427 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
428 #else
429 if (radio_status == FMRADIO_OFF)
430 radio_start();
431 #endif
433 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
434 presets_scan(NULL);
436 fms_fix_displays(FMS_ENTER);
437 FOR_NB_SCREENS(i)
438 skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);
440 preset_set_current(preset_find(curr_freq));
441 if(radio_current_preset() != -1)
442 radio_mode = RADIO_PRESET_MODE;
444 #ifndef HAVE_NOISY_IDLE_MODE
445 cpu_idle_mode(true);
446 #endif
448 while(!done)
450 if(search_dir != 0)
452 curr_freq = step_freq(curr_freq, search_dir);
453 update_type = SKIN_REFRESH_ALL;
455 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
457 preset_set_current(preset_find(curr_freq));
458 remember_frequency();
459 end_search();
460 talk = true;
462 trigger_cpu_boost();
465 if (!update_type)
467 cancel_cpu_boost();
470 button = fms_do_button_loop(update_type>0);
472 #ifndef HAVE_NOISY_IDLE_MODE
473 if (button != ACTION_NONE)
475 cpu_idle_mode(false);
476 button_timeout = current_tick + (2*HZ);
478 #endif
479 switch(button)
481 case ACTION_FM_STOP:
482 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
483 if(audio_status() == AUDIO_STATUS_RECORD)
485 audio_stop();
487 else
488 #endif
490 done = true;
491 if(presets_have_changed())
493 if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
495 presets_save();
499 update_type = SKIN_REFRESH_NON_STATIC;
500 break;
502 #ifdef FM_RECORD
503 case ACTION_FM_RECORD:
504 #ifdef FM_RECORD_DBLPRE
505 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
507 rec_lastclick = 0;
508 break;
510 if (current_tick - rec_lastclick > HZ/2)
512 rec_lastclick = current_tick;
513 break;
515 #endif /* FM_RECORD_DBLPRE */
516 #ifndef SIMULATOR
517 if(audio_status() == AUDIO_STATUS_RECORD)
519 rec_command(RECORDING_CMD_START_NEWFILE);
520 update_type = SKIN_REFRESH_ALL;
522 else
524 rec_command(RECORDING_CMD_START);
525 update_type = SKIN_REFRESH_ALL;
527 #if CONFIG_CODEC != SWCODEC
528 last_seconds = 0;
529 #endif
530 #endif /* SIMULATOR */
531 break;
532 #endif /* #ifdef FM_RECORD */
534 case ACTION_FM_EXIT:
535 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
536 if(audio_status() == AUDIO_STATUS_RECORD)
537 audio_stop();
538 #endif
539 keep_playing = true;
540 done = true;
541 if(presets_have_changed())
543 if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
545 presets_save();
549 break;
551 case ACTION_STD_PREV:
552 case ACTION_STD_NEXT:
553 next_station(button == ACTION_STD_PREV ? -1 : 1);
554 end_search();
555 update_type = SKIN_REFRESH_ALL;
556 talk = true;
557 break;
559 case ACTION_STD_PREVREPEAT:
560 case ACTION_STD_NEXTREPEAT:
562 int dir = search_dir;
563 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
564 if (radio_mode != RADIO_SCAN_MODE)
566 preset_next(search_dir);
567 end_search();
568 talk = true;
570 else if (dir == 0)
572 /* Starting auto scan */
573 tuner_set(RADIO_MUTE, 1);
575 update_type = SKIN_REFRESH_ALL;
576 break;
579 case ACTION_SETTINGS_INC:
580 case ACTION_SETTINGS_INCREPEAT:
581 global_settings.volume++;
582 setvol();
583 update_type = SKIN_REFRESH_NON_STATIC;
584 break;
586 case ACTION_SETTINGS_DEC:
587 case ACTION_SETTINGS_DECREPEAT:
588 global_settings.volume--;
589 setvol();
590 update_type = SKIN_REFRESH_NON_STATIC;
591 break;
593 case ACTION_FM_PLAY:
594 if (radio_status == FMRADIO_PLAYING)
595 radio_pause();
596 else
597 radio_start();
599 update_type = SKIN_REFRESH_NON_STATIC;
600 talk = false;
601 talk_shutup();
602 break;
604 case ACTION_FM_MENU:
605 fms_fix_displays(FMS_EXIT);
606 do_menu(&radio_settings_menu, NULL, NULL, false);
607 preset_set_current(preset_find(curr_freq));
608 fms_fix_displays(FMS_ENTER);
609 update_type = SKIN_REFRESH_ALL;
610 break;
612 #ifdef FM_PRESET
613 case ACTION_FM_PRESET:
614 if(radio_preset_count() < 1)
616 splash(HZ, ID2P(LANG_FM_NO_PRESETS));
617 update_type = SKIN_REFRESH_ALL;
618 break;
620 fms_fix_displays(FMS_EXIT);
621 handle_radio_presets();
622 fms_fix_displays(FMS_ENTER);
623 update_type = SKIN_REFRESH_ALL;
624 break;
625 #endif /* FM_PRESET */
627 #ifdef FM_FREEZE
628 case ACTION_FM_FREEZE:
629 if(!screen_freeze)
631 splash(HZ, str(LANG_FM_FREEZE));
632 screen_freeze = true;
634 else
636 update_type = SKIN_REFRESH_ALL;
637 screen_freeze = false;
639 break;
640 #endif /* FM_FREEZE */
642 case SYS_USB_CONNECTED:
643 #if CONFIG_CODEC != SWCODEC
644 /* Only accept USB connection when not recording */
645 if(audio_status() != AUDIO_STATUS_RECORD)
646 #endif
648 default_event_handler(SYS_USB_CONNECTED);
649 screen_freeze = true; /* Cosmetic: makes sure the
650 radio screen doesn't redraw */
651 done = true;
653 break;
655 #ifdef FM_MODE
656 case ACTION_FM_MODE:
657 if(radio_mode == RADIO_SCAN_MODE)
659 /* Force scan mode if there are no presets. */
660 if(radio_preset_count() > 0)
661 radio_mode = RADIO_PRESET_MODE;
663 else
664 radio_mode = RADIO_SCAN_MODE;
665 update_type = SKIN_REFRESH_ALL;
666 cond_talk_ids_fq(radio_mode ?
667 LANG_PRESET : LANG_RADIO_SCAN_MODE);
668 talk = true;
669 break;
670 #endif /* FM_MODE */
672 #ifdef FM_NEXT_PRESET
673 case ACTION_FM_NEXT_PRESET:
674 preset_next(1);
675 end_search();
676 update_type = SKIN_REFRESH_ALL;
677 talk = true;
678 break;
679 #endif
681 #ifdef FM_PREV_PRESET
682 case ACTION_FM_PREV_PRESET:
683 preset_next(-1);
684 end_search();
685 update_type = SKIN_REFRESH_ALL;
686 talk = true;
687 break;
688 #endif
689 case ACTION_NONE:
690 update_type = SKIN_REFRESH_NON_STATIC;
691 break;
693 default:
694 default_event_handler(button);
695 #ifdef HAVE_RDS_CAP
696 if (tuner_get(RADIO_EVENT))
697 update_type = SKIN_REFRESH_ALL;
698 #endif
699 if (!tuner_get(RADIO_PRESENT))
701 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
702 if(audio_status() == AUDIO_STATUS_RECORD)
703 audio_stop();
704 #endif
705 keep_playing = false;
706 done = true;
707 if(presets_have_changed())
709 if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
711 radio_save_presets();
715 /* Clear the preset list on exit. */
716 preset_list_clear();
718 break;
719 } /*switch(button)*/
721 #ifdef FM_RECORD_DBLPRE
722 if (button != ACTION_NONE)
723 lastbutton = button;
724 #endif
726 #if CONFIG_CODEC != SWCODEC
727 peak_meter_peek();
728 #endif
730 if(!screen_freeze)
732 /* Only display the peak meter when not recording */
733 #if CONFIG_CODEC != SWCODEC
734 if(TIME_AFTER(current_tick, timeout))
736 timeout = current_tick + HZ;
737 #else /* SWCODEC */
739 #endif /* CONFIG_CODEC == SWCODEC */
741 /* keep "mono" from always being displayed when paused */
742 if (radio_status != FMRADIO_PAUSED)
744 stereo = tuner_get(RADIO_STEREO) &&
745 !global_settings.fm_force_mono;
747 if(stereo != last_stereo)
749 update_type = SKIN_REFRESH_ALL;
750 last_stereo = stereo;
755 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
756 seconds = audio_recorded_time() / HZ;
757 if (update_type || seconds > last_seconds)
759 last_seconds = seconds;
760 #else
761 if (update_type)
763 #endif
764 FOR_NB_SCREENS(i)
765 skin_update(FM_SCREEN, i, update_type);
766 if (update_type == (int)SKIN_REFRESH_ALL)
767 skin_request_full_update(CUSTOM_STATUSBAR);
770 update_type = 0;
772 if (global_settings.talk_file && talk
773 && radio_status == FMRADIO_PAUSED)
775 talk = false;
776 bool enqueue = false;
777 if (radio_mode == RADIO_SCAN_MODE)
779 talk_value_decimal(curr_freq, UNIT_INT, 6, enqueue);
780 enqueue = true;
782 if (radio_current_preset() >= 0)
783 preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
784 enqueue);
787 #if CONFIG_CODEC != SWCODEC
788 if(audio_status() & AUDIO_STATUS_ERROR)
790 done = true;
792 #endif
794 #ifndef HAVE_NOISY_IDLE_MODE
795 if (TIME_AFTER(current_tick, button_timeout))
797 cpu_idle_mode(true);
799 #endif
800 } /*while(!done)*/
802 #ifndef SIMULATOR
803 #if CONFIG_CODEC != SWCODEC
804 if(audio_status() & AUDIO_STATUS_ERROR)
806 splash(0, str(LANG_DISK_FULL));
807 audio_error_clear();
809 while(1)
811 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
812 if(button == ACTION_FM_STOP)
813 break;
817 audio_init_playback();
818 #endif /* CONFIG_CODEC != SWCODEC */
820 sound_settings_apply();
821 #endif /* SIMULATOR */
823 if(keep_playing)
825 /* Catch FMRADIO_PLAYING status for the sim. */
826 #ifndef SIMULATOR
827 #if CONFIG_CODEC != SWCODEC
828 /* Enable the Left and right A/D Converter */
829 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
830 sound_default(SOUND_RIGHT_GAIN),
831 AUDIO_GAIN_LINEIN);
832 mas_codec_writereg(6, 0x4000);
833 #endif
834 end_search();
835 #endif /* SIMULATOR */
837 else
839 #if CONFIG_CODEC == SWCODEC
840 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
841 #else
842 radio_stop();
843 #endif
846 #ifndef HAVE_NOISY_IDLE_MODE
847 cpu_idle_mode(false);
848 #endif
849 fms_fix_displays(FMS_EXIT);
850 pop_current_activity();
851 in_screen = false;
852 } /* radio_screen */
854 void toggle_mono_mode(bool mono)
856 tuner_set(RADIO_FORCE_MONO, mono);
859 void set_radio_region(int region)
861 #ifdef HAVE_RADIO_REGION
862 tuner_set(RADIO_REGION, region);
863 #endif
864 next_station(0);
865 remember_frequency();
866 (void)region;
869 #endif