blob: 8bbaa27db239f909ed7eac0773ca4e1716f877d7 [file] [log] [blame]
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 Linus Nielsen Feltzing
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include <stdio.h>
24#include <stdbool.h>
Michael Sevakisa2ee6a62007-03-16 14:40:40 +000025#include <stdlib.h>
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +000026#include "sprintf.h"
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000027#include "mas.h"
28#include "settings.h"
29#include "button.h"
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000030#include "status.h"
Michael Sevakisa2ee6a62007-03-16 14:40:40 +000031#include "thread.h"
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000032#include "mpeg.h"
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +000033#include "audio.h"
Jörg Hohensohn881b53f2004-01-05 22:46:54 +000034#include "mp3_playback.h"
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +000035#include "ctype.h"
36#include "file.h"
37#include "errno.h"
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +000038#include "string.h"
39#include "system.h"
40#include "radio.h"
41#include "menu.h"
42#include "misc.h"
43#include "keyboard.h"
44#include "screens.h"
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +000045#include "peakmeter.h"
46#include "lang.h"
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +000047#include "font.h"
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +000048#include "sound_menu.h"
Marianne Arnoldaf97e932007-10-02 21:04:10 +000049#ifdef HAVE_RECORDING
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +000050#include "recording.h"
Marianne Arnoldaf97e932007-10-02 21:04:10 +000051#endif
Jörg Hohensohnfa97f162004-03-19 22:15:53 +000052#include "talk.h"
Jörg Hohensohn8f8fbac2004-10-15 21:41:46 +000053#include "tuner.h"
Jörg Hohensohn91f93502004-10-17 08:53:18 +000054#include "power.h"
Linus Nielsen Feltzingd2041832005-04-01 14:09:41 +000055#include "sound.h"
Anton Oleynikov697e8322005-11-13 21:03:53 +000056#include "screen_access.h"
57#include "statusbar.h"
Anton Oleynikov697e8322005-11-13 21:03:53 +000058#include "splash.h"
Anton Oleynikov0afd9712005-11-19 14:54:41 +000059#include "yesno.h"
Kevin Ferrare1a1abf22005-11-20 01:02:14 +000060#include "buttonbar.h"
Anton Oleynikovc94557e2005-11-19 19:23:44 +000061#include "power.h"
Hristo Kovachev009853f2006-04-02 12:23:08 +000062#include "tree.h"
63#include "dir.h"
Martin Scarratta9823652006-09-22 12:18:58 +000064#include "action.h"
Jonathan Gordon2816dc92007-02-27 09:06:30 +000065#include "list.h"
66#include "menus/exported_menus.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000067#include "root_menu.h"
Jonathan Gordon0501fb02008-05-29 11:13:46 +000068#include "viewport.h"
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000069
Jens Arnoldc6522182007-02-18 08:46:12 +000070#if CONFIG_TUNER
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +000071
Jörg Hohensohn120d8632004-10-10 17:12:43 +000072#if CONFIG_KEYPAD == RECORDER_PAD
Martin Scarratta9823652006-09-22 12:18:58 +000073#define FM_RECORD
74#define FM_PRESET_ADD
75#define FM_PRESET_ACTION
76#define FM_PRESET
Martin Scarratta2ac8f42006-09-23 11:05:13 +000077#define FM_MODE
Jens Arnold2a314072005-11-29 15:10:07 +000078
Linus Nielsen Feltzinga4b15a42005-12-15 01:11:19 +000079#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
Martin Scarratta9823652006-09-22 12:18:58 +000080#define FM_PRESET
Martin Scarratta2ac8f42006-09-23 11:05:13 +000081#define FM_MODE
Martin Scarratt5dc08bb2006-09-23 12:22:01 +000082#define FM_NEXT_PRESET
83#define FM_PREV_PRESET
Jens Arnold2a314072005-11-29 15:10:07 +000084
Barry Wardellc495cda2007-11-11 16:00:33 +000085#elif CONFIG_KEYPAD == IRIVER_H10_PAD
86#define FM_PRESET
87#define FM_MODE
88
Jens Arnold85a226d2007-03-16 23:02:39 +000089#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
Martin Scarratta9823652006-09-22 12:18:58 +000090#define FM_PRESET
Martin Scarratta2ac8f42006-09-23 11:05:13 +000091#define FM_MODE
Michael Sevakisa2ee6a62007-03-16 14:40:40 +000092/* This should be removeable if the whole tuning thing is sorted out since
93 proper tuning quiets the screen almost entirely in that extreme measures
94 have to be taken to hear any interference. */
95#define HAVE_NOISY_IDLE_MODE
Linus Nielsen Feltzinged4d7a32006-07-21 08:42:28 +000096
Martin Scarratta9823652006-09-22 12:18:58 +000097#elif CONFIG_KEYPAD == ONDIO_PAD
98#define FM_RECORD_DBLPRE
99#define FM_RECORD
Marianne Arnoldaf97e932007-10-02 21:04:10 +0000100#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_C200_PAD)
Michael Sevakis21a4a872007-06-06 19:23:48 +0000101#define FM_MENU
102#define FM_PRESET
103#define FM_STOP
104#define FM_MODE
105#define FM_EXIT
106#define FM_PLAY
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000107#endif
108
Anton Oleynikov697e8322005-11-13 21:03:53 +0000109#define RADIO_SCAN_MODE 0
110#define RADIO_PRESET_MODE 1
111
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000112static int curr_preset = -1;
Linus Nielsen Feltzing3e92dbe2004-07-12 13:28:44 +0000113static int curr_freq;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000114static int radio_mode = RADIO_SCAN_MODE;
Michael Sevakis62e0a512007-03-29 01:55:47 +0000115static int search_dir = 0;
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000116
Michael Sevakis0f175322007-02-08 10:36:49 +0000117static int radio_status = FMRADIO_OFF;
118static bool in_screen = false;
119
Anton Oleynikov697e8322005-11-13 21:03:53 +0000120#define MAX_PRESETS 64
Hristo Kovachev009853f2006-04-02 12:23:08 +0000121static bool presets_loaded = false, presets_changed = false;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000122static struct fmstation presets[MAX_PRESETS];
123
Hristo Kovachev009853f2006-04-02 12:23:08 +0000124static char filepreset[MAX_PATH]; /* preset filename variable */
Linus Nielsen Feltzinged100ca2003-05-04 22:58:12 +0000125
Hristo Kovachev009853f2006-04-02 12:23:08 +0000126static int num_presets = 0; /* The number of presets in the preset list */
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000127
Jens Arnold2597a132006-12-25 14:01:47 +0000128static void radio_save_presets(void);
Jonathan Gordon2816dc92007-02-27 09:06:30 +0000129static int handle_radio_presets(void);
Jens Arnold2597a132006-12-25 14:01:47 +0000130static bool radio_menu(void);
Jonathan Gordon2816dc92007-02-27 09:06:30 +0000131static int radio_add_preset(void);
132static int save_preset_list(void);
133static int load_preset_list(void);
134static int clear_preset_list(void);
Hristo Kovachev009853f2006-04-02 12:23:08 +0000135
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000136static int scan_presets(void *viewports);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000137
Hristo Kovachev009853f2006-04-02 12:23:08 +0000138/* Function to manipulate all yesno dialogues.
139 This function needs the output text as an argument. */
Nils Wallménius33c44462008-04-26 09:30:24 +0000140static bool yesno_pop(const char* text)
Hristo Kovachev009853f2006-04-02 12:23:08 +0000141{
142 int i;
Nils Wallménius33c44462008-04-26 09:30:24 +0000143 const char *lines[]={text};
144 const struct text_message message={lines, 1};
Hristo Kovachev009853f2006-04-02 12:23:08 +0000145 bool ret = (gui_syncyesno_run(&message,NULL,NULL)== YESNO_YES);
146 FOR_NB_SCREENS(i)
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000147 screens[i].clear_viewport();
Hristo Kovachev009853f2006-04-02 12:23:08 +0000148 return ret;
149}
150
Jörg Hohensohn8f8fbac2004-10-15 21:41:46 +0000151void radio_init(void)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000152{
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000153 tuner_init();
Linus Nielsen Feltzing47e87732004-11-22 06:34:14 +0000154 radio_stop();
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000155}
156
Anton Oleynikovc94557e2005-11-19 19:23:44 +0000157int get_radio_status(void)
158{
Michael Sevakis0f175322007-02-08 10:36:49 +0000159 return radio_status;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000160}
161
Michael Sevakis0f175322007-02-08 10:36:49 +0000162bool in_radio_screen(void)
163{
164 return in_screen;
165}
166
Michael Sevakis21a4a872007-06-06 19:23:48 +0000167/* TODO: Move some more of the control functionality to an HAL and clean up the
168 mess */
169
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000170/* secret flag for starting paused - prevents unmute */
171#define FMRADIO_START_PAUSED 0x8000
172void radio_start(void)
173{
Michael Sevakis7d759f62007-07-14 11:20:31 +0000174 const struct fm_region_data *fmr;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000175 bool start_paused;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000176
Michael Sevakis0f175322007-02-08 10:36:49 +0000177 if(radio_status == FMRADIO_PLAYING)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000178 return;
179
Michael Sevakis7d759f62007-07-14 11:20:31 +0000180 fmr = &fm_region_data[global_settings.fm_region];
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000181
Michael Sevakis0f175322007-02-08 10:36:49 +0000182 start_paused = radio_status & FMRADIO_START_PAUSED;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000183 /* clear flag before any yielding */
Michael Sevakis0f175322007-02-08 10:36:49 +0000184 radio_status &= ~FMRADIO_START_PAUSED;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000185
Michael Sevakis0f175322007-02-08 10:36:49 +0000186 if(radio_status == FMRADIO_OFF)
Michael Sevakis7d759f62007-07-14 11:20:31 +0000187 tuner_power(true);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000188
Jonathan Gordon228d62d2007-01-24 02:19:22 +0000189 curr_freq = global_status.last_frequency
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000190 * fmr->freq_step + fmr->freq_min;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000191
Michael Sevakis7d759f62007-07-14 11:20:31 +0000192 tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */
Michael Sevakis21a4a872007-06-06 19:23:48 +0000193
Michael Sevakis0f175322007-02-08 10:36:49 +0000194 if(radio_status == FMRADIO_OFF)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000195 {
Michael Sevakis7d759f62007-07-14 11:20:31 +0000196#ifdef HAVE_RADIO_REGION
197 tuner_set(RADIO_REGION, global_settings.fm_region);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000198#endif
Michael Sevakis7d759f62007-07-14 11:20:31 +0000199 tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000200 }
201
Michael Sevakis7d759f62007-07-14 11:20:31 +0000202 tuner_set(RADIO_FREQUENCY, curr_freq);
203
204#ifdef HAVE_RADIO_MUTE_TIMEOUT
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000205 {
Michael Sevakis7d759f62007-07-14 11:20:31 +0000206 unsigned long mute_timeout = current_tick + HZ;
207 if (radio_status != FMRADIO_OFF)
208 {
209 /* paused */
210 mute_timeout += HZ;
211 }
212
213 while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED))
214 {
215 if(TIME_AFTER(current_tick, mute_timeout))
216 break;
217 yield();
218 }
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000219 }
Michael Sevakis7d759f62007-07-14 11:20:31 +0000220#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000221
222 /* keep radio from sounding initially */
223 if(!start_paused)
Michael Sevakis7d759f62007-07-14 11:20:31 +0000224 tuner_set(RADIO_MUTE, 0);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000225
Michael Sevakis0f175322007-02-08 10:36:49 +0000226 radio_status = FMRADIO_PLAYING;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000227} /* radio_start */
228
229void radio_pause(void)
230{
Michael Sevakis0f175322007-02-08 10:36:49 +0000231 if(radio_status == FMRADIO_PAUSED)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000232 return;
233
Michael Sevakis0f175322007-02-08 10:36:49 +0000234 if(radio_status == FMRADIO_OFF)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000235 {
Michael Sevakis0f175322007-02-08 10:36:49 +0000236 radio_status |= FMRADIO_START_PAUSED;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000237 radio_start();
238 }
239
Michael Sevakis7d759f62007-07-14 11:20:31 +0000240 tuner_set(RADIO_MUTE, 1);
241 tuner_set(RADIO_SLEEP, 1);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000242
Michael Sevakis0f175322007-02-08 10:36:49 +0000243 radio_status = FMRADIO_PAUSED;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000244} /* radio_pause */
245
Linus Nielsen Feltzingaf2b7ad2003-05-09 00:14:59 +0000246void radio_stop(void)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000247{
Michael Sevakis0f175322007-02-08 10:36:49 +0000248 if(radio_status == FMRADIO_OFF)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000249 return;
250
Michael Sevakis7d759f62007-07-14 11:20:31 +0000251 tuner_set(RADIO_MUTE, 1);
252 tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */
Michael Sevakis0f175322007-02-08 10:36:49 +0000253 radio_status = FMRADIO_OFF;
Michael Sevakis7d759f62007-07-14 11:20:31 +0000254 tuner_power(false); /* status update, power off if avail. */
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000255} /* radio_stop */
Linus Nielsen Feltzingaf2b7ad2003-05-09 00:14:59 +0000256
Linus Nielsen Feltzingef8fd8e2003-12-19 01:24:02 +0000257bool radio_hardware_present(void)
258{
Michael Sevakis7d759f62007-07-14 11:20:31 +0000259 return tuner_get(RADIO_PRESENT);
Linus Nielsen Feltzingef8fd8e2003-12-19 01:24:02 +0000260}
261
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000262/* Keep freq on the grid for the current region */
263static int snap_freq_to_grid(int freq)
264{
Michael Sevakis7d759f62007-07-14 11:20:31 +0000265 const struct fm_region_data * const fmr =
266 &fm_region_data[global_settings.fm_region];
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000267
268 /* Range clamp if out of range or just round to nearest */
269 if (freq < fmr->freq_min)
270 freq = fmr->freq_min;
271 else if (freq > fmr->freq_max)
272 freq = fmr->freq_max;
273 else
274 freq = (freq - fmr->freq_min + fmr->freq_step/2) /
275 fmr->freq_step * fmr->freq_step + fmr->freq_min;
276
277 return freq;
278}
279
280/* Find a matching preset to freq */
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000281static int find_preset(int freq)
282{
283 int i;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000284 if(num_presets < 1)
285 return -1;
Linus Nielsen Feltzing8d8b8d12003-05-04 13:05:30 +0000286 for(i = 0;i < MAX_PRESETS;i++)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000287 {
Linus Nielsen Feltzing8d8b8d12003-05-04 13:05:30 +0000288 if(freq == presets[i].frequency)
289 return i;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000290 }
291
292 return -1;
293}
294
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000295/* Return the first preset encountered in the search direction with
296 wraparound. */
297static int find_closest_preset(int freq, int direction)
Anton Oleynikov697e8322005-11-13 21:03:53 +0000298{
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000299 int i;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000300
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000301 if (direction == 0) /* direction == 0 isn't really used */
302 return 0;
303
304 for (i = 0; i < MAX_PRESETS; i++)
Anton Oleynikov697e8322005-11-13 21:03:53 +0000305 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000306 int preset_frequency = presets[i].frequency;
307
308 if (preset_frequency == freq)
309 return i; /* Exact match = stop */
310 /* Stop when the preset frequency exeeds freq so that we can
311 pick the correct one based on direction */
312 if (preset_frequency > freq)
313 break;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000314 }
315
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000316 /* wrap around depending on direction */
317 if (i == 0 || i >= num_presets - 1)
318 i = direction < 0 ? num_presets - 1 : 0;
319 else if (direction < 0)
320 i--; /* use previous */
321
322 return i;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000323}
324
Linus Nielsen Feltzing3e92dbe2004-07-12 13:28:44 +0000325static void remember_frequency(void)
326{
Michael Sevakis7d759f62007-07-14 11:20:31 +0000327 const struct fm_region_data * const fmr =
328 &fm_region_data[global_settings.fm_region];
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000329 global_status.last_frequency = (curr_freq - fmr->freq_min)
330 / fmr->freq_step;
Jonathan Gordon228d62d2007-01-24 02:19:22 +0000331 status_save();
Linus Nielsen Feltzing3e92dbe2004-07-12 13:28:44 +0000332}
333
Jens Arnold2597a132006-12-25 14:01:47 +0000334static void next_preset(int direction)
Anton Oleynikov697e8322005-11-13 21:03:53 +0000335{
336 if (num_presets < 1)
337 return;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000338
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000339 if (curr_preset == -1)
340 curr_preset = find_closest_preset(curr_freq, direction);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000341 else
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000342 curr_preset = (curr_preset + direction + num_presets) % num_presets;
343
344 /* Must stay on the current grid for the region */
345 curr_freq = snap_freq_to_grid(presets[curr_preset].frequency);
346
Michael Sevakis7d759f62007-07-14 11:20:31 +0000347 tuner_set(RADIO_FREQUENCY, curr_freq);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000348 remember_frequency();
349}
350
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000351/* Step to the next or previous frequency */
352static int step_freq(int freq, int direction)
353{
Michael Sevakis7d759f62007-07-14 11:20:31 +0000354 const struct fm_region_data * const fmr =
355 &fm_region_data[global_settings.fm_region];
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000356
357 freq += direction*fmr->freq_step;
358
359 /* Wrap first or snapping to grid will not let us on the band extremes */
360 if (freq > fmr->freq_max)
361 freq = direction > 0 ? fmr->freq_min : fmr->freq_max;
362 else if (freq < fmr->freq_min)
363 freq = direction < 0 ? fmr->freq_max : fmr->freq_min;
364 else
365 freq = snap_freq_to_grid(freq);
366
367 return freq;
368}
369
370/* Step to the next or previous station */
371static void next_station(int direction)
372{
373 if (direction != 0 && radio_mode != RADIO_SCAN_MODE)
374 {
375 next_preset(direction);
376 return;
377 }
378
379 curr_freq = step_freq(curr_freq, direction);
380
381 if (radio_status == FMRADIO_PLAYING)
Michael Sevakis7d759f62007-07-14 11:20:31 +0000382 tuner_set(RADIO_MUTE, 1);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000383
Michael Sevakis7d759f62007-07-14 11:20:31 +0000384 tuner_set(RADIO_FREQUENCY, curr_freq);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000385
386 if (radio_status == FMRADIO_PLAYING)
Michael Sevakis7d759f62007-07-14 11:20:31 +0000387 tuner_set(RADIO_MUTE, 0);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000388
389 curr_preset = find_preset(curr_freq);
390 remember_frequency();
391}
Hristo Kovachev009853f2006-04-02 12:23:08 +0000392
Michael Sevakis62e0a512007-03-29 01:55:47 +0000393/* Ends an in-progress search */
394static void end_search(void)
395{
396 if (search_dir != 0 && radio_status == FMRADIO_PLAYING)
Michael Sevakis7d759f62007-07-14 11:20:31 +0000397 tuner_set(RADIO_MUTE, 0);
Michael Sevakis62e0a512007-03-29 01:55:47 +0000398 search_dir = 0;
399}
400
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000401/* Speak a frequency. */
402static void talk_freq(int freq, bool enqueue)
403{
404 freq /= 10000;
405 talk_number(freq / 100, enqueue);
406 talk_id(LANG_POINT, true);
407 talk_number(freq % 100 / 10, true);
408 if (freq % 10)
409 talk_number(freq % 10, true);
410}
411
412/* Speak a preset by number or by spelling its name, depending on settings. */
413static void talk_preset(int preset, bool fallback, bool enqueue)
414{
415 if (global_settings.talk_file == 1) /* number */
416 talk_number(preset + 1, enqueue);
417 else
418 { /* spell */
419 if(presets[preset].name[0])
420 talk_spell(presets[preset].name, enqueue);
421 else if(fallback)
422 talk_freq(presets[preset].frequency, enqueue);
423 }
424}
425
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000426int radio_screen(void)
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000427{
Linus Nielsen Feltzingef7293f2004-01-21 14:58:40 +0000428 char buf[MAX_PATH];
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000429 bool done = false;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000430 int ret_val = GO_TO_ROOT;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000431 int button;
432 int i;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000433 bool stereo = false, last_stereo = false;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000434 int fh;
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000435 int top_of_screen = 0;
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000436 bool update_screen = true;
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000437 bool screen_freeze = false;
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000438 bool keep_playing = false;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000439 bool statusbar = global_settings.statusbar;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000440 bool talk = false;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000441#ifdef FM_RECORD_DBLPRE
442 int lastbutton = BUTTON_NONE;
443 unsigned long rec_lastclick = 0;
444#endif
445#if CONFIG_CODEC != SWCODEC
446 bool have_recorded = false;
447 int timeout = current_tick + HZ/10;
448 unsigned int seconds = 0;
449 unsigned int last_seconds = 0;
450 int hours, minutes;
451 struct audio_recording_options rec_options;
452#endif /* CONFIG_CODEC != SWCODEC */
453#ifndef HAVE_NOISY_IDLE_MODE
Hristo Kovachev3de0db02006-03-07 11:49:06 +0000454 int button_timeout = current_tick + (2*HZ);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000455#endif
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000456 struct viewport vp[NB_SCREENS];
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000457#ifdef HAVE_BUTTONBAR
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000458 struct gui_buttonbar buttonbar;
459 gui_buttonbar_init(&buttonbar);
460 gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
461#endif
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000462
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000463 /* change status to "in screen" */
Michael Sevakis0f175322007-02-08 10:36:49 +0000464 in_screen = true;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000465
Anton Oleynikov697e8322005-11-13 21:03:53 +0000466 /* always display status bar in radio screen for now */
Jonathan Gordon4d238c12008-01-10 06:46:04 +0000467 global_status.statusbar_forced = statusbar?0:1;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000468 global_settings.statusbar = true;
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000469 gui_syncstatusbar_draw(&statusbars,true);
Hristo Kovachev009853f2006-04-02 12:23:08 +0000470 FOR_NB_SCREENS(i)
471 {
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000472 viewport_set_defaults(&vp[i], i);
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000473#ifdef HAVE_BUTTONBAR
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000474 if (global_settings.buttonbar)
475 vp[i].height -= BUTTONBAR_HEIGHT;
476#endif
477 screens[i].set_viewport(&vp[i]);
478 screens[i].clear_viewport();
479 screens[i].update_viewport();
Anton Oleynikov697e8322005-11-13 21:03:53 +0000480 }
Hristo Kovachev009853f2006-04-02 12:23:08 +0000481
Anton Oleynikov697e8322005-11-13 21:03:53 +0000482 fh = font_get(FONT_UI)->height;
483
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000484 /* Adjust for font size, trying to center the information vertically */
485 if(fh < 10)
486 top_of_screen = 1;
487
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000488 if(num_presets <= 0)
Hristo Kovachev009853f2006-04-02 12:23:08 +0000489 {
490 memset(presets, 0, sizeof(presets));
491 radio_load_presets(global_settings.fmr_file);
492 }
493
Michael Sevakis0f175322007-02-08 10:36:49 +0000494 if(radio_status == FMRADIO_OFF)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000495 audio_stop();
Jonathan Gordon67b32062007-03-07 09:16:20 +0000496#ifndef SIMULATOR
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000497
Jens Arnoldd6c05452005-08-29 21:15:27 +0000498#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzing3405d132004-06-04 12:34:29 +0000499 if(rec_create_directory() > 0)
500 have_recorded = true;
Linus Nielsen Feltzing8c7589b2005-08-13 17:35:02 +0000501
Peter D'Hoye67ff2622006-04-30 23:18:21 +0000502 audio_init_recording(talk_get_bufsize());
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000503
Linus Nielsen Feltzing7bade1a2004-07-06 12:17:14 +0000504 sound_settings_apply();
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000505 /* Yes, we use the D/A for monitoring */
506 peak_meter_playback(true);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000507
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000508 peak_meter_enabled = true;
509
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000510 rec_init_recording_options(&rec_options);
511 rec_options.rec_source = AUDIO_SRC_LINEIN;
512 rec_set_recording_options(&rec_options);
Jörg Hohensohnfa97f162004-03-19 22:15:53 +0000513
Jens Arnolda238ab92006-05-14 23:34:24 +0000514 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000515 sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
516
517#endif /* CONFIG_CODEC != SWCODEC */
518#endif /* ndef SIMULATOR */
519
520 /* turn on radio */
521#if CONFIG_CODEC == SWCODEC
Michael Sevakis2d48d0f2007-06-08 23:42:04 +0000522 audio_set_input_source(AUDIO_SRC_FMRADIO,
523 (radio_status == FMRADIO_PAUSED) ?
524 SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000525#else
Michael Sevakis0f175322007-02-08 10:36:49 +0000526 if (radio_status == FMRADIO_OFF)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000527 radio_start();
Linus Nielsen Feltzingafd74212004-07-02 07:43:49 +0000528#endif
Linus Nielsen Feltzing3e92dbe2004-07-12 13:28:44 +0000529
Nils Wallménius5b769362007-08-06 13:08:36 +0000530 if(num_presets < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000531 scan_presets(vp);
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000532
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000533 curr_preset = find_preset(curr_freq);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000534 if(curr_preset != -1)
535 radio_mode = RADIO_PRESET_MODE;
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000536
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000537#ifdef HAVE_BUTTONBAR
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000538 gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU),
Nils Wallméniusb3113672007-08-05 19:19:39 +0000539 str(LANG_PRESET), str(LANG_FM_BUTTONBAR_RECORD));
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000540#endif
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000541
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000542#ifndef HAVE_NOISY_IDLE_MODE
Linus Nielsen Feltzing8b9c64f2005-09-29 11:19:55 +0000543 cpu_idle_mode(true);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000544#endif
545
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000546 while(!done)
547 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000548 if(search_dir != 0)
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000549 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000550 curr_freq = step_freq(curr_freq, search_dir);
551 update_screen = true;
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000552
Michael Sevakis7d759f62007-07-14 11:20:31 +0000553 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000554 {
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000555 curr_preset = find_preset(curr_freq);
Linus Nielsen Feltzing3e92dbe2004-07-12 13:28:44 +0000556 remember_frequency();
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000557 end_search();
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000558 talk = true;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000559 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000560
561 trigger_cpu_boost();
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000562 }
563
Michael Sevakisfadbf0a2007-11-20 03:44:25 +0000564 if (!update_screen)
565 {
566 cancel_cpu_boost();
567 }
568
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000569#if CONFIG_CODEC != SWCODEC
570 /* TODO: Can we timeout at HZ when recording since peaks aren't
571 displayed? This should quiet recordings too. */
572 button = get_action(CONTEXT_FM,
573 update_screen ? TIMEOUT_NOBLOCK : HZ / PEAK_METER_FPS);
574#else
575 button = get_action(CONTEXT_FM,
576 update_screen ? TIMEOUT_NOBLOCK : HZ);
577#endif
578
579#ifndef HAVE_NOISY_IDLE_MODE
Martin Scarratta9823652006-09-22 12:18:58 +0000580 if (button != ACTION_NONE)
Hristo Kovachev3de0db02006-03-07 11:49:06 +0000581 {
582 cpu_idle_mode(false);
583 button_timeout = current_tick + (2*HZ);
584 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000585#endif
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000586 switch(button)
587 {
Martin Scarratta9823652006-09-22 12:18:58 +0000588 case ACTION_FM_STOP:
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000589#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000590 if(audio_status() == AUDIO_STATUS_RECORD)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000591 {
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000592 audio_stop();
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000593 }
594 else
Linus Nielsen Feltzingafd74212004-07-02 07:43:49 +0000595#endif
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000596 {
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000597 done = true;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000598 if(presets_changed)
599 {
Nils Wallménius5b769362007-08-06 13:08:36 +0000600 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
Hristo Kovachev009853f2006-04-02 12:23:08 +0000601 {
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000602 if(filepreset[0] == '\0')
Hristo Kovachev009853f2006-04-02 12:23:08 +0000603 save_preset_list();
604 else
605 radio_save_presets();
606 }
607 }
608 /* Clear the preset list on exit. */
609 clear_preset_list();
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000610 }
611 update_screen = true;
Linus Nielsen Feltzingaf2b7ad2003-05-09 00:14:59 +0000612 break;
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000613
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000614#ifdef FM_RECORD
Martin Scarratta9823652006-09-22 12:18:58 +0000615 case ACTION_FM_RECORD:
Jens Arnold1e0b5aa2005-09-05 19:17:23 +0000616#ifdef FM_RECORD_DBLPRE
Martin Scarratta9823652006-09-22 12:18:58 +0000617 if (lastbutton != ACTION_FM_RECORD_DBLPRE)
Jens Arnold1e0b5aa2005-09-05 19:17:23 +0000618 {
619 rec_lastclick = 0;
620 break;
621 }
622 if (current_tick - rec_lastclick > HZ/2)
623 {
624 rec_lastclick = current_tick;
625 break;
626 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000627#endif /* FM_RECORD_DBLPRE */
Linus Nielsen Feltzingafd74212004-07-02 07:43:49 +0000628#ifndef SIMULATOR
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000629 if(audio_status() == AUDIO_STATUS_RECORD)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000630 {
Peter D'Hoye583f1862007-08-25 15:53:54 +0000631 rec_command(RECORDING_CMD_START_NEWFILE);
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000632 update_screen = true;
633 }
634 else
635 {
Linus Nielsen Feltzing74976c12003-12-31 03:13:29 +0000636 have_recorded = true;
Peter D'Hoye583f1862007-08-25 15:53:54 +0000637 rec_command(RECORDING_CMD_START);
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000638 update_screen = true;
639 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000640#endif /* SIMULATOR */
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000641 last_seconds = 0;
642 break;
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000643#endif /* #ifdef FM_RECORD */
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000644
Martin Scarratta9823652006-09-22 12:18:58 +0000645 case ACTION_FM_EXIT:
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000646#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000647 if(audio_status() == AUDIO_STATUS_RECORD)
648 audio_stop();
Jens Arnold59483d62005-03-06 18:03:01 +0000649#endif
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000650 keep_playing = true;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000651 done = true;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000652 ret_val = GO_TO_ROOT;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000653 if(presets_changed)
654 {
Nils Wallménius5b769362007-08-06 13:08:36 +0000655 if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
Hristo Kovachev009853f2006-04-02 12:23:08 +0000656 {
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000657 if(filepreset[0] == '\0')
Hristo Kovachev009853f2006-04-02 12:23:08 +0000658 save_preset_list();
659 else
660 radio_save_presets();
661 }
662 }
663
664 /* Clear the preset list on exit. */
665 clear_preset_list();
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000666
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000667 break;
Martin Scarratta9823652006-09-22 12:18:58 +0000668
669 case ACTION_STD_PREV:
Martin Scarratta9823652006-09-22 12:18:58 +0000670 case ACTION_STD_NEXT:
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000671 next_station(button == ACTION_STD_PREV ? -1 : 1);
672 end_search();
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000673 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000674 talk = true;
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000675 break;
676
Martin Scarratta9823652006-09-22 12:18:58 +0000677 case ACTION_STD_PREVREPEAT:
Martin Scarratta9823652006-09-22 12:18:58 +0000678 case ACTION_STD_NEXTREPEAT:
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000679 {
680 int dir = search_dir;
681 search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
682 if (radio_mode != RADIO_SCAN_MODE)
Hristo Kovachev009853f2006-04-02 12:23:08 +0000683 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000684 next_preset(search_dir);
685 end_search();
Hristo Kovachev009853f2006-04-02 12:23:08 +0000686 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000687 talk = true;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000688 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000689 else if (dir == 0)
690 {
691 /* Starting auto scan */
Michael Sevakis7d759f62007-07-14 11:20:31 +0000692 tuner_set(RADIO_MUTE, 1);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000693 update_screen = true;
694 }
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000695 break;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000696 }
Martin Scarratta9823652006-09-22 12:18:58 +0000697
698 case ACTION_SETTINGS_INC:
699 case ACTION_SETTINGS_INCREPEAT:
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000700 global_settings.volume++;
Nils Wallméniusf46657e2007-05-30 17:57:32 +0000701 setvol();
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000702 update_screen = true;
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000703 break;
704
Martin Scarratta9823652006-09-22 12:18:58 +0000705 case ACTION_SETTINGS_DEC:
706 case ACTION_SETTINGS_DECREPEAT:
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000707 global_settings.volume--;
Nils Wallméniusf46657e2007-05-30 17:57:32 +0000708 setvol();
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000709 update_screen = true;
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +0000710 break;
711
Martin Scarratta9823652006-09-22 12:18:58 +0000712 case ACTION_FM_PLAY:
Michael Sevakis0f175322007-02-08 10:36:49 +0000713 if (radio_status == FMRADIO_PLAYING)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000714 radio_pause();
Anton Oleynikov697e8322005-11-13 21:03:53 +0000715 else
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000716 radio_start();
717
Anton Oleynikov697e8322005-11-13 21:03:53 +0000718 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000719 talk = false;
720 talk_shutup();
Anton Oleynikov697e8322005-11-13 21:03:53 +0000721 break;
Martin Scarratta9823652006-09-22 12:18:58 +0000722
723 case ACTION_FM_MENU:
Linus Nielsen Feltzingaf2b7ad2003-05-09 00:14:59 +0000724 radio_menu();
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000725 curr_preset = find_preset(curr_freq);
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000726 FOR_NB_SCREENS(i)
727 {
728 screens[i].set_viewport(&vp[i]);
729 screens[i].clear_viewport();
730 screens[i].update_viewport();
731 screens[i].set_viewport(NULL);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000732 }
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000733#ifdef HAVE_BUTTONBAR
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000734 gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU),
Nils Wallméniusb3113672007-08-05 19:19:39 +0000735 str(LANG_PRESET),
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000736 str(LANG_FM_BUTTONBAR_RECORD));
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000737#endif
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000738 update_screen = true;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000739 break;
Martin Scarratta9823652006-09-22 12:18:58 +0000740
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000741#ifdef FM_PRESET
Martin Scarratta9823652006-09-22 12:18:58 +0000742 case ACTION_FM_PRESET:
Hristo Kovachev009853f2006-04-02 12:23:08 +0000743 if(num_presets < 1)
744 {
Nils Wallménius5b769362007-08-06 13:08:36 +0000745 gui_syncsplash(HZ, ID2P(LANG_FM_NO_PRESETS));
Anton Oleynikovd79f3a12005-11-16 23:36:35 +0000746 update_screen = true;
Hristo Kovachev009853f2006-04-02 12:23:08 +0000747 FOR_NB_SCREENS(i)
748 {
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000749 screens[i].set_viewport(&vp[i]);
750 screens[i].clear_viewport();
751 screens[i].update_viewport();
752 screens[i].set_viewport(NULL);
Hristo Kovachev009853f2006-04-02 12:23:08 +0000753 }
754
Anton Oleynikovd79f3a12005-11-16 23:36:35 +0000755 break;
756 }
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000757 handle_radio_presets();
Hristo Kovachev009853f2006-04-02 12:23:08 +0000758 FOR_NB_SCREENS(i)
759 {
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000760 screens[i].set_viewport(&vp[i]);
761 screens[i].clear_viewport();
762 screens[i].update_viewport();
763 screens[i].set_viewport(NULL);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000764 }
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000765#ifdef HAVE_BUTTONBAR
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000766 gui_buttonbar_set(&buttonbar,
767 str(LANG_BUTTONBAR_MENU),
Nils Wallméniusb3113672007-08-05 19:19:39 +0000768 str(LANG_PRESET),
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000769 str(LANG_FM_BUTTONBAR_RECORD));
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000770#endif
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000771 update_screen = true;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000772 break;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000773#endif /* FM_PRESET */
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000774
Jörg Hohensohn120d8632004-10-10 17:12:43 +0000775#ifdef FM_FREEZE
Martin Scarratta9823652006-09-22 12:18:58 +0000776 case ACTION_FM_FREEZE:
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000777 if(!screen_freeze)
778 {
Jens Arnold4d6374c2007-03-16 21:56:08 +0000779 gui_syncsplash(HZ, str(LANG_FM_FREEZE));
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000780 screen_freeze = true;
781 }
782 else
783 {
784 update_screen = true;
785 screen_freeze = false;
786 }
787 break;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000788#endif /* FM_FREEZE */
789
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +0000790 case SYS_USB_CONNECTED:
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000791#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000792 /* Only accept USB connection when not recording */
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000793 if(audio_status() != AUDIO_STATUS_RECORD)
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000794#endif
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000795 {
Linus Nielsen Feltzingade5d7b2004-07-26 16:06:59 +0000796 default_event_handler(SYS_USB_CONNECTED);
Linus Nielsen Feltzing74976c12003-12-31 03:13:29 +0000797 screen_freeze = true; /* Cosmetic: makes sure the
798 radio screen doesn't redraw */
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000799 done = true;
800 }
801 break;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000802
Anton Oleynikov697e8322005-11-13 21:03:53 +0000803#ifdef FM_MODE
Martin Scarratta9823652006-09-22 12:18:58 +0000804 case ACTION_FM_MODE:
805 if(radio_mode == RADIO_SCAN_MODE)
Anton Oleynikov697e8322005-11-13 21:03:53 +0000806 {
Martin Scarratta9823652006-09-22 12:18:58 +0000807 /* Force scan mode if there are no presets. */
808 if(num_presets > 0)
809 radio_mode = RADIO_PRESET_MODE;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000810 }
Martin Scarratta9823652006-09-22 12:18:58 +0000811 else
812 radio_mode = RADIO_SCAN_MODE;
813 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000814 cond_talk_ids_fq(radio_mode ?
815 LANG_PRESET : LANG_RADIO_SCAN_MODE);
816 talk = true;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000817 break;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000818#endif /* FM_MODE */
819
Anton Oleynikov697e8322005-11-13 21:03:53 +0000820#ifdef FM_NEXT_PRESET
Martin Scarratta9823652006-09-22 12:18:58 +0000821 case ACTION_FM_NEXT_PRESET:
Anton Oleynikov697e8322005-11-13 21:03:53 +0000822 next_preset(1);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000823 end_search();
Anton Oleynikov697e8322005-11-13 21:03:53 +0000824 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000825 talk = true;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000826 break;
827#endif
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000828
Anton Oleynikov697e8322005-11-13 21:03:53 +0000829#ifdef FM_PREV_PRESET
Martin Scarratta9823652006-09-22 12:18:58 +0000830 case ACTION_FM_PREV_PRESET:
Anton Oleynikov697e8322005-11-13 21:03:53 +0000831 next_preset(-1);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000832 end_search();
Anton Oleynikov697e8322005-11-13 21:03:53 +0000833 update_screen = true;
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000834 talk = true;
Anton Oleynikov697e8322005-11-13 21:03:53 +0000835 break;
836#endif
Linus Nielsen Feltzingade5d7b2004-07-26 16:06:59 +0000837
838 default:
839 default_event_handler(button);
840 break;
Hristo Kovachev3de0db02006-03-07 11:49:06 +0000841 } /*switch(button)*/
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000842
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000843#ifdef FM_RECORD_DBLPRE
Martin Scarratta9823652006-09-22 12:18:58 +0000844 if (button != ACTION_NONE)
Linus Nielsen Feltzing8c7589b2005-08-13 17:35:02 +0000845 lastbutton = button;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000846#endif
Martin Scarratta9823652006-09-22 12:18:58 +0000847
Peter D'Hoyec7838b82006-03-03 19:41:16 +0000848#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000849 peak_meter_peek();
Peter D'Hoyec7838b82006-03-03 19:41:16 +0000850#endif
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000851
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000852 if(!screen_freeze)
Anton Oleynikov697e8322005-11-13 21:03:53 +0000853 {
Linus Nielsen Feltzing74976c12003-12-31 03:13:29 +0000854 /* Only display the peak meter when not recording */
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000855#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000856 if(!audio_status())
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000857 {
Dan Evertonb66477a2006-03-25 13:35:31 +0000858 FOR_NB_SCREENS(i)
859 {
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000860 screens[i].set_viewport(&vp[i]);
Dan Evertonb66477a2006-03-25 13:35:31 +0000861 peak_meter_screen(&screens[i],0,
862 STATUSBAR_HEIGHT + fh*(top_of_screen + 4), fh);
863 screens[i].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000864 screens[i].width, fh);
865 screens[i].set_viewport(NULL);
Dan Evertonb66477a2006-03-25 13:35:31 +0000866 }
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000867 }
Jens Arnold99a05982005-08-29 20:07:17 +0000868
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000869 if(TIME_AFTER(current_tick, timeout))
870 {
871 timeout = current_tick + HZ;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000872#else /* SWCODEC */
873 {
874#endif /* CONFIG_CODEC == SWCODEC */
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000875
876 /* keep "mono" from always being displayed when paused */
Michael Sevakis0f175322007-02-08 10:36:49 +0000877 if (radio_status != FMRADIO_PAUSED)
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000878 {
Michael Sevakis7d759f62007-07-14 11:20:31 +0000879 stereo = tuner_get(RADIO_STEREO) &&
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000880 !global_settings.fm_force_mono;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000881
882 if(stereo != last_stereo)
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000883 {
884 update_screen = true;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000885 last_stereo = stereo;
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000886 }
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000887 }
888 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000889
890#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
Andye6e54962005-11-12 04:00:56 +0000891 seconds = audio_recorded_time() / HZ;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000892 if (update_screen || seconds > last_seconds)
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000893 {
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000894 last_seconds = seconds;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000895#else
896 if (update_screen)
897 {
898#endif
899 int freq;
Jens Arnold2a314072005-11-29 15:10:07 +0000900
Anton Oleynikov697e8322005-11-13 21:03:53 +0000901 FOR_NB_SCREENS(i)
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000902 {
903 screens[i].set_viewport(&vp[i]);
904 }
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000905
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000906 snprintf(buf, 128, curr_preset >= 0 ? "%d. %s" : " ",
907 curr_preset + 1, presets[curr_preset].name);
908
Anton Oleynikov697e8322005-11-13 21:03:53 +0000909 FOR_NB_SCREENS(i)
910 screens[i].puts_scroll(0, top_of_screen, buf);
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000911
Dominik Riebelinge66b2ec2006-10-05 12:40:13 +0000912 freq = curr_freq / 10000;
913 snprintf(buf, 128, str(LANG_FM_STATION), freq / 100, freq % 100);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000914 FOR_NB_SCREENS(i)
915 screens[i].puts_scroll(0, top_of_screen + 1, buf);
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000916
Anton Oleynikov697e8322005-11-13 21:03:53 +0000917 snprintf(buf, 128, stereo?str(LANG_CHANNEL_STEREO):
918 str(LANG_CHANNEL_MONO));
919 FOR_NB_SCREENS(i)
920 screens[i].puts_scroll(0, top_of_screen + 2, buf);
921
Nils Wallméniusb3113672007-08-05 19:19:39 +0000922 snprintf(buf, 128, "%s %s", str(LANG_MODE),
923 radio_mode ? str(LANG_PRESET) :
Jens Arnold2a314072005-11-29 15:10:07 +0000924 str(LANG_RADIO_SCAN_MODE));
Anton Oleynikov697e8322005-11-13 21:03:53 +0000925 FOR_NB_SCREENS(i)
926 screens[i].puts_scroll(0, top_of_screen + 3, buf);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000927
Peter D'Hoyec7838b82006-03-03 19:41:16 +0000928#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000929 if(audio_status() == AUDIO_STATUS_RECORD)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000930 {
931 hours = seconds / 3600;
932 minutes = (seconds - (hours * 3600)) / 60;
933 snprintf(buf, 32, "%s %02d:%02d:%02d",
934 str(LANG_RECORDING_TIME),
935 hours, minutes, seconds%60);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000936 FOR_NB_SCREENS(i)
937 screens[i].puts_scroll(0, top_of_screen + 4, buf);
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000938 }
Linus Nielsen Feltzing74976c12003-12-31 03:13:29 +0000939 else
940 {
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000941 if(rec_options.rec_prerecord_time)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000942 {
943 snprintf(buf, 32, "%s %02d",
944 str(LANG_RECORD_PRERECORD), seconds%60);
Anton Oleynikov697e8322005-11-13 21:03:53 +0000945 FOR_NB_SCREENS(i)
946 screens[i].puts_scroll(0, top_of_screen + 4, buf);
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +0000947 }
Linus Nielsen Feltzing74976c12003-12-31 03:13:29 +0000948 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000949#endif /* CONFIG_CODEC != SWCODEC */
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000950
Jonathan Gordon0501fb02008-05-29 11:13:46 +0000951 FOR_NB_SCREENS(i)
952 {
953 screens[i].update_viewport();
954 screens[i].set_viewport(NULL);
955 }
956
Peter D'Hoyef76122f2008-05-29 20:32:39 +0000957#ifdef HAVE_BUTTONBAR
Kevin Ferrare1a1abf22005-11-20 01:02:14 +0000958 gui_buttonbar_draw(&buttonbar);
959#endif
Linus Nielsen Feltzing9e957572003-11-06 00:47:47 +0000960 }
Jens Arnoldae45d972004-12-26 18:36:48 +0000961 /* Only force the redraw if update_screen is true */
Anton Oleynikov697e8322005-11-13 21:03:53 +0000962 gui_syncstatusbar_draw(&statusbars,true);
Linus Nielsen Feltzingf13410a2003-11-05 09:46:08 +0000963 }
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000964
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000965 update_screen = false;
966
Stéphane Doyond65f9f12007-11-07 02:14:28 +0000967 if (global_settings.talk_file && talk
968 && radio_status == FMRADIO_PAUSED)
969 {
970 talk = false;
971 bool enqueue = false;
972 if (radio_mode == RADIO_SCAN_MODE)
973 {
974 talk_freq(curr_freq, enqueue);
975 enqueue = true;
976 }
977 if (curr_preset >= 0)
978 talk_preset(curr_preset, radio_mode == RADIO_PRESET_MODE,
979 enqueue);
980 }
981
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000982#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000983 if(audio_status() & AUDIO_STATUS_ERROR)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +0000984 {
985 done = true;
986 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000987#endif
988
989#ifndef HAVE_NOISY_IDLE_MODE
Hristo Kovachev3de0db02006-03-07 11:49:06 +0000990 if (TIME_AFTER(current_tick, button_timeout))
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000991 {
992 cpu_idle_mode(true);
993 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000994#endif
Hristo Kovachev3de0db02006-03-07 11:49:06 +0000995 } /*while(!done)*/
Linus Nielsen Feltzing23b0fda2003-05-03 15:39:40 +0000996
Linus Nielsen Feltzingafd74212004-07-02 07:43:49 +0000997#ifndef SIMULATOR
Michael Sevakisa2ee6a62007-03-16 14:40:40 +0000998#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +0000999 if(audio_status() & AUDIO_STATUS_ERROR)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001000 {
Jens Arnold4d6374c2007-03-16 21:56:08 +00001001 gui_syncsplash(0, str(LANG_DISK_FULL));
Anton Oleynikov697e8322005-11-13 21:03:53 +00001002 gui_syncstatusbar_draw(&statusbars,true);
1003 FOR_NB_SCREENS(i)
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001004 {
1005 screens[i].set_viewport(&vp[i]);
1006 screens[i].update_viewport();
1007 screens[i].set_viewport(NULL);
1008 }
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +00001009 audio_error_clear();
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001010
1011 while(1)
1012 {
Martin Scarratta9823652006-09-22 12:18:58 +00001013 button = get_action(CONTEXT_FM, TIMEOUT_BLOCK);
Martin Scarratt3bf676e2006-09-25 19:59:37 +00001014 if(button == ACTION_FM_STOP)
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001015 break;
1016 }
1017 }
1018
Linus Nielsen Feltzinge1f70582005-04-04 12:36:06 +00001019 audio_init_playback();
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001020#endif /* CONFIG_CODEC != SWCODEC */
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001021
Linus Nielsen Feltzing7bade1a2004-07-06 12:17:14 +00001022 sound_settings_apply();
Hristo Kovachev009853f2006-04-02 12:23:08 +00001023#endif /* SIMULATOR */
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001024
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001025 if(keep_playing)
1026 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001027/* Catch FMRADIO_PLAYING status for the sim. */
Hristo Kovachev009853f2006-04-02 12:23:08 +00001028#ifndef SIMULATOR
Jens Arnoldd6c05452005-08-29 21:15:27 +00001029#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001030 /* Enable the Left and right A/D Converter */
Andye6e54962005-11-12 04:00:56 +00001031 audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001032 sound_default(SOUND_RIGHT_GAIN),
1033 AUDIO_GAIN_LINEIN);
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001034 mas_codec_writereg(6, 0x4000);
Linus Nielsen Feltzing8c7589b2005-08-13 17:35:02 +00001035#endif
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001036 end_search();
1037#endif /* SIMULATOR */
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001038 }
Jörg Hohensohnef8d5082004-10-19 08:20:38 +00001039 else
1040 {
Jens Arnoldd6c05452005-08-29 21:15:27 +00001041#if CONFIG_CODEC == SWCODEC
Michael Sevakis2d48d0f2007-06-08 23:42:04 +00001042 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001043#else
1044 radio_stop();
Linus Nielsen Feltzing8c7589b2005-08-13 17:35:02 +00001045#endif
Jörg Hohensohnef8d5082004-10-19 08:20:38 +00001046 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001047
1048#ifndef HAVE_NOISY_IDLE_MODE
Linus Nielsen Feltzing8b9c64f2005-09-29 11:19:55 +00001049 cpu_idle_mode(false);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001050#endif
Anton Oleynikov697e8322005-11-13 21:03:53 +00001051
1052 /* restore status bar settings */
1053 global_settings.statusbar = statusbar;
Jonathan Gordon4d238c12008-01-10 06:46:04 +00001054 global_status.statusbar_forced = 0;
Michael Sevakis0f175322007-02-08 10:36:49 +00001055 in_screen = false;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001056#if CONFIG_CODEC != SWCODEC
Linus Nielsen Feltzingaaa99e72003-11-20 00:33:43 +00001057 return have_recorded;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001058#else
1059 return false;
1060#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001061} /* radio_screen */
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001062
Jens Arnold2597a132006-12-25 14:01:47 +00001063static void radio_save_presets(void)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001064{
1065 int fd;
1066 int i;
Hristo Kovachev009853f2006-04-02 12:23:08 +00001067
Jens Arnold67eb1542007-02-01 23:08:15 +00001068 fd = creat(filepreset);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001069 if(fd >= 0)
1070 {
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001071 for(i = 0;i < num_presets;i++)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001072 {
Daniel Stenberg6610f8e2005-02-22 12:48:36 +00001073 fdprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001074 }
1075 close(fd);
Hristo Kovachev009853f2006-04-02 12:23:08 +00001076
1077 if(!strncasecmp(FMPRESET_PATH, filepreset, strlen(FMPRESET_PATH)))
1078 set_file(filepreset, global_settings.fmr_file, MAX_FILENAME);
1079 presets_changed = false;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001080 }
1081 else
1082 {
Nils Wallménius5b769362007-08-06 13:08:36 +00001083 gui_syncsplash(HZ, ID2P(LANG_FM_PRESET_SAVE_FAILED));
Hristo Kovachev009853f2006-04-02 12:23:08 +00001084 }
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001085}
1086
Hristo Kovachev009853f2006-04-02 12:23:08 +00001087void radio_load_presets(char *filename)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001088{
1089 int fd;
1090 int rc;
1091 char buf[128];
1092 char *freq;
1093 char *name;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001094 bool done = false;
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001095 int f;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001096
Hristo Kovachev009853f2006-04-02 12:23:08 +00001097 memset(presets, 0, sizeof(presets));
1098 num_presets = 0;
1099
1100/* No Preset in configuration. */
1101 if(filename[0] == '\0')
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001102 {
Hristo Kovachev009853f2006-04-02 12:23:08 +00001103 filepreset[0] = '\0';
1104 return;
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001105 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001106/* Temporary preset, loaded until player shuts down. */
1107 else if(filename[0] == '/')
1108 strncpy(filepreset, filename, sizeof(filepreset));
1109/* Preset from default directory. */
1110 else
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001111 snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
Hristo Kovachev009853f2006-04-02 12:23:08 +00001112 FMPRESET_PATH, filename);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001113
Hristo Kovachev009853f2006-04-02 12:23:08 +00001114 fd = open(filepreset, O_RDONLY);
1115 if(fd >= 0)
1116 {
1117 while(!done && num_presets < MAX_PRESETS)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001118 {
Hristo Kovachev009853f2006-04-02 12:23:08 +00001119 rc = read_line(fd, buf, 128);
1120 if(rc > 0)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001121 {
Hristo Kovachev009853f2006-04-02 12:23:08 +00001122 if(settings_parseline(buf, &freq, &name))
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001123 {
Hristo Kovachev009853f2006-04-02 12:23:08 +00001124 f = atoi(freq);
1125 if(f) /* For backwards compatibility */
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001126 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001127 struct fmstation * const fms = &presets[num_presets];
1128 fms->frequency = f;
1129 strncpy(fms->name, name, MAX_FMPRESET_LEN);
1130 fms->name[MAX_FMPRESET_LEN] = '\0';
Hristo Kovachev009853f2006-04-02 12:23:08 +00001131 num_presets++;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001132 }
1133 }
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001134 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001135 else
1136 done = true;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001137 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001138 close(fd);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001139 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001140 else /* invalid file name? */
1141 filepreset[0] = '\0';
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001142
1143 presets_loaded = num_presets > 0;
Hristo Kovachev009853f2006-04-02 12:23:08 +00001144 presets_changed = false;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001145}
1146
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001147
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001148static int radio_add_preset(void)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001149{
Magnus Holmgrena9675232007-05-05 12:06:35 +00001150 char buf[MAX_FMPRESET_LEN + 1];
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001151
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001152 if(num_presets < MAX_PRESETS)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001153 {
Hristo Kovachevf709ad72006-04-03 10:06:39 +00001154 memset(buf, 0, MAX_FMPRESET_LEN);
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001155
Hristo Kovachevf709ad72006-04-03 10:06:39 +00001156 if (!kbd_input(buf, MAX_FMPRESET_LEN))
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001157 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001158 struct fmstation * const fms = &presets[num_presets];
1159 buf[MAX_FMPRESET_LEN] = '\0';
1160 strcpy(fms->name, buf);
1161 fms->frequency = curr_freq;
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001162 num_presets++;
Hristo Kovachev009853f2006-04-02 12:23:08 +00001163 presets_changed = true;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001164 presets_loaded = num_presets > 0;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001165 }
1166 }
1167 else
1168 {
Nils Wallménius5b769362007-08-06 13:08:36 +00001169 gui_syncsplash(HZ, ID2P(LANG_FM_NO_FREE_PRESETS));
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001170 }
1171 return true;
1172}
1173
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001174/* needed to know which preset we are edit/delete-ing */
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001175static int selected_preset = -1;
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001176static int radio_edit_preset(void)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001177{
Peter D'Hoyed3f10702007-06-04 21:38:23 +00001178 char buf[MAX_FMPRESET_LEN + 1];
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001179
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001180 if (num_presets > 0)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001181 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001182 struct fmstation * const fms = &presets[selected_preset];
1183
1184 strncpy(buf, fms->name, MAX_FMPRESET_LEN);
1185
1186 if (!kbd_input(buf, MAX_FMPRESET_LEN))
1187 {
1188 buf[MAX_FMPRESET_LEN] = '\0';
1189 strcpy(fms->name, buf);
1190 presets_changed = true;
1191 }
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001192 }
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001193
Jonathan Gordondd40a2e2007-03-18 07:57:36 +00001194 return 1;
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001195}
1196
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001197static int radio_delete_preset(void)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001198{
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001199 if (num_presets > 0)
1200 {
1201 struct fmstation * const fms = &presets[selected_preset];
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001202
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001203 if (selected_preset >= --num_presets)
1204 selected_preset = num_presets - 1;
1205
1206 memmove(fms, fms + 1, (uintptr_t)(fms + num_presets) -
1207 (uintptr_t)fms);
1208
1209 }
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001210
Hristo Kovachev009853f2006-04-02 12:23:08 +00001211 /* Don't ask to save when all presets are deleted. */
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001212 presets_changed = num_presets > 0;
1213
1214 if (!presets_changed)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001215 {
Hristo Kovachev009853f2006-04-02 12:23:08 +00001216 /* The preset list will be cleared, switch to Scan Mode. */
1217 radio_mode = RADIO_SCAN_MODE;
1218 presets_loaded = false;
1219 }
1220
Jonathan Gordondd40a2e2007-03-18 07:57:36 +00001221 return 1;
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001222}
1223
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001224static int load_preset_list(void)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001225{
1226 return !rockbox_browse(FMPRESET_PATH, SHOW_FMR);
1227}
1228
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001229static int save_preset_list(void)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001230{
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001231 if(num_presets > 0)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001232 {
Peter D'Hoyeab90b1d2006-04-25 00:14:21 +00001233 bool bad_file_name = true;
1234
Nils Wallméniusa0199642008-04-16 19:51:43 +00001235 if(!dir_exists(FMPRESET_PATH)) /* Check if there is preset folder */
1236 mkdir(FMPRESET_PATH);
1237
Michael Sevakis0f5cb942006-11-06 18:07:30 +00001238 create_numbered_filename(filepreset, FMPRESET_PATH, "preset",
1239 ".fmr", 2 IF_CNFN_NUM_(, NULL));
Peter D'Hoyeab90b1d2006-04-25 00:14:21 +00001240
1241 while(bad_file_name)
1242 {
1243 if(!kbd_input(filepreset, sizeof(filepreset)))
1244 {
1245 /* check the name: max MAX_FILENAME (20) chars */
1246 char* p2;
1247 char* p1;
1248 int len;
1249 p1 = strrchr(filepreset, '/');
1250 p2 = p1;
1251 while((p1) && (*p2) && (*p2 != '.'))
1252 p2++;
1253 len = (int)(p2-p1) - 1;
1254 if((!p1) || (len > MAX_FILENAME) || (len == 0))
1255 {
1256 /* no slash, too long or too short */
Nils Wallménius5b769362007-08-06 13:08:36 +00001257 gui_syncsplash(HZ, ID2P(LANG_INVALID_FILENAME));
Peter D'Hoyeab90b1d2006-04-25 00:14:21 +00001258 }
1259 else
1260 {
1261 /* add correct extension (easier to always write)
1262 at this point, p2 points to 0 or the extension dot */
1263 *p2 = '\0';
1264 strcat(filepreset,".fmr");
1265 bad_file_name = false;
1266 radio_save_presets();
1267 }
1268 }
1269 else
1270 {
1271 /* user aborted */
1272 return false;
1273 }
1274 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001275 }
1276 else
Nils Wallménius5b769362007-08-06 13:08:36 +00001277 gui_syncsplash(HZ, ID2P(LANG_FM_NO_PRESETS));
Hristo Kovachev009853f2006-04-02 12:23:08 +00001278
1279 return true;
1280}
1281
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001282static int clear_preset_list(void)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001283{
Hristo Kovachev009853f2006-04-02 12:23:08 +00001284 /* Clear all the preset entries */
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001285 memset(presets, 0, sizeof (presets));
Hristo Kovachev009853f2006-04-02 12:23:08 +00001286
1287 num_presets = 0;
1288 presets_loaded = false;
1289 /* The preset list will be cleared switch to Scan Mode. */
1290 radio_mode = RADIO_SCAN_MODE;
1291
1292 presets_changed = false; /* Don't ask to save when clearing the list. */
1293
1294 return true;
1295}
1296
Jonathan Gordondd40a2e2007-03-18 07:57:36 +00001297MENUITEM_FUNCTION(radio_edit_preset_item, MENU_FUNC_CHECK_RETVAL,
Jonathan Gordondaf66942007-03-17 12:33:34 +00001298 ID2P(LANG_FM_EDIT_PRESET),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001299 radio_edit_preset, NULL, NULL, Icon_NOICON);
Jonathan Gordondd40a2e2007-03-18 07:57:36 +00001300MENUITEM_FUNCTION(radio_delete_preset_item, MENU_FUNC_CHECK_RETVAL,
Jonathan Gordondaf66942007-03-17 12:33:34 +00001301 ID2P(LANG_FM_DELETE_PRESET),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001302 radio_delete_preset, NULL, NULL, Icon_NOICON);
Bertrik Sikkene15f8a22008-05-03 08:35:14 +00001303static int radio_preset_callback(int action,
1304 const struct menu_item_ex *this_item)
Jonathan Gordon9144be52007-02-27 09:16:47 +00001305{
Jonathan Gordon9144be52007-02-27 09:16:47 +00001306 if (action == ACTION_STD_OK)
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001307 action = ACTION_EXIT_AFTER_THIS_MENUITEM;
Jonathan Gordon9144be52007-02-27 09:16:47 +00001308 return action;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001309 (void)this_item;
Jonathan Gordon9144be52007-02-27 09:16:47 +00001310}
Nils Wallméniusb3113672007-08-05 19:19:39 +00001311MAKE_MENU(handle_radio_preset_menu, ID2P(LANG_PRESET),
Jonathan Gordon02a87172007-03-03 13:52:14 +00001312 radio_preset_callback, Icon_NOICON, &radio_edit_preset_item,
Jonathan Gordon9144be52007-02-27 09:16:47 +00001313 &radio_delete_preset_item);
Jörg Hohensohnc100a422004-10-19 22:50:34 +00001314/* present a list of preset stations */
Nils Wallménius68489612008-04-09 15:25:17 +00001315static char * presets_get_name(int selected_item, void *data,
1316 char *buffer, size_t buffer_len)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001317{
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001318 (void)data;
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001319 struct fmstation *p = &presets[selected_item];
1320 if(p->name[0])
1321 return p->name;
1322 int freq = p->frequency / 10000;
1323 int frac = freq % 100;
1324 freq /= 100;
Nils Wallménius68489612008-04-09 15:25:17 +00001325 snprintf(buffer, buffer_len,
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001326 str(LANG_FM_DEFAULT_PRESET_NAME), freq, frac);
1327 return buffer;
1328}
1329
1330static int presets_speak_name(int selected_item, void * data)
1331{
1332 (void)data;
1333 talk_preset(selected_item, true, false);
1334 return 0;
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001335}
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001336
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001337static int handle_radio_presets(void)
1338{
1339 struct gui_synclist lists;
1340 int result = 0;
1341 int action = ACTION_NONE;
Peter D'Hoyef76122f2008-05-29 20:32:39 +00001342#ifdef HAVE_BUTTONBAR
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001343 struct gui_buttonbar buttonbar;
1344#endif
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001345
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001346 if(presets_loaded == false)
1347 return result;
1348
Peter D'Hoyef76122f2008-05-29 20:32:39 +00001349#ifdef HAVE_BUTTONBAR
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001350 gui_buttonbar_init(&buttonbar);
1351 gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
1352 gui_buttonbar_set(&buttonbar, str(LANG_FM_BUTTONBAR_ADD),
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001353 str(LANG_FM_BUTTONBAR_EXIT),
1354 str(LANG_FM_BUTTONBAR_ACTION));
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001355 gui_buttonbar_draw(&buttonbar);
1356#endif
Jonathan Gordon5ca15392008-03-26 03:35:24 +00001357 gui_synclist_init(&lists, presets_get_name, NULL, false, 1, NULL);
Nils Wallméniusb3113672007-08-05 19:19:39 +00001358 gui_synclist_set_title(&lists, str(LANG_PRESET), NOICON);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001359 gui_synclist_set_icon_callback(&lists, NULL);
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001360 if(global_settings.talk_file)
1361 gui_synclist_set_voice_callback(&lists, presets_speak_name);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001362 gui_synclist_set_nb_items(&lists, num_presets);
1363 gui_synclist_select_item(&lists, curr_preset<0 ? 0 : curr_preset);
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001364 gui_synclist_speak_item(&lists);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001365
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001366 while (result == 0)
1367 {
1368 gui_synclist_draw(&lists);
1369 gui_syncstatusbar_draw(&statusbars, true);
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001370 list_do_action(CONTEXT_STD, HZ,
1371 &lists, &action, LIST_WRAP_UNLESS_HELD);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001372 switch (action)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001373 {
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001374 case ACTION_STD_MENU:
1375 radio_add_preset();
1376 break;
1377 case ACTION_STD_CANCEL:
1378 result = 1;
1379 break;
1380 case ACTION_STD_OK:
1381 curr_preset = gui_synclist_get_sel_pos(&lists);
1382 curr_freq = presets[curr_preset].frequency;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001383 next_station(0);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001384 remember_frequency();
1385 result = 1;
1386 break;
1387 case ACTION_F3:
1388 case ACTION_STD_CONTEXT:
1389 selected_preset = gui_synclist_get_sel_pos(&lists);
Jonathan Gordon5ca15392008-03-26 03:35:24 +00001390 do_menu(&handle_radio_preset_menu, NULL, NULL, false);
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001391 gui_synclist_speak_item(&lists);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001392 break;
1393 default:
1394 if(default_event_handler(action) == SYS_USB_CONNECTED)
1395 result = 2;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001396 }
1397 }
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001398 return result - 1;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001399}
1400
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001401void toggle_mono_mode(bool mono)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001402{
Michael Sevakis7d759f62007-07-14 11:20:31 +00001403 tuner_set(RADIO_FORCE_MONO, mono);
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001404}
1405
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001406void set_radio_region(int region)
Linus Nielsen Feltzing8448ba82004-07-05 14:30:17 +00001407{
Michael Sevakis680afaf2007-07-14 13:41:59 +00001408#ifdef HAVE_RADIO_REGION
Michael Sevakis7d759f62007-07-14 11:20:31 +00001409 tuner_set(RADIO_REGION, region);
Michael Sevakis680afaf2007-07-14 13:41:59 +00001410#endif
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001411 next_station(0);
Dominik Riebelinga22d9952006-10-12 13:59:44 +00001412 remember_frequency();
Michael Sevakis680afaf2007-07-14 13:41:59 +00001413 (void)region;
Dominik Riebelinge66b2ec2006-10-05 12:40:13 +00001414}
1415
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001416MENUITEM_SETTING(set_region, &global_settings.fm_region, NULL);
1417MENUITEM_SETTING(force_mono, &global_settings.fm_force_mono, NULL);
1418
Jens Arnold2a314072005-11-29 15:10:07 +00001419#ifndef FM_MODE
Bertrik Sikken19425902008-05-03 21:33:00 +00001420static char* get_mode_text(int selected_item, void * data, char *buffer)
Jens Arnold2a314072005-11-29 15:10:07 +00001421{
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001422 (void)selected_item;
1423 (void)data;
Nils Wallméniusb3113672007-08-05 19:19:39 +00001424 snprintf(buffer, MAX_PATH, "%s %s", str(LANG_MODE),
1425 radio_mode ? str(LANG_PRESET) :
Jens Arnold2a314072005-11-29 15:10:07 +00001426 str(LANG_RADIO_SCAN_MODE));
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001427 return buffer;
Jens Arnold2a314072005-11-29 15:10:07 +00001428}
Jonathan Gordondaf66942007-03-17 12:33:34 +00001429static int toggle_radio_mode(void)
Jens Arnold2a314072005-11-29 15:10:07 +00001430{
1431 radio_mode = (radio_mode == RADIO_SCAN_MODE) ?
1432 RADIO_PRESET_MODE : RADIO_SCAN_MODE;
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001433 return 0;
Jens Arnold2a314072005-11-29 15:10:07 +00001434}
Jonathan Gordondaf66942007-03-17 12:33:34 +00001435MENUITEM_FUNCTION_DYNTEXT(radio_mode_item, 0,
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001436 toggle_radio_mode, NULL,
Stéphane Doyon5acf0912007-10-09 03:48:56 +00001437 get_mode_text, NULL, NULL, NULL, Icon_NOICON);
Jens Arnold2a314072005-11-29 15:10:07 +00001438#endif
1439
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001440static int scan_presets(void *viewports)
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001441{
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001442 bool do_scan = true;
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001443 int i;
1444 struct viewport *vp = (struct viewport *)viewports;
Hristo Kovachev009853f2006-04-02 12:23:08 +00001445
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001446 FOR_NB_SCREENS(i)
1447 screens[i].set_viewport(vp?&vp[i]:NULL);
Hristo Kovachev009853f2006-04-02 12:23:08 +00001448 if(num_presets > 0) /* Do that to avoid 2 questions. */
Nils Wallménius5b769362007-08-06 13:08:36 +00001449 do_scan = yesno_pop(ID2P(LANG_FM_CLEAR_PRESETS));
Hristo Kovachev009853f2006-04-02 12:23:08 +00001450
1451 if(do_scan)
1452 {
Michael Sevakis7d759f62007-07-14 11:20:31 +00001453 const struct fm_region_data * const fmr =
1454 &fm_region_data[global_settings.fm_region];
1455
Peter D'Hoyed3f10702007-06-04 21:38:23 +00001456 char buf[MAX_FMPRESET_LEN + 1];
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001457
1458 curr_freq = fmr->freq_min;
Anton Oleynikov0afd9712005-11-19 14:54:41 +00001459 num_presets = 0;
Hristo Kovachevf709ad72006-04-03 10:06:39 +00001460 memset(presets, 0, sizeof(presets));
Michael Sevakis7d759f62007-07-14 11:20:31 +00001461 tuner_set(RADIO_MUTE, 1);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001462
1463 while(curr_freq <= fmr->freq_max)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001464 {
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001465 int freq, frac;
Jonathan Gordon568e18e2006-12-26 22:01:27 +00001466 if (num_presets >= MAX_PRESETS || action_userabort(TIMEOUT_NOBLOCK))
Anton Oleynikov0afd9712005-11-19 14:54:41 +00001467 break;
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001468
Dominik Riebelinge66b2ec2006-10-05 12:40:13 +00001469 freq = curr_freq / 10000;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001470 frac = freq % 100;
1471 freq /= 100;
1472
1473 snprintf(buf, MAX_FMPRESET_LEN, str(LANG_FM_SCANNING), freq, frac);
Jens Arnold4d6374c2007-03-16 21:56:08 +00001474 gui_syncsplash(0, buf);
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001475
Michael Sevakis7d759f62007-07-14 11:20:31 +00001476 if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001477 {
1478 /* add preset */
Stéphane Doyond65f9f12007-11-07 02:14:28 +00001479 presets[num_presets].name[0] = '\0';
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001480 presets[num_presets].frequency = curr_freq;
1481 num_presets++;
Anton Oleynikov0afd9712005-11-19 14:54:41 +00001482 }
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001483
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001484 curr_freq += fmr->freq_step;
Anton Oleynikov0afd9712005-11-19 14:54:41 +00001485 }
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001486
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001487 if (radio_status == FMRADIO_PLAYING)
Michael Sevakis7d759f62007-07-14 11:20:31 +00001488 tuner_set(RADIO_MUTE, 0);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001489
Hristo Kovachev009853f2006-04-02 12:23:08 +00001490 presets_changed = true;
1491
1492 FOR_NB_SCREENS(i)
1493 {
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001494 screens[i].clear_viewport();
1495 screens[i].update_viewport();
Hristo Kovachev009853f2006-04-02 12:23:08 +00001496 }
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001497
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001498 if(num_presets > 0)
Hristo Kovachev009853f2006-04-02 12:23:08 +00001499 {
Anton Oleynikov0afd9712005-11-19 14:54:41 +00001500 curr_freq = presets[0].frequency;
Anton Oleynikovc94557e2005-11-19 19:23:44 +00001501 radio_mode = RADIO_PRESET_MODE;
Hristo Kovachev009853f2006-04-02 12:23:08 +00001502 presets_loaded = true;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001503 next_station(0);
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001504 }
Hristo Kovachev009853f2006-04-02 12:23:08 +00001505 else
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001506 {
1507 /* Wrap it to beginning or we'll be past end of band */
Hristo Kovachev009853f2006-04-02 12:23:08 +00001508 presets_loaded = false;
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001509 next_station(1);
1510 }
Anton Oleynikovd79f3a12005-11-16 23:36:35 +00001511 }
1512 return true;
1513}
1514
Jörg Hohensohnc100a422004-10-19 22:50:34 +00001515
Michael Sevakis69b98bd2006-10-10 13:42:22 +00001516#ifdef HAVE_RECORDING
1517
Michael Sevakis8f659ae2007-05-20 20:26:36 +00001518#if defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC
Michael Sevakis69b98bd2006-10-10 13:42:22 +00001519#define FM_RECORDING_SCREEN
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001520static int fm_recording_screen(void)
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001521{
1522 bool ret;
1523
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001524 /* switch recording source to FMRADIO for the duration */
1525 int rec_source = global_settings.rec_source;
1526 global_settings.rec_source = AUDIO_SRC_FMRADIO;
1527
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001528 ret = recording_screen(true);
1529
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001530 /* safe to reset as changing sources is prohibited here */
1531 global_settings.rec_source = rec_source;
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001532
1533 return ret;
1534}
Jonathan Gordondaf66942007-03-17 12:33:34 +00001535
Michael Sevakis8f659ae2007-05-20 20:26:36 +00001536#endif /* defined(HAVE_FMRADIO_REC) && CONFIG_CODEC == SWCODEC */
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001537
Michael Sevakis8f659ae2007-05-20 20:26:36 +00001538#if defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC
Michael Sevakis69b98bd2006-10-10 13:42:22 +00001539#define FM_RECORDING_SETTINGS
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001540static int fm_recording_settings(void)
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001541{
1542 bool ret = recording_menu(true);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001543
Michael Sevakis9d56f2d2006-09-17 18:52:31 +00001544#if CONFIG_CODEC != SWCODEC
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001545 if (!ret)
1546 {
Michael Sevakis0f5cb942006-11-06 18:07:30 +00001547 struct audio_recording_options rec_options;
1548 rec_init_recording_options(&rec_options);
1549 rec_options.rec_source = AUDIO_SRC_LINEIN;
1550 rec_set_recording_options(&rec_options);
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001551 }
Michael Sevakis9d56f2d2006-09-17 18:52:31 +00001552#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001553
1554 return ret;
1555}
Jonathan Gordondaf66942007-03-17 12:33:34 +00001556
Michael Sevakis8f659ae2007-05-20 20:26:36 +00001557#endif /* defined(HAVE_FMRADIO_REC) || CONFIG_CODEC != SWCODEC */
Michael Sevakis69b98bd2006-10-10 13:42:22 +00001558#endif /* HAVE_RECORDING */
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001559
1560#ifdef FM_RECORDING_SCREEN
Nils Wallméniusb3113672007-08-05 19:19:39 +00001561MENUITEM_FUNCTION(recscreen_item, 0, ID2P(LANG_RECORDING),
Peter D'Hoyee50cba92007-06-25 21:19:45 +00001562 fm_recording_screen, NULL, NULL, Icon_Recording);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001563#endif
1564#ifdef FM_RECORDING_SETTINGS
Jonathan Gordondaf66942007-03-17 12:33:34 +00001565MENUITEM_FUNCTION(recsettings_item, 0, ID2P(LANG_RECORDING_SETTINGS),
Peter D'Hoyee50cba92007-06-25 21:19:45 +00001566 fm_recording_settings, NULL, NULL, Icon_Recording);
Michael Sevakisa2ee6a62007-03-16 14:40:40 +00001567#endif
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001568#ifndef FM_PRESET
Nils Wallméniusb3113672007-08-05 19:19:39 +00001569MENUITEM_FUNCTION(radio_presets_item, 0, ID2P(LANG_PRESET),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001570 handle_radio_presets, NULL, NULL, Icon_NOICON);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001571#endif
1572#ifndef FM_PRESET_ADD
Jonathan Gordondaf66942007-03-17 12:33:34 +00001573MENUITEM_FUNCTION(radio_addpreset_item, 0, ID2P(LANG_FM_ADD_PRESET),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001574 radio_add_preset, NULL, NULL, Icon_NOICON);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001575#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +00001576
1577
Jonathan Gordondaf66942007-03-17 12:33:34 +00001578MENUITEM_FUNCTION(presetload_item, 0, ID2P(LANG_FM_PRESET_LOAD),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001579 load_preset_list, NULL, NULL, Icon_NOICON);
Jonathan Gordondaf66942007-03-17 12:33:34 +00001580MENUITEM_FUNCTION(presetsave_item, 0, ID2P(LANG_FM_PRESET_SAVE),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001581 save_preset_list, NULL, NULL, Icon_NOICON);
Jonathan Gordondaf66942007-03-17 12:33:34 +00001582MENUITEM_FUNCTION(presetclear_item, 0, ID2P(LANG_FM_PRESET_CLEAR),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001583 clear_preset_list, NULL, NULL, Icon_NOICON);
Jonathan Gordon0501fb02008-05-29 11:13:46 +00001584MENUITEM_FUNCTION(scan_presets_item, MENU_FUNC_USEPARAM,
1585 ID2P(LANG_FM_SCAN_PRESETS),
Jonathan Gordone54d8e12007-03-18 07:03:43 +00001586 scan_presets, NULL, NULL, Icon_NOICON);
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001587
Peter D'Hoye9337efd2007-07-03 18:31:13 +00001588MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
Jonathan Gordon02a87172007-03-03 13:52:14 +00001589 Icon_Radio_screen,
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001590#ifndef FM_PRESET
1591 &radio_presets_item,
1592#endif
1593#ifndef FM_PRESET_ADD
1594 &radio_addpreset_item,
1595#endif
1596 &presetload_item, &presetsave_item, &presetclear_item,
1597 &force_mono,
1598#ifndef FM_MODE
1599 &radio_mode_item,
1600#endif
1601 &set_region, &sound_settings,
1602#ifdef FM_RECORDING_SCREEN
Jonathan Gordon4721def2007-02-27 09:22:56 +00001603 &recscreen_item,
Jonathan Gordon2816dc92007-02-27 09:06:30 +00001604#endif
1605#ifdef FM_RECORDING_SETTINGS
1606 &recsettings_item,
1607#endif
1608 &scan_presets_item);
Jörg Hohensohnc100a422004-10-19 22:50:34 +00001609/* main menu of the radio screen */
Jens Arnold2597a132006-12-25 14:01:47 +00001610static bool radio_menu(void)
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001611{
Jonathan Gordon5ca15392008-03-26 03:35:24 +00001612 return do_menu(&radio_settings_menu, NULL, NULL, false) == MENU_ATTACHED_USB;
Linus Nielsen Feltzingc5dacdc2003-05-04 02:23:18 +00001613}
1614
Linus Nielsen Feltzing331c7d92003-05-03 02:40:09 +00001615#endif