diff options
Diffstat (limited to 'apps/sound_menu.c')
-rw-r--r-- | apps/sound_menu.c | 375 |
1 files changed, 374 insertions, 1 deletions
diff --git a/apps/sound_menu.c b/apps/sound_menu.c index 560163c7c1..68c959a0ed 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "config.h" | 19 | #include "config.h" |
20 | #include <stdio.h> | 20 | #include <stdio.h> |
21 | #include <stdbool.h> | 21 | #include <stdbool.h> |
22 | #include "system.h" | ||
22 | #include "kernel.h" | 23 | #include "kernel.h" |
23 | #include "lcd.h" | 24 | #include "lcd.h" |
24 | #include "menu.h" | 25 | #include "menu.h" |
@@ -29,12 +30,18 @@ | |||
29 | #include "screens.h" | 30 | #include "screens.h" |
30 | #ifdef HAVE_LCD_BITMAP | 31 | #ifdef HAVE_LCD_BITMAP |
31 | #include "icons.h" | 32 | #include "icons.h" |
33 | #include "font.h" | ||
34 | #include "widgets.h" | ||
32 | #endif | 35 | #endif |
33 | #include "lang.h" | 36 | #include "lang.h" |
34 | #include "sprintf.h" | 37 | #include "sprintf.h" |
35 | #include "talk.h" | 38 | #include "talk.h" |
36 | #include "misc.h" | 39 | #include "misc.h" |
37 | #include "sound.h" | 40 | #include "sound.h" |
41 | #if CONFIG_HWCODEC == MAS3587F || CONFIG_HWCODEC == MAS3539F | ||
42 | #include "peakmeter.h" | ||
43 | #include "mas.h" | ||
44 | #endif | ||
38 | 45 | ||
39 | static const char* const fmt[] = | 46 | static const char* const fmt[] = |
40 | { | 47 | { |
@@ -435,11 +442,373 @@ bool sound_menu(void) | |||
435 | } | 442 | } |
436 | 443 | ||
437 | #ifdef HAVE_RECORDING | 444 | #ifdef HAVE_RECORDING |
445 | enum trigger_menu_option | ||
446 | { | ||
447 | TRIGGER_MODE, | ||
448 | PRERECORD_TIME, | ||
449 | START_THRESHOLD, | ||
450 | START_DURATION, | ||
451 | STOP_THRESHOLD, | ||
452 | STOP_POSTREC, | ||
453 | STOP_GAP, | ||
454 | TRIG_OPTION_COUNT, | ||
455 | }; | ||
456 | |||
457 | #if !defined(SIMULATOR) && CONFIG_HWCODEC == MAS3587F | ||
458 | static char* create_thres_str(int threshold) | ||
459 | { | ||
460 | static char retval[6]; | ||
461 | if (threshold < 0) { | ||
462 | if (threshold < -88) { | ||
463 | snprintf (retval, sizeof retval, "%s", str(LANG_DB_INF)); | ||
464 | } else { | ||
465 | snprintf (retval, sizeof retval, "%ddb", threshold + 1); | ||
466 | } | ||
467 | } else { | ||
468 | snprintf (retval, sizeof retval, "%d%%", threshold); | ||
469 | } | ||
470 | return retval; | ||
471 | } | ||
472 | #endif | ||
473 | |||
474 | #if !defined(SIMULATOR) && (CONFIG_HWCODEC == MAS3587F || CONFIG_HWCODEC == MAS3539F) | ||
475 | #define INF_DB (-89) | ||
476 | static void change_threshold(int *threshold, int change) | ||
477 | { | ||
478 | if (global_settings.peak_meter_dbfs) { | ||
479 | if (*threshold >= 0) { | ||
480 | int db = (calc_db(*threshold * MAX_PEAK / 100) - 9000) / 100; | ||
481 | *threshold = db; | ||
482 | } | ||
483 | *threshold += change; | ||
484 | if (*threshold > -1) { | ||
485 | *threshold = INF_DB; | ||
486 | } else if (*threshold < INF_DB) { | ||
487 | *threshold = -1; | ||
488 | } | ||
489 | } else { | ||
490 | if (*threshold < 0) { | ||
491 | *threshold = peak_meter_db2sample(*threshold * 100) * 100 / MAX_PEAK; | ||
492 | } | ||
493 | *threshold += change; | ||
494 | if (*threshold > 100) { | ||
495 | *threshold = 0; | ||
496 | } else if (*threshold < 0) { | ||
497 | *threshold = 100; | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * Displays a menu for editing the trigger settings. | ||
504 | */ | ||
505 | bool rectrigger(void) | ||
506 | { | ||
507 | int exit_request = false; | ||
508 | enum trigger_menu_option selected = TRIGGER_MODE; | ||
509 | bool retval = false; | ||
510 | int old_x_margin, old_y_margin; | ||
511 | |||
512 | #define TRIGGER_MODE_COUNT 3 | ||
513 | char *trigger_modes[] = | ||
514 | { | ||
515 | str(LANG_OFF), | ||
516 | str(LANG_RECORD_TRIG_NOREARM), | ||
517 | str(LANG_RECORD_TRIG_REARM) | ||
518 | }; | ||
519 | |||
520 | #define PRERECORD_TIMES_COUNT 31 | ||
521 | char *prerecord_times[] = { | ||
522 | str(LANG_OFF),"1s","2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", | ||
523 | "10s", "11s", "12s", "13s", "14s", "15s", "16s", "17s", "18s", "19s", | ||
524 | "20s", "21s", "22s", "23s", "24s", "25s", "26s", "27s", "28s", "29s", | ||
525 | "30s" | ||
526 | }; | ||
527 | |||
528 | char *option_name[TRIG_OPTION_COUNT]; | ||
529 | |||
530 | int old_start_thres = global_settings.rec_start_thres; | ||
531 | int old_start_duration = global_settings.rec_start_duration; | ||
532 | int old_prerecord_time = global_settings.rec_prerecord_time; | ||
533 | int old_stop_thres = global_settings.rec_stop_thres; | ||
534 | int old_stop_postrec = global_settings.rec_stop_postrec; | ||
535 | int old_stop_gap = global_settings.rec_stop_gap; | ||
536 | int old_trigger_mode = global_settings.rec_trigger_mode; | ||
537 | |||
538 | int offset = 0; | ||
539 | int option_lines; | ||
540 | int w, h; | ||
541 | |||
542 | option_name[TRIGGER_MODE] = str(LANG_RECORD_TRIGGER_MODE); | ||
543 | option_name[PRERECORD_TIME] = str(LANG_RECORD_PRERECORD_TIME); | ||
544 | option_name[START_THRESHOLD] = str(LANG_RECORD_START_THRESHOLD); | ||
545 | option_name[START_DURATION] = str(LANG_RECORD_MIN_DURATION); | ||
546 | option_name[STOP_THRESHOLD] = str(LANG_RECORD_STOP_THRESHOLD); | ||
547 | option_name[STOP_POSTREC] = str(LANG_RECORD_STOP_POSTREC); | ||
548 | option_name[STOP_GAP] = str(LANG_RECORD_STOP_GAP); | ||
549 | |||
550 | |||
551 | /* restart trigger with new values */ | ||
552 | settings_apply_trigger(); | ||
553 | peak_meter_trigger (global_settings.rec_trigger_mode != TRIG_MODE_OFF); | ||
554 | |||
555 | lcd_clear_display(); | ||
556 | |||
557 | old_x_margin = lcd_getxmargin(); | ||
558 | old_y_margin = lcd_getymargin(); | ||
559 | if(global_settings.statusbar) | ||
560 | lcd_setmargins(0, STATUSBAR_HEIGHT); | ||
561 | else | ||
562 | lcd_setmargins(0, 0); | ||
563 | |||
564 | lcd_getstringsize("M", &w, &h); | ||
565 | |||
566 | // two lines are reserved for peak meter and trigger status | ||
567 | option_lines = (LCD_HEIGHT/h) - (global_settings.statusbar ? 1:0) - 2; | ||
568 | |||
569 | while (!exit_request) { | ||
570 | int stat_height = global_settings.statusbar ? STATUSBAR_HEIGHT : 0; | ||
571 | int button, i; | ||
572 | char *str; | ||
573 | char option_value[TRIG_OPTION_COUNT][7]; | ||
574 | |||
575 | snprintf( | ||
576 | option_value[TRIGGER_MODE], | ||
577 | sizeof option_value[TRIGGER_MODE], | ||
578 | "%s", | ||
579 | trigger_modes[global_settings.rec_trigger_mode]); | ||
580 | |||
581 | snprintf ( | ||
582 | option_value[PRERECORD_TIME], | ||
583 | sizeof option_value[PRERECORD_TIME], | ||
584 | "%s", | ||
585 | prerecord_times[global_settings.rec_prerecord_time]); | ||
586 | |||
587 | /* due to value range shift (peak_meter_define_trigger) -1 is 0db */ | ||
588 | if (global_settings.rec_start_thres == -1) { | ||
589 | str = str(LANG_OFF); | ||
590 | } else { | ||
591 | str = create_thres_str(global_settings.rec_start_thres); | ||
592 | } | ||
593 | snprintf( | ||
594 | option_value[START_THRESHOLD], | ||
595 | sizeof option_value[START_THRESHOLD], | ||
596 | "%s", | ||
597 | str); | ||
598 | |||
599 | snprintf( | ||
600 | option_value[START_DURATION], | ||
601 | sizeof option_value[START_DURATION], | ||
602 | "%s", | ||
603 | trig_durations[global_settings.rec_start_duration]); | ||
604 | |||
605 | |||
606 | if (global_settings.rec_stop_thres <= INF_DB) { | ||
607 | str = str(LANG_OFF); | ||
608 | } else { | ||
609 | str = create_thres_str(global_settings.rec_stop_thres); | ||
610 | } | ||
611 | snprintf( | ||
612 | option_value[STOP_THRESHOLD], | ||
613 | sizeof option_value[STOP_THRESHOLD], | ||
614 | "%s", | ||
615 | str); | ||
616 | |||
617 | snprintf( | ||
618 | option_value[STOP_POSTREC], | ||
619 | sizeof option_value[STOP_POSTREC], | ||
620 | "%s", | ||
621 | trig_durations[global_settings.rec_stop_postrec]); | ||
622 | |||
623 | snprintf( | ||
624 | option_value[STOP_GAP], | ||
625 | sizeof option_value[STOP_GAP], | ||
626 | "%s", | ||
627 | trig_durations[global_settings.rec_stop_gap]); | ||
628 | |||
629 | lcd_clearrect(0, stat_height, LCD_WIDTH, LCD_HEIGHT - stat_height); | ||
630 | status_draw(true); | ||
631 | |||
632 | /* reselect FONT_SYSFONT as status_draw has changed the font */ | ||
633 | /*lcd_setfont(FONT_SYSFIXED);*/ | ||
634 | |||
635 | for (i = 0; i < option_lines; i++) { | ||
636 | int x, y; | ||
637 | |||
638 | str = option_name[i + offset]; | ||
639 | lcd_putsxy(5, stat_height + i * h, str); | ||
640 | |||
641 | str = option_value[i + offset]; | ||
642 | lcd_getstringsize(str, &w, &h); | ||
643 | y = stat_height + i * h; | ||
644 | x = LCD_WIDTH - w; | ||
645 | lcd_putsxy(x, y, str); | ||
646 | if ((int)selected == (i + offset)) | ||
647 | lcd_invertrect(x, y, w, h); | ||
648 | } | ||
649 | |||
650 | scrollbar(0, stat_height, | ||
651 | 4, LCD_HEIGHT - 16 - stat_height, | ||
652 | TRIG_OPTION_COUNT, offset, offset + option_lines, | ||
653 | VERTICAL); | ||
654 | |||
655 | peak_meter_draw_trig(0, LCD_HEIGHT - 8 - TRIG_HEIGHT); | ||
656 | |||
657 | button = peak_meter_draw_get_btn(0, LCD_HEIGHT - 8, LCD_WIDTH, 8); | ||
658 | |||
659 | lcd_update(); | ||
660 | |||
661 | switch (button) { | ||
662 | case BUTTON_OFF: | ||
663 | splash(50, true, str(LANG_RESET_DONE_CANCEL)); | ||
664 | global_settings.rec_start_thres = old_start_thres; | ||
665 | global_settings.rec_start_duration = old_start_duration; | ||
666 | global_settings.rec_prerecord_time = old_prerecord_time; | ||
667 | global_settings.rec_stop_thres = old_stop_thres; | ||
668 | global_settings.rec_stop_postrec = old_stop_postrec; | ||
669 | global_settings.rec_stop_gap = old_stop_gap; | ||
670 | global_settings.rec_trigger_mode = old_trigger_mode; | ||
671 | exit_request = true; | ||
672 | break; | ||
673 | |||
674 | case BUTTON_PLAY: | ||
675 | exit_request = true; | ||
676 | break; | ||
677 | |||
678 | case BUTTON_UP: | ||
679 | selected += TRIG_OPTION_COUNT - 1; | ||
680 | selected %= TRIG_OPTION_COUNT; | ||
681 | offset = MIN(offset, (int)selected); | ||
682 | offset = MAX(offset, (int)selected - option_lines + 1); | ||
683 | break; | ||
684 | |||
685 | case BUTTON_DOWN: | ||
686 | selected ++; | ||
687 | selected %= TRIG_OPTION_COUNT; | ||
688 | offset = MIN(offset, (int)selected); | ||
689 | offset = MAX(offset, (int)selected - option_lines + 1); | ||
690 | break; | ||
691 | |||
692 | case BUTTON_RIGHT: | ||
693 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
694 | switch (selected) { | ||
695 | case TRIGGER_MODE: | ||
696 | global_settings.rec_trigger_mode ++; | ||
697 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
698 | break; | ||
699 | |||
700 | case PRERECORD_TIME: | ||
701 | global_settings.rec_prerecord_time ++; | ||
702 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
703 | break; | ||
704 | |||
705 | case START_THRESHOLD: | ||
706 | change_threshold(&global_settings.rec_start_thres, 1); | ||
707 | break; | ||
708 | |||
709 | case START_DURATION: | ||
710 | global_settings.rec_start_duration ++; | ||
711 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
712 | break; | ||
713 | |||
714 | case STOP_THRESHOLD: | ||
715 | change_threshold(&global_settings.rec_stop_thres, 1); | ||
716 | break; | ||
717 | |||
718 | case STOP_POSTREC: | ||
719 | global_settings.rec_stop_postrec ++; | ||
720 | global_settings.rec_stop_postrec %= TRIG_DURATION_COUNT; | ||
721 | break; | ||
722 | |||
723 | case STOP_GAP: | ||
724 | global_settings.rec_stop_gap ++; | ||
725 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
726 | break; | ||
727 | |||
728 | case TRIG_OPTION_COUNT: | ||
729 | // avoid compiler warnings | ||
730 | break; | ||
731 | } | ||
732 | peak_meter_trigger(global_settings.rec_trigger_mode!=TRIG_OFF); | ||
733 | settings_apply_trigger(); | ||
734 | break; | ||
735 | |||
736 | case BUTTON_LEFT: | ||
737 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
738 | switch (selected) { | ||
739 | case TRIGGER_MODE: | ||
740 | global_settings.rec_trigger_mode+=TRIGGER_MODE_COUNT-1; | ||
741 | global_settings.rec_trigger_mode %= TRIGGER_MODE_COUNT; | ||
742 | break; | ||
743 | |||
744 | case PRERECORD_TIME: | ||
745 | global_settings.rec_prerecord_time += PRERECORD_TIMES_COUNT - 1; | ||
746 | global_settings.rec_prerecord_time %= PRERECORD_TIMES_COUNT; | ||
747 | break; | ||
748 | |||
749 | case START_THRESHOLD: | ||
750 | change_threshold(&global_settings.rec_start_thres, -1); | ||
751 | break; | ||
752 | |||
753 | case START_DURATION: | ||
754 | global_settings.rec_start_duration += TRIG_DURATION_COUNT-1; | ||
755 | global_settings.rec_start_duration %= TRIG_DURATION_COUNT; | ||
756 | break; | ||
757 | |||
758 | case STOP_THRESHOLD: | ||
759 | change_threshold(&global_settings.rec_stop_thres, -1); | ||
760 | break; | ||
761 | |||
762 | case STOP_POSTREC: | ||
763 | global_settings.rec_stop_postrec += | ||
764 | TRIG_DURATION_COUNT - 1; | ||
765 | global_settings.rec_stop_postrec %= | ||
766 | TRIG_DURATION_COUNT; | ||
767 | break; | ||
768 | |||
769 | case STOP_GAP: | ||
770 | global_settings.rec_stop_gap += | ||
771 | TRIG_DURATION_COUNT - 1; | ||
772 | global_settings.rec_stop_gap %= TRIG_DURATION_COUNT; | ||
773 | break; | ||
774 | |||
775 | case TRIG_OPTION_COUNT: | ||
776 | // avoid compiler warnings | ||
777 | break; | ||
778 | } | ||
779 | |||
780 | if (global_settings.rec_trigger_mode == TRIG_OFF) { | ||
781 | peak_meter_trigger(true); | ||
782 | } else { | ||
783 | /* restart trigger with new values */ | ||
784 | settings_apply_trigger(); | ||
785 | } | ||
786 | break; | ||
787 | |||
788 | case BUTTON_F2: | ||
789 | peak_meter_trigger(true); | ||
790 | break; | ||
791 | |||
792 | case SYS_USB_CONNECTED: | ||
793 | usb_screen(); | ||
794 | retval = true; | ||
795 | exit_request = true; | ||
796 | break; | ||
797 | } | ||
798 | } | ||
799 | |||
800 | peak_meter_trigger(false); | ||
801 | lcd_setfont(FONT_UI); | ||
802 | lcd_setmargins(old_x_margin, old_y_margin); | ||
803 | return retval; | ||
804 | } | ||
805 | #endif | ||
806 | |||
438 | bool recording_menu(bool no_source) | 807 | bool recording_menu(bool no_source) |
439 | { | 808 | { |
440 | int m; | 809 | int m; |
441 | int i = 0; | 810 | int i = 0; |
442 | struct menu_item items[9]; | 811 | struct menu_item items[10]; |
443 | bool result; | 812 | bool result; |
444 | 813 | ||
445 | items[i].desc = ID2P(LANG_RECORDING_QUALITY); | 814 | items[i].desc = ID2P(LANG_RECORDING_QUALITY); |
@@ -462,6 +831,10 @@ bool recording_menu(bool no_source) | |||
462 | items[i++].function = recdirectory; | 831 | items[i++].function = recdirectory; |
463 | items[i].desc = ID2P(LANG_RECORD_STARTUP); | 832 | items[i].desc = ID2P(LANG_RECORD_STARTUP); |
464 | items[i++].function = reconstartup; | 833 | items[i++].function = reconstartup; |
834 | #if !defined(SIMULATOR) && CONFIG_HWCODEC == MAS3587F | ||
835 | items[i].desc = str(LANG_RECORD_TRIGGER); | ||
836 | items[i++].function = rectrigger; | ||
837 | #endif | ||
465 | 838 | ||
466 | m=menu_init( items, i, NULL, NULL, NULL, NULL); | 839 | m=menu_init( items, i, NULL, NULL, NULL, NULL); |
467 | result = menu_run(m); | 840 | result = menu_run(m); |