diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/lang/english.lang | 36 | ||||
-rw-r--r-- | apps/recorder/radio.c | 390 |
2 files changed, 281 insertions, 145 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 20195cfbd4..2944e562a8 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -2721,3 +2721,39 @@ desc: browser sorting setting | |||
2721 | eng: "by type" | 2721 | eng: "by type" |
2722 | voice: "by type" | 2722 | voice: "by type" |
2723 | new: | 2723 | new: |
2724 | |||
2725 | id: LANG_FM_EDIT_PRESET | ||
2726 | desc: in radio screen | ||
2727 | eng: "Edit preset" | ||
2728 | voice: "Edit preset" | ||
2729 | new: | ||
2730 | |||
2731 | id: LANG_FM_MONO_MODE | ||
2732 | desc: in radio screen | ||
2733 | eng: "Force mono" | ||
2734 | voice: "Force mono" | ||
2735 | new: | ||
2736 | |||
2737 | id: LANG_FM_BUTTONBAR_EXIT | ||
2738 | desc: in radio screen | ||
2739 | eng: "Exit" | ||
2740 | voice: "Exit" | ||
2741 | new: | ||
2742 | |||
2743 | id: LANG_FM_BUTTONBAR_EDIT | ||
2744 | desc: in radio screen | ||
2745 | eng: "Edit" | ||
2746 | voice: "Edit" | ||
2747 | new: | ||
2748 | |||
2749 | id: LANG_FM_BUTTONBAR_ADD | ||
2750 | desc: in radio screen | ||
2751 | eng: "Add" | ||
2752 | voice: "Add" | ||
2753 | new: | ||
2754 | |||
2755 | id: LANG_FM_BUTTONBAR_ACTION | ||
2756 | desc: in radio screen | ||
2757 | eng: "Action" | ||
2758 | voice: "Action" | ||
2759 | new: | ||
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index f75387739a..d4dc8a93aa 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c | |||
@@ -55,6 +55,18 @@ | |||
55 | #define PLL_FREQ_STEP 10000 | 55 | #define PLL_FREQ_STEP 10000 |
56 | #define FREQ_STEP 100000 | 56 | #define FREQ_STEP 100000 |
57 | 57 | ||
58 | #define RADIO_FREQUENCY 0 | ||
59 | #define RADIO_MUTE 1 | ||
60 | #define RADIO_IF_MEASUREMENT 2 | ||
61 | #define RADIO_SENSITIVITY 3 | ||
62 | #define RADIO_FORCE_MONO 4 | ||
63 | |||
64 | #define DEFAULT_IN1 0x100003 /* Mute */ | ||
65 | #define DEFAULT_IN2 0x140884 /* 5kHz, 7.2MHz crystal */ | ||
66 | |||
67 | static int fm_in1 = DEFAULT_IN1; | ||
68 | static int fm_in2 = DEFAULT_IN2; | ||
69 | |||
58 | static int curr_preset = -1; | 70 | static int curr_preset = -1; |
59 | static int curr_freq = 99400000; | 71 | static int curr_freq = 99400000; |
60 | static int pll_cnt; | 72 | static int pll_cnt; |
@@ -67,15 +79,59 @@ static char default_filename[] = "/.rockbox/fm-presets-default.fmr"; | |||
67 | 79 | ||
68 | int debug_fm_detection; | 80 | int debug_fm_detection; |
69 | 81 | ||
82 | static int preset_menu; /* The menu index of the preset list */ | ||
83 | static struct menu_item preset_menu_items[MAX_PRESETS]; | ||
84 | static int num_presets; /* The number of presets in the preset list */ | ||
85 | |||
70 | void radio_load_presets(void); | 86 | void radio_load_presets(void); |
71 | bool radio_preset_select(void); | 87 | bool handle_radio_presets(void); |
72 | bool radio_menu(void); | 88 | bool radio_menu(void); |
73 | 89 | ||
74 | void radio_stop(void) | 90 | void radio_set(int setting, int value) |
75 | { | 91 | { |
76 | /* Mute the FM radio */ | 92 | switch(setting) |
77 | fmradio_set(1, 0x100003); | 93 | { |
94 | case RADIO_FREQUENCY: | ||
95 | /* We add the standard Intermediate Frequency 10.7MHz | ||
96 | ** before calculating the divisor | ||
97 | ** The reference frequency is set to 50kHz, and the VCO | ||
98 | ** output is prescaled by 2. | ||
99 | */ | ||
100 | |||
101 | pll_cnt = (value + 10700000) / (PLL_FREQ_STEP/2) / 2; | ||
102 | |||
103 | /* 0x100000 == FM mode | ||
104 | ** 0x000002 == Microprocessor controlled Mute | ||
105 | */ | ||
106 | fm_in1 = (fm_in1 & 0xfff00007) | (pll_cnt << 3); | ||
107 | fmradio_set(1, fm_in1); | ||
108 | break; | ||
109 | |||
110 | case RADIO_MUTE: | ||
111 | fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0); | ||
112 | fmradio_set(1, fm_in1); | ||
113 | break; | ||
114 | |||
115 | case RADIO_IF_MEASUREMENT: | ||
116 | fm_in1 = (fm_in1 & 0xfffffffb) | (value?4:0); | ||
117 | fmradio_set(1, fm_in1); | ||
118 | break; | ||
119 | |||
120 | case RADIO_SENSITIVITY: | ||
121 | fm_in2 = (fm_in2 & 0xffff9fff) | ((value & 3) << 13); | ||
122 | fmradio_set(2, fm_in2); | ||
123 | break; | ||
124 | |||
125 | case RADIO_FORCE_MONO: | ||
126 | fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4); | ||
127 | fmradio_set(2, fm_in2); | ||
128 | break; | ||
129 | } | ||
130 | } | ||
78 | 131 | ||
132 | void radio_stop(void) | ||
133 | { | ||
134 | radio_set(RADIO_MUTE, 1); | ||
79 | } | 135 | } |
80 | 136 | ||
81 | bool radio_hardware_present(void) | 137 | bool radio_hardware_present(void) |
@@ -91,22 +147,6 @@ bool radio_hardware_present(void) | |||
91 | return false; | 147 | return false; |
92 | } | 148 | } |
93 | 149 | ||
94 | void radio_set_frequency(int freq) | ||
95 | { | ||
96 | /* We add the standard Intermediate Frequency 10.7MHz before calculating | ||
97 | ** the divisor | ||
98 | ** The reference frequency is set to 50kHz, and the VCO output is prescaled | ||
99 | ** by 2. | ||
100 | */ | ||
101 | |||
102 | pll_cnt = (freq + 10700000) / (PLL_FREQ_STEP/2) / 2; | ||
103 | |||
104 | /* 0x100000 == FM mode | ||
105 | ** 0x000002 == Microprocessor controlled Mute | ||
106 | */ | ||
107 | fmradio_set(1, 0x100002 | pll_cnt << 3); | ||
108 | } | ||
109 | |||
110 | static int find_preset(int freq) | 150 | static int find_preset(int freq) |
111 | { | 151 | { |
112 | int i; | 152 | int i; |
@@ -192,8 +232,15 @@ bool radio_screen(void) | |||
192 | mpeg_sound_default(SOUND_RIGHT_GAIN), false); | 232 | mpeg_sound_default(SOUND_RIGHT_GAIN), false); |
193 | #endif | 233 | #endif |
194 | 234 | ||
195 | fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */ | 235 | fmradio_set(1, DEFAULT_IN1); |
196 | radio_set_frequency(curr_freq); | 236 | fmradio_set(2, DEFAULT_IN2); |
237 | |||
238 | radio_set(RADIO_FREQUENCY, curr_freq); | ||
239 | radio_set(RADIO_IF_MEASUREMENT, 0); | ||
240 | radio_set(RADIO_SENSITIVITY, 0); | ||
241 | radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); | ||
242 | radio_set(RADIO_MUTE, 0); | ||
243 | |||
197 | curr_preset = find_preset(curr_freq); | 244 | curr_preset = find_preset(curr_freq); |
198 | 245 | ||
199 | buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), | 246 | buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), |
@@ -210,11 +257,11 @@ bool radio_screen(void) | |||
210 | curr_freq = MIN_FREQ; | 257 | curr_freq = MIN_FREQ; |
211 | 258 | ||
212 | /* Tune in and delay */ | 259 | /* Tune in and delay */ |
213 | radio_set_frequency(curr_freq); | 260 | radio_set(RADIO_FREQUENCY, curr_freq); |
214 | sleep(1); | 261 | sleep(1); |
215 | 262 | ||
216 | /* Start IF measurement */ | 263 | /* Start IF measurement */ |
217 | fmradio_set(1, 0x100006 | pll_cnt << 3); | 264 | radio_set(RADIO_IF_MEASUREMENT, 1); |
218 | sleep(1); | 265 | sleep(1); |
219 | 266 | ||
220 | /* Now check how close to the IF frequency we are */ | 267 | /* Now check how close to the IF frequency we are */ |
@@ -280,7 +327,7 @@ bool radio_screen(void) | |||
280 | if(curr_freq < MIN_FREQ) | 327 | if(curr_freq < MIN_FREQ) |
281 | curr_freq = MIN_FREQ; | 328 | curr_freq = MIN_FREQ; |
282 | 329 | ||
283 | radio_set_frequency(curr_freq); | 330 | radio_set(RADIO_FREQUENCY, curr_freq); |
284 | curr_preset = find_preset(curr_freq); | 331 | curr_preset = find_preset(curr_freq); |
285 | search_dir = 0; | 332 | search_dir = 0; |
286 | update_screen = true; | 333 | update_screen = true; |
@@ -291,7 +338,7 @@ bool radio_screen(void) | |||
291 | if(curr_freq > MAX_FREQ) | 338 | if(curr_freq > MAX_FREQ) |
292 | curr_freq = MAX_FREQ; | 339 | curr_freq = MAX_FREQ; |
293 | 340 | ||
294 | radio_set_frequency(curr_freq); | 341 | radio_set(RADIO_FREQUENCY, curr_freq); |
295 | curr_preset = find_preset(curr_freq); | 342 | curr_preset = find_preset(curr_freq); |
296 | search_dir = 0; | 343 | search_dir = 0; |
297 | update_screen = true; | 344 | update_screen = true; |
@@ -337,7 +384,7 @@ bool radio_screen(void) | |||
337 | break; | 384 | break; |
338 | 385 | ||
339 | case BUTTON_F2: | 386 | case BUTTON_F2: |
340 | radio_preset_select(); | 387 | handle_radio_presets(); |
341 | curr_preset = find_preset(curr_freq); | 388 | curr_preset = find_preset(curr_freq); |
342 | lcd_clear_display(); | 389 | lcd_clear_display(); |
343 | lcd_setmargins(0, 8); | 390 | lcd_setmargins(0, 8); |
@@ -393,7 +440,8 @@ bool radio_screen(void) | |||
393 | timeout = current_tick + HZ; | 440 | timeout = current_tick + HZ; |
394 | 441 | ||
395 | val = fmradio_read(3); | 442 | val = fmradio_read(3); |
396 | stereo = (val & 0x100000)?true:false; | 443 | stereo = ((val & 0x100000)?true:false) & |
444 | !global_settings.fm_force_mono; | ||
397 | if(stereo != last_stereo_status) | 445 | if(stereo != last_stereo_status) |
398 | { | 446 | { |
399 | update_screen = true; | 447 | update_screen = true; |
@@ -441,9 +489,12 @@ bool radio_screen(void) | |||
441 | } | 489 | } |
442 | else | 490 | else |
443 | { | 491 | { |
444 | snprintf(buf, 32, "%s %02d", | 492 | if(global_settings.rec_prerecord_time) |
445 | str(LANG_RECORD_PRERECORD), seconds%60); | 493 | { |
446 | lcd_puts(0, top_of_screen + 3, buf); | 494 | snprintf(buf, 32, "%s %02d", |
495 | str(LANG_RECORD_PRERECORD), seconds%60); | ||
496 | lcd_puts(0, top_of_screen + 3, buf); | ||
497 | } | ||
447 | } | 498 | } |
448 | 499 | ||
449 | /* Only force the redraw if update_screen is true */ | 500 | /* Only force the redraw if update_screen is true */ |
@@ -503,29 +554,6 @@ bool radio_screen(void) | |||
503 | return have_recorded; | 554 | return have_recorded; |
504 | } | 555 | } |
505 | 556 | ||
506 | static bool parseline(char* line, char** freq, char** name) | ||
507 | { | ||
508 | char* ptr; | ||
509 | |||
510 | while ( isspace(*line) ) | ||
511 | line++; | ||
512 | |||
513 | if ( *line == '#' ) | ||
514 | return false; | ||
515 | |||
516 | ptr = strchr(line, ':'); | ||
517 | if ( !ptr ) | ||
518 | return false; | ||
519 | |||
520 | *freq = line; | ||
521 | *ptr = 0; | ||
522 | ptr++; | ||
523 | while (isspace(*ptr)) | ||
524 | ptr++; | ||
525 | *name = ptr; | ||
526 | return true; | ||
527 | } | ||
528 | |||
529 | void radio_save_presets(void) | 557 | void radio_save_presets(void) |
530 | { | 558 | { |
531 | int fd; | 559 | int fd; |
@@ -534,7 +562,7 @@ void radio_save_presets(void) | |||
534 | fd = creat(default_filename, O_WRONLY); | 562 | fd = creat(default_filename, O_WRONLY); |
535 | if(fd >= 0) | 563 | if(fd >= 0) |
536 | { | 564 | { |
537 | for(i = 0;i < MAX_PRESETS;i++) | 565 | for(i = 0;i < num_presets;i++) |
538 | { | 566 | { |
539 | fprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name); | 567 | fprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name); |
540 | } | 568 | } |
@@ -555,10 +583,12 @@ void radio_load_presets(void) | |||
555 | char *name; | 583 | char *name; |
556 | bool done = false; | 584 | bool done = false; |
557 | int i; | 585 | int i; |
586 | int f; | ||
558 | 587 | ||
559 | if(!presets_loaded) | 588 | if(!presets_loaded) |
560 | { | 589 | { |
561 | memset(presets, 0, sizeof(presets)); | 590 | memset(presets, 0, sizeof(presets)); |
591 | num_presets = 0; | ||
562 | 592 | ||
563 | fd = open(default_filename, O_RDONLY); | 593 | fd = open(default_filename, O_RDONLY); |
564 | if(fd >= 0) | 594 | if(fd >= 0) |
@@ -569,12 +599,16 @@ void radio_load_presets(void) | |||
569 | rc = read_line(fd, buf, 128); | 599 | rc = read_line(fd, buf, 128); |
570 | if(rc > 0) | 600 | if(rc > 0) |
571 | { | 601 | { |
572 | if(parseline(buf, &freq, &name)) | 602 | if(settings_parseline(buf, &freq, &name)) |
573 | { | 603 | { |
574 | presets[i].frequency = atoi(freq); | 604 | f = atoi(freq); |
575 | strncpy(presets[i].name, name, 27); | 605 | if(f) /* For backwards compatibility */ |
576 | presets[i].name[27] = 0; | 606 | { |
577 | i++; | 607 | presets[num_presets].frequency = f; |
608 | strncpy(presets[num_presets].name, name, 27); | ||
609 | presets[num_presets].name[27] = 0; | ||
610 | num_presets++; | ||
611 | } | ||
578 | } | 612 | } |
579 | } | 613 | } |
580 | else | 614 | else |
@@ -586,71 +620,35 @@ void radio_load_presets(void) | |||
586 | presets_loaded = true; | 620 | presets_loaded = true; |
587 | } | 621 | } |
588 | 622 | ||
589 | bool radio_preset_select(void) | 623 | static void rebuild_preset_menu(void) |
590 | { | 624 | { |
591 | struct menu_item menu[MAX_PRESETS]; | ||
592 | int m, result; | ||
593 | int i; | 625 | int i; |
594 | bool reload_dir = false; | 626 | for(i = 0;i < num_presets;i++) |
595 | int num_presets; | ||
596 | |||
597 | if(presets_loaded) | ||
598 | { | 627 | { |
599 | num_presets = 0; | 628 | preset_menu_items[i].desc = presets[i].name; |
600 | 629 | preset_menu_items[i].voice_id = -1; | |
601 | for(i = 0;i < MAX_PRESETS;i++) | ||
602 | { | ||
603 | if(presets[i].frequency) | ||
604 | { | ||
605 | menu[num_presets].desc = presets[i].name; | ||
606 | menu[num_presets].voice_id = -1; | ||
607 | /* We use the function pointer entry for the preset | ||
608 | entry index */ | ||
609 | menu[num_presets++].function = (void *)i; | ||
610 | } | ||
611 | } | ||
612 | |||
613 | if(num_presets) | ||
614 | { | ||
615 | /* DIY menu handling, since we want to exit after selection */ | ||
616 | m = menu_init( menu, num_presets, NULL, NULL, NULL, NULL ); | ||
617 | result = menu_show(m); | ||
618 | menu_exit(m); | ||
619 | if (result == MENU_SELECTED_EXIT) | ||
620 | return false; | ||
621 | else if (result == MENU_ATTACHED_USB) | ||
622 | reload_dir = true; | ||
623 | |||
624 | if (result >= 0) | ||
625 | { | ||
626 | i = (int)menu[result].function; | ||
627 | curr_freq = presets[i].frequency; | ||
628 | radio_set_frequency(curr_freq); | ||
629 | } | ||
630 | } | ||
631 | else | ||
632 | { | ||
633 | splash(HZ*2, true, str(LANG_FM_NO_PRESETS)); | ||
634 | } | ||
635 | } | 630 | } |
636 | |||
637 | return reload_dir; | ||
638 | } | 631 | } |
639 | 632 | ||
640 | static bool radio_add_preset(void) | 633 | static bool radio_add_preset(void) |
641 | { | 634 | { |
642 | char buf[27]; | 635 | char buf[27]; |
643 | int i = find_preset(0); | ||
644 | 636 | ||
645 | if(i >= 0) | 637 | if(num_presets < MAX_PRESETS) |
646 | { | 638 | { |
647 | memset(buf, 0, 27); | 639 | memset(buf, 0, 27); |
648 | 640 | ||
649 | if (!kbd_input(buf, 27)) | 641 | if (!kbd_input(buf, 27)) |
650 | { | 642 | { |
651 | buf[27] = 0; | 643 | buf[27] = 0; |
652 | strcpy(presets[i].name, buf); | 644 | strcpy(presets[num_presets].name, buf); |
653 | presets[i].frequency = curr_freq; | 645 | presets[num_presets].frequency = curr_freq; |
646 | menu_insert(preset_menu, -1, | ||
647 | presets[num_presets].name, 0, 0); | ||
648 | /* We must still rebuild the menu table, since the | ||
649 | item name pointers must be updated */ | ||
650 | rebuild_preset_menu(); | ||
651 | num_presets++; | ||
654 | radio_save_presets(); | 652 | radio_save_presets(); |
655 | } | 653 | } |
656 | } | 654 | } |
@@ -661,47 +659,129 @@ static bool radio_add_preset(void) | |||
661 | return true; | 659 | return true; |
662 | } | 660 | } |
663 | 661 | ||
662 | static int handle_radio_presets_menu_cb(int key, int m) | ||
663 | { | ||
664 | (void)m; | ||
665 | switch(key) | ||
666 | { | ||
667 | case BUTTON_F3: | ||
668 | key = BUTTON_LEFT; /* Fake an exit */ | ||
669 | break; | ||
670 | } | ||
671 | return key; | ||
672 | } | ||
673 | |||
674 | static bool radio_edit_preset(void) | ||
675 | { | ||
676 | int pos = menu_cursor(preset_menu); | ||
677 | char buf[27]; | ||
678 | |||
679 | strncpy(buf, menu_description(preset_menu, pos), 27); | ||
680 | |||
681 | if (!kbd_input(buf, 27)) | ||
682 | { | ||
683 | buf[27] = 0; | ||
684 | strcpy(presets[pos].name, buf); | ||
685 | radio_save_presets(); | ||
686 | } | ||
687 | return true; | ||
688 | } | ||
689 | |||
664 | bool radio_delete_preset(void) | 690 | bool radio_delete_preset(void) |
665 | { | 691 | { |
666 | struct menu_item menu[MAX_PRESETS]; | 692 | int pos = menu_cursor(preset_menu); |
667 | int m, result; | 693 | int i; |
694 | |||
695 | for(i = pos;i < num_presets;i++) | ||
696 | presets[i] = presets[i+1]; | ||
697 | num_presets--; | ||
698 | |||
699 | menu_delete(preset_menu, pos); | ||
700 | /* We must still rebuild the menu table, since the | ||
701 | item name pointers must be updated */ | ||
702 | rebuild_preset_menu(); | ||
703 | radio_save_presets(); | ||
704 | |||
705 | return true; /* Make the menu return immediately */ | ||
706 | } | ||
707 | |||
708 | bool handle_radio_presets_menu(void) | ||
709 | { | ||
710 | struct menu_item preset_menu_items[] = { | ||
711 | { STR(LANG_FM_EDIT_PRESET), radio_edit_preset }, | ||
712 | { STR(LANG_FM_DELETE_PRESET), radio_delete_preset }, | ||
713 | }; | ||
714 | int m; | ||
715 | |||
716 | m = menu_init( preset_menu_items, | ||
717 | sizeof preset_menu_items / sizeof(struct menu_item), | ||
718 | handle_radio_presets_menu_cb, | ||
719 | NULL, NULL, str(LANG_FM_BUTTONBAR_EXIT)); | ||
720 | menu_run(m); | ||
721 | menu_exit(m); | ||
722 | return false; | ||
723 | } | ||
724 | |||
725 | int handle_radio_presets_cb(int key, int m) | ||
726 | { | ||
727 | bool ret; | ||
728 | |||
729 | switch(key) | ||
730 | { | ||
731 | case BUTTON_F1: | ||
732 | radio_add_preset(); | ||
733 | menu_draw(m); | ||
734 | key = BUTTON_NONE; | ||
735 | break; | ||
736 | |||
737 | case BUTTON_F2: | ||
738 | menu_draw(m); | ||
739 | key = BUTTON_LEFT; /* Fake an exit */ | ||
740 | break; | ||
741 | |||
742 | case BUTTON_F3: | ||
743 | ret = handle_radio_presets_menu(); | ||
744 | menu_draw(m); | ||
745 | if(ret) | ||
746 | key = MENU_ATTACHED_USB; | ||
747 | else | ||
748 | key = BUTTON_NONE; | ||
749 | break; | ||
750 | } | ||
751 | return key; | ||
752 | } | ||
753 | |||
754 | bool handle_radio_presets(void) | ||
755 | { | ||
756 | int result; | ||
668 | int i; | 757 | int i; |
669 | bool reload_dir = false; | 758 | bool reload_dir = false; |
670 | int num_presets; | ||
671 | 759 | ||
672 | if(presets_loaded) | 760 | if(presets_loaded) |
673 | { | 761 | { |
674 | num_presets = 0; | 762 | rebuild_preset_menu(); |
675 | 763 | ||
676 | for(i = 0;i < MAX_PRESETS;i++) | ||
677 | { | ||
678 | if(presets[i].frequency) | ||
679 | { | ||
680 | menu[num_presets].desc = presets[i].name; | ||
681 | menu[num_presets].voice_id = -1; | ||
682 | /* We use the function pointer entry for the preset | ||
683 | entry index */ | ||
684 | menu[num_presets++].function = (void *)i; | ||
685 | } | ||
686 | } | ||
687 | |||
688 | /* DIY menu handling, since we want to exit after selection */ | 764 | /* DIY menu handling, since we want to exit after selection */ |
689 | m = menu_init( menu, num_presets, NULL, NULL, NULL, NULL ); | 765 | preset_menu = menu_init( preset_menu_items, num_presets, |
690 | result = menu_show(m); | 766 | handle_radio_presets_cb, |
691 | menu_exit(m); | 767 | str(LANG_FM_BUTTONBAR_ADD), |
768 | str(LANG_FM_BUTTONBAR_EXIT), | ||
769 | str(LANG_FM_BUTTONBAR_ACTION)); | ||
770 | result = menu_show(preset_menu); | ||
771 | menu_exit(preset_menu); | ||
692 | if (result == MENU_SELECTED_EXIT) | 772 | if (result == MENU_SELECTED_EXIT) |
693 | return false; | 773 | return false; |
694 | else if (result == MENU_ATTACHED_USB) | 774 | else if (result == MENU_ATTACHED_USB) |
695 | reload_dir = true; | 775 | reload_dir = true; |
696 | 776 | ||
697 | if (result >= 0) | 777 | if (result >= 0) /* A preset was selected */ |
698 | { | 778 | { |
699 | i = (int)menu[result].function; | 779 | i = menu_cursor(preset_menu); |
700 | presets[i].frequency = 0; | 780 | curr_freq = presets[i].frequency; |
701 | radio_save_presets(); | 781 | radio_set(RADIO_FREQUENCY, curr_freq); |
702 | } | 782 | } |
703 | } | 783 | } |
704 | 784 | ||
705 | return reload_dir; | 785 | return reload_dir; |
706 | } | 786 | } |
707 | 787 | ||
@@ -726,22 +806,42 @@ static bool fm_recording_settings(void) | |||
726 | return ret; | 806 | return ret; |
727 | } | 807 | } |
728 | #endif | 808 | #endif |
809 | |||
810 | char monomode_menu_string[32]; | ||
811 | |||
812 | static void create_monomode_menu(void) | ||
813 | { | ||
814 | snprintf(monomode_menu_string, 32, "%s: %s", str(LANG_FM_MONO_MODE), | ||
815 | global_settings.fm_force_mono? | ||
816 | str(LANG_SET_BOOL_YES):str(LANG_SET_BOOL_NO)); | ||
817 | } | ||
818 | |||
819 | static bool toggle_mono_mode(void) | ||
820 | { | ||
821 | global_settings.fm_force_mono = !global_settings.fm_force_mono; | ||
822 | radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); | ||
823 | settings_save(); | ||
824 | create_monomode_menu(); | ||
825 | return false; | ||
826 | } | ||
827 | |||
729 | bool radio_menu(void) | 828 | bool radio_menu(void) |
730 | { | 829 | { |
731 | struct menu_item radio_menu_items[] = { | 830 | struct menu_item items[3]; |
732 | { STR(LANG_FM_SAVE_PRESET), radio_add_preset }, | ||
733 | { STR(LANG_FM_DELETE_PRESET), radio_delete_preset }, | ||
734 | { STR(LANG_SOUND_SETTINGS), sound_menu }, | ||
735 | #ifndef SIMULATOR | ||
736 | { STR(LANG_RECORDING_SETTINGS), fm_recording_settings } | ||
737 | #endif | ||
738 | }; | ||
739 | int m; | 831 | int m; |
740 | bool result; | 832 | bool result; |
741 | 833 | ||
742 | m = menu_init( radio_menu_items, | 834 | m = menu_init(items, 0, NULL, NULL, NULL, NULL); |
743 | sizeof radio_menu_items / sizeof(struct menu_item), NULL, | 835 | |
744 | NULL, NULL, NULL); | 836 | create_monomode_menu(); |
837 | menu_insert(m, -1, monomode_menu_string, LANG_FM_MONO_MODE, | ||
838 | toggle_mono_mode); | ||
839 | menu_insert(m, -1, STR(LANG_SOUND_SETTINGS), sound_menu); | ||
840 | |||
841 | #ifndef SIMULATOR | ||
842 | menu_insert(m, -1, STR(LANG_RECORDING_SETTINGS), fm_recording_settings); | ||
843 | #endif | ||
844 | |||
745 | result = menu_run(m); | 845 | result = menu_run(m); |
746 | menu_exit(m); | 846 | menu_exit(m); |
747 | return result; | 847 | return result; |