diff options
Diffstat (limited to 'apps/recorder')
-rw-r--r-- | apps/recorder/radio.c | 637 | ||||
-rw-r--r-- | apps/recorder/radio.h | 10 |
2 files changed, 335 insertions, 312 deletions
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 7258840dbf..8b79f2c9e7 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c | |||
@@ -20,12 +20,13 @@ | |||
20 | #include "config.h" | 20 | #include "config.h" |
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <stdbool.h> | 22 | #include <stdbool.h> |
23 | #include <stdlib.h> | ||
23 | #include "sprintf.h" | 24 | #include "sprintf.h" |
24 | #include "mas.h" | 25 | #include "mas.h" |
25 | #include "settings.h" | 26 | #include "settings.h" |
26 | #include "button.h" | 27 | #include "button.h" |
27 | #include "status.h" | 28 | #include "status.h" |
28 | #include "kernel.h" | 29 | #include "thread.h" |
29 | #include "mpeg.h" | 30 | #include "mpeg.h" |
30 | #include "audio.h" | 31 | #include "audio.h" |
31 | #include "mp3_playback.h" | 32 | #include "mp3_playback.h" |
@@ -47,7 +48,6 @@ | |||
47 | #include "recording.h" | 48 | #include "recording.h" |
48 | #include "talk.h" | 49 | #include "talk.h" |
49 | #include "tuner.h" | 50 | #include "tuner.h" |
50 | #include "hwcompat.h" | ||
51 | #include "power.h" | 51 | #include "power.h" |
52 | #include "sound.h" | 52 | #include "sound.h" |
53 | #include "screen_access.h" | 53 | #include "screen_access.h" |
@@ -82,6 +82,10 @@ | |||
82 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) | 82 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) |
83 | #define FM_PRESET | 83 | #define FM_PRESET |
84 | #define FM_MODE | 84 | #define FM_MODE |
85 | /* This should be removeable if the whole tuning thing is sorted out since | ||
86 | proper tuning quiets the screen almost entirely in that extreme measures | ||
87 | have to be taken to hear any interference. */ | ||
88 | #define HAVE_NOISY_IDLE_MODE | ||
85 | 89 | ||
86 | #elif CONFIG_KEYPAD == ONDIO_PAD | 90 | #elif CONFIG_KEYPAD == ONDIO_PAD |
87 | #define FM_RECORD_DBLPRE | 91 | #define FM_RECORD_DBLPRE |
@@ -91,26 +95,12 @@ | |||
91 | #define RADIO_SCAN_MODE 0 | 95 | #define RADIO_SCAN_MODE 0 |
92 | #define RADIO_PRESET_MODE 1 | 96 | #define RADIO_PRESET_MODE 1 |
93 | 97 | ||
94 | #if (CONFIG_TUNER & TEA5767) | 98 | static const struct fm_region_setting fm_region[] = { |
95 | #define DEEMPH_50 0, | 99 | /* Note: Desriptive strings are just for display atm and are not compiled. */ |
96 | #define DEEMPH_75 1, | 100 | FM_REGION_ENTRY("Europe", 87500000, 108000000, 50000, 0, 0), |
97 | #define BAND_LIM_EU 0 | 101 | FM_REGION_ENTRY("US/Canada", 87900000, 107900000, 200000, 1, 0), |
98 | #define BAND_LIM_JP 1 | 102 | FM_REGION_ENTRY("Japan", 76000000, 90000000, 100000, 0, 1), |
99 | #else | 103 | FM_REGION_ENTRY("Korea", 87500000, 108000000, 100000, 0, 0), |
100 | #define DEEMPH_50 | ||
101 | #define DEEMPH_75 | ||
102 | #define BAND_LIM_EU | ||
103 | #define BAND_LIM_JP | ||
104 | #endif | ||
105 | static struct fm_region_setting fm_region[] = { | ||
106 | /* Europe */ | ||
107 | { 87500000, 108000000, 50000, DEEMPH_50 BAND_LIM_EU }, | ||
108 | /* US / Canada */ | ||
109 | { 87900000, 107900000, 200000, DEEMPH_75 BAND_LIM_EU }, | ||
110 | /* Japan */ | ||
111 | { 76000000, 90000000, 100000, DEEMPH_50 BAND_LIM_JP }, | ||
112 | /* Korea */ | ||
113 | { 87500000, 108000000, 100000, DEEMPH_50 BAND_LIM_EU }, | ||
114 | }; | 104 | }; |
115 | 105 | ||
116 | static int curr_preset = -1; | 106 | static int curr_preset = -1; |
@@ -138,22 +128,6 @@ static int clear_preset_list(void); | |||
138 | 128 | ||
139 | static int scan_presets(void); | 129 | static int scan_presets(void); |
140 | 130 | ||
141 | #ifdef SIMULATOR | ||
142 | void radio_set(int setting, int value); | ||
143 | int radio_get(int setting); | ||
144 | #else | ||
145 | #if CONFIG_TUNER == S1A0903X01 /* FM recorder */ | ||
146 | #define radio_set samsung_set | ||
147 | #define radio_get samsung_get | ||
148 | #elif CONFIG_TUNER == TEA5767 /* iriver, iaudio */ | ||
149 | #define radio_set philips_set | ||
150 | #define radio_get philips_get | ||
151 | #elif CONFIG_TUNER == (S1A0903X01 | TEA5767) /* OndioFM */ | ||
152 | static void (*radio_set)(int setting, int value); | ||
153 | static int (*radio_get)(int setting); | ||
154 | #endif | ||
155 | #endif | ||
156 | |||
157 | /* Function to manipulate all yesno dialogues. | 131 | /* Function to manipulate all yesno dialogues. |
158 | This function needs the output text as an argument. */ | 132 | This function needs the output text as an argument. */ |
159 | static bool yesno_pop(char* text) | 133 | static bool yesno_pop(char* text) |
@@ -169,25 +143,10 @@ static bool yesno_pop(char* text) | |||
169 | 143 | ||
170 | void radio_init(void) | 144 | void radio_init(void) |
171 | { | 145 | { |
172 | #ifndef SIMULATOR | 146 | tuner_init(); |
173 | #if CONFIG_TUNER == (S1A0903X01 | TEA5767) | ||
174 | if (read_hw_mask() & TUNER_MODEL) | ||
175 | { | ||
176 | radio_set = philips_set; | ||
177 | radio_get = philips_get; | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | radio_set = samsung_set; | ||
182 | radio_get = samsung_get; | ||
183 | } | ||
184 | #endif | ||
185 | #endif | ||
186 | radio_stop(); | 147 | radio_stop(); |
187 | } | 148 | } |
188 | 149 | ||
189 | /* For powermgmt.c to check status for shutdown since it can't access | ||
190 | the global_status structure directly. */ | ||
191 | int get_radio_status(void) | 150 | int get_radio_status(void) |
192 | { | 151 | { |
193 | return radio_status; | 152 | return radio_status; |
@@ -202,12 +161,15 @@ bool in_radio_screen(void) | |||
202 | #define FMRADIO_START_PAUSED 0x8000 | 161 | #define FMRADIO_START_PAUSED 0x8000 |
203 | void radio_start(void) | 162 | void radio_start(void) |
204 | { | 163 | { |
164 | const struct fm_region_setting *fmr; | ||
205 | bool start_paused; | 165 | bool start_paused; |
206 | int mute_timeout; | 166 | int mute_timeout; |
207 | 167 | ||
208 | if(radio_status == FMRADIO_PLAYING) | 168 | if(radio_status == FMRADIO_PLAYING) |
209 | return; | 169 | return; |
210 | 170 | ||
171 | fmr = &fm_region[global_settings.fm_region]; | ||
172 | |||
211 | start_paused = radio_status & FMRADIO_START_PAUSED; | 173 | start_paused = radio_status & FMRADIO_START_PAUSED; |
212 | /* clear flag before any yielding */ | 174 | /* clear flag before any yielding */ |
213 | radio_status &= ~FMRADIO_START_PAUSED; | 175 | radio_status &= ~FMRADIO_START_PAUSED; |
@@ -216,21 +178,21 @@ void radio_start(void) | |||
216 | radio_power(true); | 178 | radio_power(true); |
217 | 179 | ||
218 | curr_freq = global_status.last_frequency | 180 | curr_freq = global_status.last_frequency |
219 | * fm_region[global_settings.fm_region].freq_step | 181 | * fmr->freq_step + fmr->freq_min; |
220 | + fm_region[global_settings.fm_region].freq_min; | ||
221 | 182 | ||
222 | radio_set(RADIO_SLEEP, 0); /* wake up the tuner */ | 183 | radio_set(RADIO_SLEEP, 0); /* wake up the tuner */ |
223 | radio_set(RADIO_FREQUENCY, curr_freq); | 184 | radio_set(RADIO_FREQUENCY, curr_freq); |
224 | 185 | ||
225 | if(radio_status == FMRADIO_OFF) | 186 | if(radio_status == FMRADIO_OFF) |
226 | { | 187 | { |
188 | #if (CONFIG_TUNER & S1A0903X01) | ||
227 | radio_set(RADIO_IF_MEASUREMENT, 0); | 189 | radio_set(RADIO_IF_MEASUREMENT, 0); |
228 | radio_set(RADIO_SENSITIVITY, 0); | 190 | radio_set(RADIO_SENSITIVITY, 0); |
191 | #endif | ||
229 | radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); | 192 | radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); |
230 | #if (CONFIG_TUNER & TEA5767) | 193 | #if (CONFIG_TUNER & TEA5767) |
231 | radio_set(RADIO_SET_DEEMPHASIS, | 194 | radio_set(RADIO_SET_DEEMPHASIS, fmr->deemphasis); |
232 | fm_region[global_settings.fm_region].deemphasis); | 195 | radio_set(RADIO_SET_BAND, fmr->band); |
233 | radio_set(RADIO_SET_BAND, fm_region[global_settings.fm_region].band); | ||
234 | #endif | 196 | #endif |
235 | mute_timeout = current_tick + 1*HZ; | 197 | mute_timeout = current_tick + 1*HZ; |
236 | } | 198 | } |
@@ -295,6 +257,25 @@ bool radio_hardware_present(void) | |||
295 | #endif | 257 | #endif |
296 | } | 258 | } |
297 | 259 | ||
260 | /* Keep freq on the grid for the current region */ | ||
261 | static int snap_freq_to_grid(int freq) | ||
262 | { | ||
263 | const struct fm_region_setting * const fmr = | ||
264 | &fm_region[global_settings.fm_region]; | ||
265 | |||
266 | /* Range clamp if out of range or just round to nearest */ | ||
267 | if (freq < fmr->freq_min) | ||
268 | freq = fmr->freq_min; | ||
269 | else if (freq > fmr->freq_max) | ||
270 | freq = fmr->freq_max; | ||
271 | else | ||
272 | freq = (freq - fmr->freq_min + fmr->freq_step/2) / | ||
273 | fmr->freq_step * fmr->freq_step + fmr->freq_min; | ||
274 | |||
275 | return freq; | ||
276 | } | ||
277 | |||
278 | /* Find a matching preset to freq */ | ||
298 | static int find_preset(int freq) | 279 | static int find_preset(int freq) |
299 | { | 280 | { |
300 | int i; | 281 | int i; |
@@ -309,35 +290,43 @@ static int find_preset(int freq) | |||
309 | return -1; | 290 | return -1; |
310 | } | 291 | } |
311 | 292 | ||
312 | static int find_closest_preset(int freq) | 293 | /* Return the first preset encountered in the search direction with |
294 | wraparound. */ | ||
295 | static int find_closest_preset(int freq, int direction) | ||
313 | { | 296 | { |
314 | int i; | 297 | int i; |
315 | int diff; | ||
316 | int min_diff = fm_region[global_settings.fm_region].freq_min; | ||
317 | int preset = -1; | ||
318 | 298 | ||
319 | for(i = 0;i < MAX_PRESETS;i++) | 299 | if (direction == 0) /* direction == 0 isn't really used */ |
300 | return 0; | ||
301 | |||
302 | for (i = 0; i < MAX_PRESETS; i++) | ||
320 | { | 303 | { |
321 | diff = freq - presets[i].frequency; | 304 | int preset_frequency = presets[i].frequency; |
322 | if(diff==0) | 305 | |
323 | return i; | 306 | if (preset_frequency == freq) |
324 | if(diff < 0) | 307 | return i; /* Exact match = stop */ |
325 | diff = -diff; | 308 | /* Stop when the preset frequency exeeds freq so that we can |
326 | if(diff < min_diff) | 309 | pick the correct one based on direction */ |
327 | { | 310 | if (preset_frequency > freq) |
328 | preset = i; | 311 | break; |
329 | min_diff = diff; | ||
330 | } | ||
331 | } | 312 | } |
332 | 313 | ||
333 | return preset; | 314 | /* wrap around depending on direction */ |
315 | if (i == 0 || i >= num_presets - 1) | ||
316 | i = direction < 0 ? num_presets - 1 : 0; | ||
317 | else if (direction < 0) | ||
318 | i--; /* use previous */ | ||
319 | |||
320 | return i; | ||
334 | } | 321 | } |
335 | 322 | ||
336 | static void remember_frequency(void) | 323 | static void remember_frequency(void) |
337 | { | 324 | { |
338 | global_status.last_frequency = (curr_freq | 325 | const struct fm_region_setting * const fmr = |
339 | - fm_region[global_settings.fm_region].freq_min) | 326 | &fm_region[global_settings.fm_region]; |
340 | / fm_region[global_settings.fm_region].freq_step; | 327 | |
328 | global_status.last_frequency = (curr_freq - fmr->freq_min) | ||
329 | / fmr->freq_step; | ||
341 | status_save(); | 330 | status_save(); |
342 | } | 331 | } |
343 | 332 | ||
@@ -346,60 +335,104 @@ static void next_preset(int direction) | |||
346 | if (num_presets < 1) | 335 | if (num_presets < 1) |
347 | return; | 336 | return; |
348 | 337 | ||
349 | if(curr_preset == -1) | 338 | if (curr_preset == -1) |
350 | curr_preset = find_closest_preset(curr_freq); | 339 | curr_preset = find_closest_preset(curr_freq, direction); |
351 | |||
352 | if(direction > 0) | ||
353 | if(curr_preset == num_presets - 1) | ||
354 | curr_preset = 0; | ||
355 | else | ||
356 | curr_preset++; | ||
357 | else | 340 | else |
358 | if(curr_preset == 0) | 341 | curr_preset = (curr_preset + direction + num_presets) % num_presets; |
359 | curr_preset = num_presets - 1; | 342 | |
360 | else | 343 | /* Must stay on the current grid for the region */ |
361 | curr_preset--; | 344 | curr_freq = snap_freq_to_grid(presets[curr_preset].frequency); |
362 | 345 | ||
363 | curr_freq = presets[curr_preset].frequency; | ||
364 | radio_set(RADIO_FREQUENCY, curr_freq); | 346 | radio_set(RADIO_FREQUENCY, curr_freq); |
365 | remember_frequency(); | 347 | remember_frequency(); |
366 | } | 348 | } |
367 | 349 | ||
350 | /* Step to the next or previous frequency */ | ||
351 | static int step_freq(int freq, int direction) | ||
352 | { | ||
353 | const struct fm_region_setting * const fmr = | ||
354 | &fm_region[global_settings.fm_region]; | ||
355 | |||
356 | freq += direction*fmr->freq_step; | ||
357 | |||
358 | /* Wrap first or snapping to grid will not let us on the band extremes */ | ||
359 | if (freq > fmr->freq_max) | ||
360 | freq = direction > 0 ? fmr->freq_min : fmr->freq_max; | ||
361 | else if (freq < fmr->freq_min) | ||
362 | freq = direction < 0 ? fmr->freq_max : fmr->freq_min; | ||
363 | else | ||
364 | freq = snap_freq_to_grid(freq); | ||
365 | |||
366 | return freq; | ||
367 | } | ||
368 | |||
369 | /* Step to the next or previous station */ | ||
370 | static void next_station(int direction) | ||
371 | { | ||
372 | if (direction != 0 && radio_mode != RADIO_SCAN_MODE) | ||
373 | { | ||
374 | next_preset(direction); | ||
375 | return; | ||
376 | } | ||
377 | |||
378 | curr_freq = step_freq(curr_freq, direction); | ||
379 | |||
380 | if (radio_status == FMRADIO_PLAYING) | ||
381 | radio_set(RADIO_MUTE, 1); | ||
382 | |||
383 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
384 | |||
385 | if (radio_status == FMRADIO_PLAYING) | ||
386 | radio_set(RADIO_MUTE, 0); | ||
387 | |||
388 | curr_preset = find_preset(curr_freq); | ||
389 | remember_frequency(); | ||
390 | } | ||
368 | 391 | ||
369 | int radio_screen(void) | 392 | int radio_screen(void) |
370 | { | 393 | { |
371 | char buf[MAX_PATH]; | 394 | char buf[MAX_PATH]; |
372 | bool done = false; | 395 | bool done = false; |
373 | int button, lastbutton = BUTTON_NONE; | ||
374 | int ret_val = GO_TO_ROOT; | 396 | int ret_val = GO_TO_ROOT; |
375 | #ifdef FM_RECORD_DBLPRE | 397 | int button; |
376 | unsigned long rec_lastclick = 0; | 398 | int i; |
377 | #endif | ||
378 | int freq, i; | ||
379 | bool tuned; | ||
380 | bool stereo = false; | ||
381 | int search_dir = 0; | 399 | int search_dir = 0; |
400 | bool stereo = false, last_stereo = false; | ||
382 | int fh; | 401 | int fh; |
383 | bool last_stereo_status = false; | ||
384 | int top_of_screen = 0; | 402 | int top_of_screen = 0; |
385 | bool update_screen = true; | 403 | bool update_screen = true; |
386 | int timeout = current_tick + HZ/10; | ||
387 | bool screen_freeze = false; | 404 | bool screen_freeze = false; |
405 | bool keep_playing = false; | ||
406 | bool statusbar = global_settings.statusbar; | ||
407 | #ifdef FM_RECORD_DBLPRE | ||
408 | int lastbutton = BUTTON_NONE; | ||
409 | unsigned long rec_lastclick = 0; | ||
410 | #endif | ||
411 | #if CONFIG_CODEC != SWCODEC | ||
388 | bool have_recorded = false; | 412 | bool have_recorded = false; |
413 | int timeout = current_tick + HZ/10; | ||
389 | unsigned int seconds = 0; | 414 | unsigned int seconds = 0; |
390 | unsigned int last_seconds = 0; | 415 | unsigned int last_seconds = 0; |
391 | #if CONFIG_CODEC != SWCODEC | ||
392 | int hours, minutes; | 416 | int hours, minutes; |
393 | struct audio_recording_options rec_options; | 417 | struct audio_recording_options rec_options; |
394 | #endif | 418 | #endif /* CONFIG_CODEC != SWCODEC */ |
395 | bool keep_playing = false; | 419 | #ifndef HAVE_NOISY_IDLE_MODE |
396 | bool statusbar = global_settings.statusbar; | ||
397 | int button_timeout = current_tick + (2*HZ); | 420 | int button_timeout = current_tick + (2*HZ); |
421 | #endif | ||
398 | #ifdef HAS_BUTTONBAR | 422 | #ifdef HAS_BUTTONBAR |
399 | struct gui_buttonbar buttonbar; | 423 | struct gui_buttonbar buttonbar; |
400 | gui_buttonbar_init(&buttonbar); | 424 | gui_buttonbar_init(&buttonbar); |
401 | gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) ); | 425 | gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) ); |
402 | #endif | 426 | #endif |
427 | |||
428 | /* Ends an in-progress search - needs access to search_dir */ | ||
429 | void end_search(void) | ||
430 | { | ||
431 | if (search_dir != 0 && radio_status == FMRADIO_PLAYING) | ||
432 | radio_set(RADIO_MUTE, 0); | ||
433 | search_dir = 0; | ||
434 | } | ||
435 | |||
403 | /* change status to "in screen" */ | 436 | /* change status to "in screen" */ |
404 | in_screen = true; | 437 | in_screen = true; |
405 | 438 | ||
@@ -419,7 +452,7 @@ int radio_screen(void) | |||
419 | if(fh < 10) | 452 | if(fh < 10) |
420 | top_of_screen = 1; | 453 | top_of_screen = 1; |
421 | 454 | ||
422 | if(!num_presets) | 455 | if(num_presets <= 0) |
423 | { | 456 | { |
424 | memset(presets, 0, sizeof(presets)); | 457 | memset(presets, 0, sizeof(presets)); |
425 | radio_load_presets(global_settings.fmr_file); | 458 | radio_load_presets(global_settings.fmr_file); |
@@ -461,8 +494,7 @@ int radio_screen(void) | |||
461 | radio_start(); | 494 | radio_start(); |
462 | #endif | 495 | #endif |
463 | 496 | ||
464 | /* I hate this thing with vehement passion (jhMikeS): */ | 497 | if(num_presets < 1 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN))) |
465 | if(num_presets == 0 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN))) | ||
466 | scan_presets(); | 498 | scan_presets(); |
467 | 499 | ||
468 | curr_preset = find_preset(curr_freq); | 500 | curr_preset = find_preset(curr_freq); |
@@ -474,50 +506,44 @@ int radio_screen(void) | |||
474 | str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); | 506 | str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); |
475 | #endif | 507 | #endif |
476 | 508 | ||
509 | #ifndef HAVE_NOISY_IDLE_MODE | ||
477 | cpu_idle_mode(true); | 510 | cpu_idle_mode(true); |
478 | 511 | #endif | |
512 | |||
479 | while(!done) | 513 | while(!done) |
480 | { | 514 | { |
481 | if(search_dir) | 515 | if(search_dir != 0) |
482 | { | 516 | { |
483 | curr_freq += search_dir | 517 | curr_freq = step_freq(curr_freq, search_dir); |
484 | * fm_region[global_settings.fm_region].freq_step; | 518 | update_screen = true; |
485 | if(curr_freq < fm_region[global_settings.fm_region].freq_min) | ||
486 | curr_freq = fm_region[global_settings.fm_region].freq_max; | ||
487 | if(curr_freq > fm_region[global_settings.fm_region].freq_max) | ||
488 | curr_freq = fm_region[global_settings.fm_region].freq_min; | ||
489 | |||
490 | /* Tune in and delay */ | ||
491 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
492 | sleep(1); | ||
493 | |||
494 | /* Start IF measurement */ | ||
495 | radio_set(RADIO_IF_MEASUREMENT, 1); | ||
496 | sleep(1); | ||
497 | |||
498 | /* Now check how close to the IF frequency we are */ | ||
499 | tuned = radio_get(RADIO_TUNED); | ||
500 | 519 | ||
501 | /* Stop searching if the tuning is close */ | 520 | if(radio_set(RADIO_SCAN_FREQUENCY, curr_freq)) |
502 | if(tuned) | ||
503 | { | 521 | { |
504 | search_dir = 0; | ||
505 | curr_preset = find_preset(curr_freq); | 522 | curr_preset = find_preset(curr_freq); |
506 | remember_frequency(); | 523 | remember_frequency(); |
524 | end_search(); | ||
507 | } | 525 | } |
508 | 526 | ||
509 | update_screen = true; | 527 | trigger_cpu_boost(); |
510 | } | 528 | } |
511 | 529 | ||
512 | if(search_dir) | 530 | #if CONFIG_CODEC != SWCODEC |
513 | button = button_get(false); | 531 | /* TODO: Can we timeout at HZ when recording since peaks aren't |
514 | else | 532 | displayed? This should quiet recordings too. */ |
515 | button = get_action(CONTEXT_FM, HZ / PEAK_METER_FPS); | 533 | button = get_action(CONTEXT_FM, |
534 | update_screen ? TIMEOUT_NOBLOCK : HZ / PEAK_METER_FPS); | ||
535 | #else | ||
536 | button = get_action(CONTEXT_FM, | ||
537 | update_screen ? TIMEOUT_NOBLOCK : HZ); | ||
538 | #endif | ||
539 | |||
540 | #ifndef HAVE_NOISY_IDLE_MODE | ||
516 | if (button != ACTION_NONE) | 541 | if (button != ACTION_NONE) |
517 | { | 542 | { |
518 | cpu_idle_mode(false); | 543 | cpu_idle_mode(false); |
519 | button_timeout = current_tick + (2*HZ); | 544 | button_timeout = current_tick + (2*HZ); |
520 | } | 545 | } |
546 | #endif | ||
521 | switch(button) | 547 | switch(button) |
522 | { | 548 | { |
523 | case ACTION_FM_STOP: | 549 | case ACTION_FM_STOP: |
@@ -559,7 +585,7 @@ int radio_screen(void) | |||
559 | rec_lastclick = current_tick; | 585 | rec_lastclick = current_tick; |
560 | break; | 586 | break; |
561 | } | 587 | } |
562 | #endif | 588 | #endif /* FM_RECORD_DBLPRE */ |
563 | #ifndef SIMULATOR | 589 | #ifndef SIMULATOR |
564 | if(audio_status() == AUDIO_STATUS_RECORD) | 590 | if(audio_status() == AUDIO_STATUS_RECORD) |
565 | { | 591 | { |
@@ -572,7 +598,7 @@ int radio_screen(void) | |||
572 | rec_record(); | 598 | rec_record(); |
573 | update_screen = true; | 599 | update_screen = true; |
574 | } | 600 | } |
575 | #endif | 601 | #endif /* SIMULATOR */ |
576 | last_seconds = 0; | 602 | last_seconds = 0; |
577 | break; | 603 | break; |
578 | #endif /* #ifdef FM_RECORD */ | 604 | #endif /* #ifdef FM_RECORD */ |
@@ -602,63 +628,31 @@ int radio_screen(void) | |||
602 | break; | 628 | break; |
603 | 629 | ||
604 | case ACTION_STD_PREV: | 630 | case ACTION_STD_PREV: |
605 | if(radio_mode == RADIO_SCAN_MODE) | ||
606 | { | ||
607 | curr_freq | ||
608 | -= fm_region[global_settings.fm_region].freq_step; | ||
609 | if(curr_freq < fm_region[global_settings.fm_region].freq_min) | ||
610 | curr_freq | ||
611 | = fm_region[global_settings.fm_region].freq_max; | ||
612 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
613 | curr_preset = find_preset(curr_freq); | ||
614 | remember_frequency(); | ||
615 | } | ||
616 | else | ||
617 | next_preset(-1); | ||
618 | search_dir = 0; | ||
619 | update_screen = true; | ||
620 | break; | ||
621 | |||
622 | case ACTION_STD_NEXT: | 631 | case ACTION_STD_NEXT: |
623 | if(radio_mode == RADIO_SCAN_MODE) | 632 | next_station(button == ACTION_STD_PREV ? -1 : 1); |
624 | { | 633 | end_search(); |
625 | curr_freq | ||
626 | += fm_region[global_settings.fm_region].freq_step; | ||
627 | if(curr_freq > fm_region[global_settings.fm_region].freq_max) | ||
628 | curr_freq | ||
629 | = fm_region[global_settings.fm_region].freq_min; | ||
630 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
631 | curr_preset = find_preset(curr_freq); | ||
632 | remember_frequency(); | ||
633 | } | ||
634 | else | ||
635 | next_preset(1); | ||
636 | search_dir = 0; | ||
637 | update_screen = true; | 634 | update_screen = true; |
638 | break; | 635 | break; |
639 | 636 | ||
640 | case ACTION_STD_PREVREPEAT: | 637 | case ACTION_STD_PREVREPEAT: |
641 | if(radio_mode == RADIO_SCAN_MODE) | 638 | case ACTION_STD_NEXTREPEAT: |
642 | search_dir = -1; | 639 | { |
643 | else | 640 | int dir = search_dir; |
641 | search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1; | ||
642 | if (radio_mode != RADIO_SCAN_MODE) | ||
644 | { | 643 | { |
645 | next_preset(-1); | 644 | next_preset(search_dir); |
645 | end_search(); | ||
646 | update_screen = true; | 646 | update_screen = true; |
647 | } | 647 | } |
648 | 648 | else if (dir == 0) | |
649 | break; | ||
650 | |||
651 | case ACTION_STD_NEXTREPEAT: | ||
652 | if(radio_mode == RADIO_SCAN_MODE) | ||
653 | search_dir = 1; | ||
654 | else | ||
655 | { | 649 | { |
656 | next_preset(1); | 650 | /* Starting auto scan */ |
651 | radio_set(RADIO_MUTE, 1); | ||
657 | update_screen = true; | 652 | update_screen = true; |
658 | } | 653 | } |
659 | |||
660 | break; | 654 | break; |
661 | 655 | } | |
662 | 656 | ||
663 | case ACTION_SETTINGS_INC: | 657 | case ACTION_SETTINGS_INC: |
664 | case ACTION_SETTINGS_INCREPEAT: | 658 | case ACTION_SETTINGS_INCREPEAT: |
@@ -693,8 +687,9 @@ int radio_screen(void) | |||
693 | radio_menu(); | 687 | radio_menu(); |
694 | curr_preset = find_preset(curr_freq); | 688 | curr_preset = find_preset(curr_freq); |
695 | FOR_NB_SCREENS(i){ | 689 | FOR_NB_SCREENS(i){ |
696 | gui_textarea_clear(&screens[i]); | 690 | struct screen *sc = &screens[i]; |
697 | screen_set_xmargin(&screens[i],0); | 691 | gui_textarea_clear(sc); |
692 | screen_set_xmargin(sc, 0); | ||
698 | } | 693 | } |
699 | #ifdef HAS_BUTTONBAR | 694 | #ifdef HAS_BUTTONBAR |
700 | gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU), | 695 | gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU), |
@@ -712,9 +707,10 @@ int radio_screen(void) | |||
712 | update_screen = true; | 707 | update_screen = true; |
713 | FOR_NB_SCREENS(i) | 708 | FOR_NB_SCREENS(i) |
714 | { | 709 | { |
715 | gui_textarea_clear(&screens[i]); | 710 | struct screen *sc = &screens[i]; |
716 | screen_set_xmargin(&screens[i],0); | 711 | gui_textarea_clear(sc); |
717 | gui_textarea_update(&screens[i]); | 712 | screen_set_xmargin(sc, 0); |
713 | gui_textarea_update(sc); | ||
718 | } | 714 | } |
719 | 715 | ||
720 | break; | 716 | break; |
@@ -722,9 +718,10 @@ int radio_screen(void) | |||
722 | handle_radio_presets(); | 718 | handle_radio_presets(); |
723 | FOR_NB_SCREENS(i) | 719 | FOR_NB_SCREENS(i) |
724 | { | 720 | { |
725 | gui_textarea_clear(&screens[i]); | 721 | struct screen *sc = &screens[i]; |
726 | screen_set_xmargin(&screens[i],0); | 722 | gui_textarea_clear(sc); |
727 | gui_textarea_update(&screens[i]); | 723 | screen_set_xmargin(sc, 0); |
724 | gui_textarea_update(sc); | ||
728 | } | 725 | } |
729 | #ifdef HAS_BUTTONBAR | 726 | #ifdef HAS_BUTTONBAR |
730 | gui_buttonbar_set(&buttonbar, | 727 | gui_buttonbar_set(&buttonbar, |
@@ -734,7 +731,7 @@ int radio_screen(void) | |||
734 | #endif | 731 | #endif |
735 | update_screen = true; | 732 | update_screen = true; |
736 | break; | 733 | break; |
737 | #endif | 734 | #endif /* FM_PRESET */ |
738 | 735 | ||
739 | #ifdef FM_FREEZE | 736 | #ifdef FM_FREEZE |
740 | case ACTION_FM_FREEZE: | 737 | case ACTION_FM_FREEZE: |
@@ -749,10 +746,13 @@ int radio_screen(void) | |||
749 | screen_freeze = false; | 746 | screen_freeze = false; |
750 | } | 747 | } |
751 | break; | 748 | break; |
752 | #endif | 749 | #endif /* FM_FREEZE */ |
750 | |||
753 | case SYS_USB_CONNECTED: | 751 | case SYS_USB_CONNECTED: |
752 | #if CONFIG_CODEC != SWCODEC | ||
754 | /* Only accept USB connection when not recording */ | 753 | /* Only accept USB connection when not recording */ |
755 | if(audio_status() != AUDIO_STATUS_RECORD) | 754 | if(audio_status() != AUDIO_STATUS_RECORD) |
755 | #endif | ||
756 | { | 756 | { |
757 | default_event_handler(SYS_USB_CONNECTED); | 757 | default_event_handler(SYS_USB_CONNECTED); |
758 | screen_freeze = true; /* Cosmetic: makes sure the | 758 | screen_freeze = true; /* Cosmetic: makes sure the |
@@ -773,18 +773,20 @@ int radio_screen(void) | |||
773 | radio_mode = RADIO_SCAN_MODE; | 773 | radio_mode = RADIO_SCAN_MODE; |
774 | update_screen = true; | 774 | update_screen = true; |
775 | break; | 775 | break; |
776 | #endif | 776 | #endif /* FM_MODE */ |
777 | |||
777 | #ifdef FM_NEXT_PRESET | 778 | #ifdef FM_NEXT_PRESET |
778 | case ACTION_FM_NEXT_PRESET: | 779 | case ACTION_FM_NEXT_PRESET: |
779 | next_preset(1); | 780 | next_preset(1); |
780 | search_dir = 0; | 781 | end_search(); |
781 | update_screen = true; | 782 | update_screen = true; |
782 | break; | 783 | break; |
783 | #endif | 784 | #endif |
785 | |||
784 | #ifdef FM_PREV_PRESET | 786 | #ifdef FM_PREV_PRESET |
785 | case ACTION_FM_PREV_PRESET: | 787 | case ACTION_FM_PREV_PRESET: |
786 | next_preset(-1); | 788 | next_preset(-1); |
787 | search_dir = 0; | 789 | end_search(); |
788 | update_screen = true; | 790 | update_screen = true; |
789 | break; | 791 | break; |
790 | #endif | 792 | #endif |
@@ -794,8 +796,10 @@ int radio_screen(void) | |||
794 | break; | 796 | break; |
795 | } /*switch(button)*/ | 797 | } /*switch(button)*/ |
796 | 798 | ||
799 | #ifdef FM_RECORD_DBLPRE | ||
797 | if (button != ACTION_NONE) | 800 | if (button != ACTION_NONE) |
798 | lastbutton = button; | 801 | lastbutton = button; |
802 | #endif | ||
799 | 803 | ||
800 | #if CONFIG_CODEC != SWCODEC | 804 | #if CONFIG_CODEC != SWCODEC |
801 | peak_meter_peek(); | 805 | peak_meter_peek(); |
@@ -804,10 +808,9 @@ int radio_screen(void) | |||
804 | if(!screen_freeze) | 808 | if(!screen_freeze) |
805 | { | 809 | { |
806 | /* Only display the peak meter when not recording */ | 810 | /* Only display the peak meter when not recording */ |
811 | #if CONFIG_CODEC != SWCODEC | ||
807 | if(!audio_status()) | 812 | if(!audio_status()) |
808 | { | 813 | { |
809 | |||
810 | #if CONFIG_CODEC != SWCODEC | ||
811 | FOR_NB_SCREENS(i) | 814 | FOR_NB_SCREENS(i) |
812 | { | 815 | { |
813 | peak_meter_screen(&screens[i],0, | 816 | peak_meter_screen(&screens[i],0, |
@@ -815,44 +818,46 @@ int radio_screen(void) | |||
815 | screens[i].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4), | 818 | screens[i].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4), |
816 | screens[i].width, fh); | 819 | screens[i].width, fh); |
817 | } | 820 | } |
818 | #endif | ||
819 | |||
820 | } | 821 | } |
821 | 822 | ||
822 | if(TIME_AFTER(current_tick, timeout)) | 823 | if(TIME_AFTER(current_tick, timeout)) |
823 | { | 824 | { |
824 | timeout = current_tick + HZ; | 825 | timeout = current_tick + HZ; |
826 | #else /* SWCODEC */ | ||
827 | { | ||
828 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
825 | 829 | ||
826 | /* keep "mono" from always being displayed when paused */ | 830 | /* keep "mono" from always being displayed when paused */ |
827 | if (radio_status != FMRADIO_PAUSED) | 831 | if (radio_status != FMRADIO_PAUSED) |
828 | { | 832 | { |
829 | stereo = radio_get(RADIO_STEREO) && | 833 | stereo = radio_get(RADIO_STEREO) && |
830 | !global_settings.fm_force_mono; | 834 | !global_settings.fm_force_mono; |
831 | if(stereo != last_stereo_status) | 835 | |
836 | if(stereo != last_stereo) | ||
832 | { | 837 | { |
833 | update_screen = true; | 838 | update_screen = true; |
834 | last_stereo_status = stereo; | 839 | last_stereo = stereo; |
835 | } | 840 | } |
836 | } | 841 | } |
837 | } | 842 | } |
838 | 843 | ||
839 | #ifndef SIMULATOR | 844 | #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) |
840 | #if CONFIG_CODEC != SWCODEC | ||
841 | seconds = audio_recorded_time() / HZ; | 845 | seconds = audio_recorded_time() / HZ; |
842 | #endif | 846 | if (update_screen || seconds > last_seconds) |
843 | #endif | ||
844 | if(update_screen || seconds > last_seconds) | ||
845 | { | 847 | { |
846 | last_seconds = seconds; | 848 | last_seconds = seconds; |
849 | #else | ||
850 | if (update_screen) | ||
851 | { | ||
852 | #endif | ||
853 | int freq; | ||
847 | 854 | ||
848 | FOR_NB_SCREENS(i) | 855 | FOR_NB_SCREENS(i) |
849 | screens[i].setfont(FONT_UI); | 856 | screens[i].setfont(FONT_UI); |
850 | 857 | ||
851 | if (curr_preset >= 0 ) | 858 | snprintf(buf, 128, curr_preset >= 0 ? "%d. %s" : " ", |
852 | snprintf(buf, 128, "%d. %s",curr_preset + 1, | 859 | curr_preset + 1, presets[curr_preset].name); |
853 | presets[curr_preset].name); | 860 | |
854 | else | ||
855 | snprintf(buf, 128, " "); | ||
856 | FOR_NB_SCREENS(i) | 861 | FOR_NB_SCREENS(i) |
857 | screens[i].puts_scroll(0, top_of_screen, buf); | 862 | screens[i].puts_scroll(0, top_of_screen, buf); |
858 | 863 | ||
@@ -871,6 +876,7 @@ int radio_screen(void) | |||
871 | str(LANG_RADIO_SCAN_MODE)); | 876 | str(LANG_RADIO_SCAN_MODE)); |
872 | FOR_NB_SCREENS(i) | 877 | FOR_NB_SCREENS(i) |
873 | screens[i].puts_scroll(0, top_of_screen + 3, buf); | 878 | screens[i].puts_scroll(0, top_of_screen + 3, buf); |
879 | |||
874 | #if CONFIG_CODEC != SWCODEC | 880 | #if CONFIG_CODEC != SWCODEC |
875 | if(audio_status() == AUDIO_STATUS_RECORD) | 881 | if(audio_status() == AUDIO_STATUS_RECORD) |
876 | { | 882 | { |
@@ -892,7 +898,7 @@ int radio_screen(void) | |||
892 | screens[i].puts_scroll(0, top_of_screen + 4, buf); | 898 | screens[i].puts_scroll(0, top_of_screen + 4, buf); |
893 | } | 899 | } |
894 | } | 900 | } |
895 | #endif | 901 | #endif /* CONFIG_CODEC != SWCODEC */ |
896 | 902 | ||
897 | #ifdef HAS_BUTTONBAR | 903 | #ifdef HAS_BUTTONBAR |
898 | gui_buttonbar_draw(&buttonbar); | 904 | gui_buttonbar_draw(&buttonbar); |
@@ -902,21 +908,27 @@ int radio_screen(void) | |||
902 | } | 908 | } |
903 | /* Only force the redraw if update_screen is true */ | 909 | /* Only force the redraw if update_screen is true */ |
904 | gui_syncstatusbar_draw(&statusbars,true); | 910 | gui_syncstatusbar_draw(&statusbars,true); |
905 | |||
906 | update_screen = false; | ||
907 | } | 911 | } |
908 | 912 | ||
913 | update_screen = false; | ||
914 | |||
915 | #if CONFIG_CODEC != SWCODEC | ||
909 | if(audio_status() & AUDIO_STATUS_ERROR) | 916 | if(audio_status() & AUDIO_STATUS_ERROR) |
910 | { | 917 | { |
911 | done = true; | 918 | done = true; |
912 | } | 919 | } |
920 | #endif | ||
921 | |||
922 | #ifndef HAVE_NOISY_IDLE_MODE | ||
913 | if (TIME_AFTER(current_tick, button_timeout)) | 923 | if (TIME_AFTER(current_tick, button_timeout)) |
914 | { | 924 | { |
915 | cpu_idle_mode(true); | 925 | cpu_idle_mode(true); |
916 | } | 926 | } |
927 | #endif | ||
917 | } /*while(!done)*/ | 928 | } /*while(!done)*/ |
918 | 929 | ||
919 | #ifndef SIMULATOR | 930 | #ifndef SIMULATOR |
931 | #if CONFIG_CODEC != SWCODEC | ||
920 | if(audio_status() & AUDIO_STATUS_ERROR) | 932 | if(audio_status() & AUDIO_STATUS_ERROR) |
921 | { | 933 | { |
922 | gui_syncsplash(0, true, str(LANG_DISK_FULL)); | 934 | gui_syncsplash(0, true, str(LANG_DISK_FULL)); |
@@ -933,16 +945,15 @@ int radio_screen(void) | |||
933 | } | 945 | } |
934 | } | 946 | } |
935 | 947 | ||
936 | #if CONFIG_CODEC != SWCODEC | ||
937 | audio_init_playback(); | 948 | audio_init_playback(); |
938 | #endif | 949 | #endif /* CONFIG_CODEC != SWCODEC */ |
939 | 950 | ||
940 | sound_settings_apply(); | 951 | sound_settings_apply(); |
941 | #endif /* SIMULATOR */ | 952 | #endif /* SIMULATOR */ |
942 | 953 | ||
943 | if(keep_playing) | 954 | if(keep_playing) |
944 | { | 955 | { |
945 | /* Catch FMRADIO_PLAYING status for the sim. */ | 956 | /* Catch FMRADIO_PLAYING status for the sim. */ |
946 | #ifndef SIMULATOR | 957 | #ifndef SIMULATOR |
947 | #if CONFIG_CODEC != SWCODEC | 958 | #if CONFIG_CODEC != SWCODEC |
948 | /* Enable the Left and right A/D Converter */ | 959 | /* Enable the Left and right A/D Converter */ |
@@ -951,7 +962,8 @@ int radio_screen(void) | |||
951 | AUDIO_GAIN_LINEIN); | 962 | AUDIO_GAIN_LINEIN); |
952 | mas_codec_writereg(6, 0x4000); | 963 | mas_codec_writereg(6, 0x4000); |
953 | #endif | 964 | #endif |
954 | #endif | 965 | end_search(); |
966 | #endif /* SIMULATOR */ | ||
955 | } | 967 | } |
956 | else | 968 | else |
957 | { | 969 | { |
@@ -961,15 +973,20 @@ int radio_screen(void) | |||
961 | radio_stop(); | 973 | radio_stop(); |
962 | #endif | 974 | #endif |
963 | } | 975 | } |
964 | 976 | ||
977 | #ifndef HAVE_NOISY_IDLE_MODE | ||
965 | cpu_idle_mode(false); | 978 | cpu_idle_mode(false); |
979 | #endif | ||
966 | 980 | ||
967 | /* restore status bar settings */ | 981 | /* restore status bar settings */ |
968 | global_settings.statusbar = statusbar; | 982 | global_settings.statusbar = statusbar; |
969 | 983 | ||
970 | in_screen = false; | 984 | in_screen = false; |
971 | 985 | #if CONFIG_CODEC != SWCODEC | |
972 | return have_recorded; | 986 | return have_recorded; |
987 | #else | ||
988 | return false; | ||
989 | #endif | ||
973 | } /* radio_screen */ | 990 | } /* radio_screen */ |
974 | 991 | ||
975 | static void radio_save_presets(void) | 992 | static void radio_save_presets(void) |
@@ -1006,7 +1023,6 @@ void radio_load_presets(char *filename) | |||
1006 | bool done = false; | 1023 | bool done = false; |
1007 | int f; | 1024 | int f; |
1008 | 1025 | ||
1009 | |||
1010 | memset(presets, 0, sizeof(presets)); | 1026 | memset(presets, 0, sizeof(presets)); |
1011 | num_presets = 0; | 1027 | num_presets = 0; |
1012 | 1028 | ||
@@ -1037,9 +1053,10 @@ void radio_load_presets(char *filename) | |||
1037 | f = atoi(freq); | 1053 | f = atoi(freq); |
1038 | if(f) /* For backwards compatibility */ | 1054 | if(f) /* For backwards compatibility */ |
1039 | { | 1055 | { |
1040 | presets[num_presets].frequency = f; | 1056 | struct fmstation * const fms = &presets[num_presets]; |
1041 | strncpy(presets[num_presets].name, name, MAX_FMPRESET_LEN); | 1057 | fms->frequency = f; |
1042 | presets[num_presets].name[MAX_FMPRESET_LEN] = 0; | 1058 | strncpy(fms->name, name, MAX_FMPRESET_LEN); |
1059 | fms->name[MAX_FMPRESET_LEN] = '\0'; | ||
1043 | num_presets++; | 1060 | num_presets++; |
1044 | } | 1061 | } |
1045 | } | 1062 | } |
@@ -1051,12 +1068,8 @@ void radio_load_presets(char *filename) | |||
1051 | } | 1068 | } |
1052 | else /* invalid file name? */ | 1069 | else /* invalid file name? */ |
1053 | filepreset[0] = '\0'; | 1070 | filepreset[0] = '\0'; |
1054 | 1071 | ||
1055 | if(num_presets > 0) | 1072 | presets_loaded = num_presets > 0; |
1056 | presets_loaded = true; | ||
1057 | else | ||
1058 | presets_loaded = false; | ||
1059 | |||
1060 | presets_changed = false; | 1073 | presets_changed = false; |
1061 | } | 1074 | } |
1062 | 1075 | ||
@@ -1071,13 +1084,13 @@ static int radio_add_preset(void) | |||
1071 | 1084 | ||
1072 | if (!kbd_input(buf, MAX_FMPRESET_LEN)) | 1085 | if (!kbd_input(buf, MAX_FMPRESET_LEN)) |
1073 | { | 1086 | { |
1074 | buf[MAX_FMPRESET_LEN] = 0; | 1087 | struct fmstation * const fms = &presets[num_presets]; |
1075 | strcpy(presets[num_presets].name, buf); | 1088 | buf[MAX_FMPRESET_LEN] = '\0'; |
1076 | presets[num_presets].frequency = curr_freq; | 1089 | strcpy(fms->name, buf); |
1090 | fms->frequency = curr_freq; | ||
1077 | num_presets++; | 1091 | num_presets++; |
1078 | presets_changed = true; | 1092 | presets_changed = true; |
1079 | if(num_presets > 0) | 1093 | presets_loaded = num_presets > 0; |
1080 | presets_loaded = true; | ||
1081 | } | 1094 | } |
1082 | } | 1095 | } |
1083 | else | 1096 | else |
@@ -1088,43 +1101,53 @@ static int radio_add_preset(void) | |||
1088 | } | 1101 | } |
1089 | 1102 | ||
1090 | /* needed to know which preset we are edit/delete-ing */ | 1103 | /* needed to know which preset we are edit/delete-ing */ |
1091 | static int selected_preset = 0; | 1104 | static int selected_preset = -1; |
1092 | static int radio_edit_preset(void) | 1105 | static int radio_edit_preset(void) |
1093 | { | 1106 | { |
1094 | char buf[MAX_FMPRESET_LEN]; | 1107 | char buf[MAX_FMPRESET_LEN]; |
1095 | 1108 | ||
1096 | strncpy(buf, presets[selected_preset].name, MAX_FMPRESET_LEN); | 1109 | if (num_presets > 0) |
1097 | |||
1098 | if (!kbd_input(buf, MAX_FMPRESET_LEN)) | ||
1099 | { | 1110 | { |
1100 | buf[MAX_FMPRESET_LEN] = 0; | 1111 | struct fmstation * const fms = &presets[selected_preset]; |
1101 | strcpy(presets[selected_preset].name, buf); | 1112 | |
1102 | presets_changed = true; | 1113 | strncpy(buf, fms->name, MAX_FMPRESET_LEN); |
1114 | |||
1115 | if (!kbd_input(buf, MAX_FMPRESET_LEN)) | ||
1116 | { | ||
1117 | buf[MAX_FMPRESET_LEN] = '\0'; | ||
1118 | strcpy(fms->name, buf); | ||
1119 | presets_changed = true; | ||
1120 | } | ||
1103 | } | 1121 | } |
1122 | |||
1104 | return true; | 1123 | return true; |
1105 | } | 1124 | } |
1106 | 1125 | ||
1107 | static int radio_delete_preset(void) | 1126 | static int radio_delete_preset(void) |
1108 | { | 1127 | { |
1109 | int pos = selected_preset; | 1128 | if (num_presets > 0) |
1110 | int i; | 1129 | { |
1130 | struct fmstation * const fms = &presets[selected_preset]; | ||
1131 | |||
1132 | if (selected_preset >= --num_presets) | ||
1133 | selected_preset = num_presets - 1; | ||
1111 | 1134 | ||
1112 | for(i = pos;i < num_presets;i++) | 1135 | memmove(fms, fms + 1, (uintptr_t)(fms + num_presets) - |
1113 | presets[i] = presets[i+1]; | 1136 | (uintptr_t)fms); |
1114 | num_presets--; | 1137 | |
1138 | } | ||
1115 | 1139 | ||
1116 | /* Don't ask to save when all presets are deleted. */ | 1140 | /* Don't ask to save when all presets are deleted. */ |
1117 | if(num_presets > 0) | 1141 | presets_changed = num_presets > 0; |
1118 | presets_changed = true; | 1142 | |
1119 | else | 1143 | if (!presets_changed) |
1120 | { | 1144 | { |
1121 | presets_changed = false; | ||
1122 | /* The preset list will be cleared, switch to Scan Mode. */ | 1145 | /* The preset list will be cleared, switch to Scan Mode. */ |
1123 | radio_mode = RADIO_SCAN_MODE; | 1146 | radio_mode = RADIO_SCAN_MODE; |
1124 | presets_loaded = false; | 1147 | presets_loaded = false; |
1125 | } | 1148 | } |
1126 | 1149 | ||
1127 | return true; /* Make the menu return immediately */ | 1150 | return true; |
1128 | } | 1151 | } |
1129 | 1152 | ||
1130 | static int load_preset_list(void) | 1153 | static int load_preset_list(void) |
@@ -1134,7 +1157,7 @@ static int load_preset_list(void) | |||
1134 | 1157 | ||
1135 | static int save_preset_list(void) | 1158 | static int save_preset_list(void) |
1136 | { | 1159 | { |
1137 | if(num_presets != 0) | 1160 | if(num_presets > 0) |
1138 | { | 1161 | { |
1139 | bool bad_file_name = true; | 1162 | bool bad_file_name = true; |
1140 | 1163 | ||
@@ -1187,13 +1210,8 @@ static int save_preset_list(void) | |||
1187 | 1210 | ||
1188 | static int clear_preset_list(void) | 1211 | static int clear_preset_list(void) |
1189 | { | 1212 | { |
1190 | int i; | ||
1191 | |||
1192 | /* Clear all the preset entries */ | 1213 | /* Clear all the preset entries */ |
1193 | for(i = 0;i <= num_presets;i++){ | 1214 | memset(presets, 0, sizeof (presets)); |
1194 | presets[i].name[0] = '\0'; | ||
1195 | presets[i].frequency = 0; | ||
1196 | } | ||
1197 | 1215 | ||
1198 | num_presets = 0; | 1216 | num_presets = 0; |
1199 | presets_loaded = false; | 1217 | presets_loaded = false; |
@@ -1211,10 +1229,10 @@ MENUITEM_FUNCTION(radio_delete_preset_item, ID2P(LANG_FM_DELETE_PRESET), | |||
1211 | radio_delete_preset, NULL, Icon_NOICON); | 1229 | radio_delete_preset, NULL, Icon_NOICON); |
1212 | int radio_preset_callback(int action, const struct menu_item_ex *this_item) | 1230 | int radio_preset_callback(int action, const struct menu_item_ex *this_item) |
1213 | { | 1231 | { |
1214 | (void)this_item; | ||
1215 | if (action == ACTION_STD_OK) | 1232 | if (action == ACTION_STD_OK) |
1216 | return ACTION_EXIT_AFTER_THIS_MENUITEM; | 1233 | action = ACTION_EXIT_AFTER_THIS_MENUITEM; |
1217 | return action; | 1234 | return action; |
1235 | (void)this_item; | ||
1218 | } | 1236 | } |
1219 | MAKE_MENU(handle_radio_preset_menu, ID2P(LANG_FM_BUTTONBAR_PRESETS), | 1237 | MAKE_MENU(handle_radio_preset_menu, ID2P(LANG_FM_BUTTONBAR_PRESETS), |
1220 | radio_preset_callback, Icon_NOICON, &radio_edit_preset_item, | 1238 | radio_preset_callback, Icon_NOICON, &radio_edit_preset_item, |
@@ -1272,7 +1290,7 @@ static int handle_radio_presets(void) | |||
1272 | case ACTION_STD_OK: | 1290 | case ACTION_STD_OK: |
1273 | curr_preset = gui_synclist_get_sel_pos(&lists); | 1291 | curr_preset = gui_synclist_get_sel_pos(&lists); |
1274 | curr_freq = presets[curr_preset].frequency; | 1292 | curr_freq = presets[curr_preset].frequency; |
1275 | radio_set(RADIO_FREQUENCY, curr_freq); | 1293 | next_station(0); |
1276 | remember_frequency(); | 1294 | remember_frequency(); |
1277 | result = 1; | 1295 | result = 1; |
1278 | break; | 1296 | break; |
@@ -1302,15 +1320,7 @@ void set_radio_region(int region) | |||
1302 | fm_region[region].deemphasis); | 1320 | fm_region[region].deemphasis); |
1303 | radio_set(RADIO_SET_BAND, fm_region[region].band); | 1321 | radio_set(RADIO_SET_BAND, fm_region[region].band); |
1304 | #endif | 1322 | #endif |
1305 | /* make sure the current frequency is in the region range */ | 1323 | next_station(0); |
1306 | curr_freq -= (curr_freq - fm_region[region].freq_min) | ||
1307 | % fm_region[region].freq_step; | ||
1308 | if(curr_freq < fm_region[region].freq_min) | ||
1309 | curr_freq = fm_region[region].freq_min; | ||
1310 | if(curr_freq > fm_region[region].freq_max) | ||
1311 | curr_freq = fm_region[region].freq_max; | ||
1312 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
1313 | |||
1314 | remember_frequency(); | 1324 | remember_frequency(); |
1315 | } | 1325 | } |
1316 | 1326 | ||
@@ -1340,52 +1350,52 @@ MENUITEM_FUNCTION_WPARAM_DYNTEXT(radio_mode_item, toggle_radio_mode, NULL, NULL, | |||
1340 | 1350 | ||
1341 | static int scan_presets(void) | 1351 | static int scan_presets(void) |
1342 | { | 1352 | { |
1343 | bool tuned = false, do_scan = true; | 1353 | bool do_scan = true; |
1344 | char buf[MAX_FMPRESET_LEN]; | ||
1345 | int freq, i; | ||
1346 | 1354 | ||
1347 | if(num_presets > 0) /* Do that to avoid 2 questions. */ | 1355 | if(num_presets > 0) /* Do that to avoid 2 questions. */ |
1348 | do_scan = yesno_pop(str(LANG_FM_CLEAR_PRESETS)); | 1356 | do_scan = yesno_pop(str(LANG_FM_CLEAR_PRESETS)); |
1349 | 1357 | ||
1350 | if(do_scan) | 1358 | if(do_scan) |
1351 | { | 1359 | { |
1352 | curr_freq = fm_region[global_settings.fm_region].freq_min; | 1360 | const struct fm_region_setting * const fmr = |
1361 | &fm_region[global_settings.fm_region]; | ||
1362 | char buf[MAX_FMPRESET_LEN]; | ||
1363 | int i; | ||
1364 | |||
1365 | curr_freq = fmr->freq_min; | ||
1353 | num_presets = 0; | 1366 | num_presets = 0; |
1354 | memset(presets, 0, sizeof(presets)); | 1367 | memset(presets, 0, sizeof(presets)); |
1355 | while(curr_freq <= fm_region[global_settings.fm_region].freq_max) | 1368 | radio_set(RADIO_MUTE, 1); |
1369 | |||
1370 | while(curr_freq <= fmr->freq_max) | ||
1356 | { | 1371 | { |
1372 | int freq, frac; | ||
1357 | if (num_presets >= MAX_PRESETS || action_userabort(TIMEOUT_NOBLOCK)) | 1373 | if (num_presets >= MAX_PRESETS || action_userabort(TIMEOUT_NOBLOCK)) |
1358 | break; | 1374 | break; |
1359 | 1375 | ||
1360 | freq = curr_freq / 10000; | 1376 | freq = curr_freq / 10000; |
1361 | snprintf(buf, MAX_FMPRESET_LEN, str(LANG_FM_SCANNING), | 1377 | frac = freq % 100; |
1362 | freq/100, freq % 100); | 1378 | freq /= 100; |
1379 | |||
1380 | snprintf(buf, MAX_FMPRESET_LEN, str(LANG_FM_SCANNING), freq, frac); | ||
1363 | gui_syncsplash(0, true, buf); | 1381 | gui_syncsplash(0, true, buf); |
1364 | 1382 | ||
1365 | /* Tune in and delay */ | 1383 | if(radio_set(RADIO_SCAN_FREQUENCY, curr_freq)) |
1366 | radio_set(RADIO_FREQUENCY, curr_freq); | 1384 | { |
1367 | sleep(1); | 1385 | /* add preset */ |
1368 | 1386 | snprintf(buf, MAX_FMPRESET_LEN, | |
1369 | /* Start IF measurement */ | 1387 | str(LANG_FM_DEFAULT_PRESET_NAME), freq, frac); |
1370 | radio_set(RADIO_IF_MEASUREMENT, 1); | 1388 | strcpy(presets[num_presets].name,buf); |
1371 | sleep(1); | 1389 | presets[num_presets].frequency = curr_freq; |
1372 | 1390 | num_presets++; | |
1373 | /* Now check how close to the IF frequency we are */ | ||
1374 | tuned = radio_get(RADIO_TUNED); | ||
1375 | |||
1376 | /* add preset */ | ||
1377 | if(tuned){ | ||
1378 | snprintf(buf, MAX_FMPRESET_LEN, | ||
1379 | str(LANG_FM_DEFAULT_PRESET_NAME),freq/100, freq % 100); | ||
1380 | strcpy(presets[num_presets].name,buf); | ||
1381 | presets[num_presets].frequency = curr_freq; | ||
1382 | num_presets++; | ||
1383 | } | 1391 | } |
1384 | 1392 | ||
1385 | curr_freq += fm_region[global_settings.fm_region].freq_step; | 1393 | curr_freq += fmr->freq_step; |
1386 | |||
1387 | } | 1394 | } |
1388 | 1395 | ||
1396 | if (radio_status == FMRADIO_PLAYING) | ||
1397 | radio_set(RADIO_MUTE, 0); | ||
1398 | |||
1389 | presets_changed = true; | 1399 | presets_changed = true; |
1390 | 1400 | ||
1391 | FOR_NB_SCREENS(i) | 1401 | FOR_NB_SCREENS(i) |
@@ -1395,22 +1405,24 @@ static int scan_presets(void) | |||
1395 | gui_textarea_update(&screens[i]); | 1405 | gui_textarea_update(&screens[i]); |
1396 | } | 1406 | } |
1397 | 1407 | ||
1398 | if(num_presets > 0 ) | 1408 | if(num_presets > 0) |
1399 | { | 1409 | { |
1400 | curr_freq = presets[0].frequency; | 1410 | curr_freq = presets[0].frequency; |
1401 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
1402 | remember_frequency(); | ||
1403 | radio_mode = RADIO_PRESET_MODE; | 1411 | radio_mode = RADIO_PRESET_MODE; |
1404 | presets_loaded = true; | 1412 | presets_loaded = true; |
1413 | next_station(0); | ||
1405 | } | 1414 | } |
1406 | else | 1415 | else |
1416 | { | ||
1417 | /* Wrap it to beginning or we'll be past end of band */ | ||
1407 | presets_loaded = false; | 1418 | presets_loaded = false; |
1419 | next_station(1); | ||
1420 | } | ||
1408 | } | 1421 | } |
1409 | return true; | 1422 | return true; |
1410 | } | 1423 | } |
1411 | 1424 | ||
1412 | 1425 | ||
1413 | #ifndef SIMULATOR | ||
1414 | #ifdef HAVE_RECORDING | 1426 | #ifdef HAVE_RECORDING |
1415 | 1427 | ||
1416 | #if defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC | 1428 | #if defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC |
@@ -1433,8 +1445,6 @@ static int fm_recording_screen(void) | |||
1433 | 1445 | ||
1434 | return ret; | 1446 | return ret; |
1435 | } | 1447 | } |
1436 | MENUITEM_FUNCTION(recscreen_item, ID2P(LANG_RECORDING_MENU), | ||
1437 | fm_recording_screen, NULL, Icon_NOICON); | ||
1438 | #endif /* defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC */ | 1448 | #endif /* defined(HAVE_FMRADIO_IN) && CONFIG_CODEC == SWCODEC */ |
1439 | 1449 | ||
1440 | #if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC | 1450 | #if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC |
@@ -1442,6 +1452,7 @@ MENUITEM_FUNCTION(recscreen_item, ID2P(LANG_RECORDING_MENU), | |||
1442 | static int fm_recording_settings(void) | 1452 | static int fm_recording_settings(void) |
1443 | { | 1453 | { |
1444 | bool ret = recording_menu(true); | 1454 | bool ret = recording_menu(true); |
1455 | |||
1445 | #if CONFIG_CODEC != SWCODEC | 1456 | #if CONFIG_CODEC != SWCODEC |
1446 | if (!ret) | 1457 | if (!ret) |
1447 | { | 1458 | { |
@@ -1454,11 +1465,17 @@ static int fm_recording_settings(void) | |||
1454 | 1465 | ||
1455 | return ret; | 1466 | return ret; |
1456 | } | 1467 | } |
1457 | MENUITEM_FUNCTION(recsettings_item, ID2P(LANG_RECORDING_SETTINGS), | ||
1458 | fm_recording_settings, NULL, Icon_NOICON); | ||
1459 | #endif /* defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC */ | 1468 | #endif /* defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC */ |
1460 | #endif /* HAVE_RECORDING */ | 1469 | #endif /* HAVE_RECORDING */ |
1461 | #endif /* SIMULATOR */ | 1470 | |
1471 | #ifdef FM_RECORDING_SCREEN | ||
1472 | MENUITEM_FUNCTION(recscreen_item, ID2P(LANG_RECORDING_MENU), | ||
1473 | fm_recording_screen, NULL, Icon_NOICON); | ||
1474 | #endif | ||
1475 | #ifdef FM_RECORDING_SETTINGS | ||
1476 | MENUITEM_FUNCTION(recsettings_item, ID2P(LANG_RECORDING_SETTINGS), | ||
1477 | fm_recording_settings, NULL, Icon_NOICON); | ||
1478 | #endif | ||
1462 | #ifndef FM_PRESET | 1479 | #ifndef FM_PRESET |
1463 | MENUITEM_FUNCTION(radio_presets_item, ID2P(LANG_FM_BUTTONBAR_PRESETS), | 1480 | MENUITEM_FUNCTION(radio_presets_item, ID2P(LANG_FM_BUTTONBAR_PRESETS), |
1464 | handle_radio_presets, NULL, Icon_NOICON); | 1481 | handle_radio_presets, NULL, Icon_NOICON); |
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index add3989061..f04c14d6d3 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h | |||
@@ -50,8 +50,14 @@ struct fm_region_setting | |||
50 | int freq_max; | 50 | int freq_max; |
51 | int freq_step; | 51 | int freq_step; |
52 | #if (CONFIG_TUNER & TEA5767) | 52 | #if (CONFIG_TUNER & TEA5767) |
53 | int deemphasis; /* 0: 50us, 1: 75us */ | 53 | char deemphasis; /* 0: 50us, 1: 75us */ |
54 | int band; /* 0: europe, 1: japan (BL in TEA spec)*/ | 54 | char band; /* 0: europe, 1: japan (BL in TEA spec)*/ |
55 | /* Note: "region" parameter is just for display atm and is not compiled. */ | ||
56 | #define FM_REGION_ENTRY(region, fmin, fmax, fstep, deemph, band) \ | ||
57 | { fmin, fmax, fstep, deemph, band } | ||
58 | #else | ||
59 | #define FM_REGION_ENTRY(region, fmin, fmax, fstep, deemph, band) \ | ||
60 | { fmin, fmax, fstep } | ||
55 | #endif | 61 | #endif |
56 | }; | 62 | }; |
57 | 63 | ||