summaryrefslogtreecommitdiff
path: root/apps/sound_menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/sound_menu.c')
-rw-r--r--apps/sound_menu.c375
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
39static const char* const fmt[] = 46static 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
445enum 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
458static 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)
476static 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 */
505bool 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
438bool recording_menu(bool no_source) 807bool 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);