diff options
Diffstat (limited to 'apps/recorder/peakmeter.c')
-rw-r--r-- | apps/recorder/peakmeter.c | 374 |
1 files changed, 337 insertions, 37 deletions
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 41d375e076..0481e25acd 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "kernel.h" | 22 | #include "kernel.h" |
23 | #include "settings.h" | 23 | #include "settings.h" |
24 | #include "lcd.h" | 24 | #include "lcd.h" |
25 | #include "widgets.h" | ||
25 | #include "wps-display.h" | 26 | #include "wps-display.h" |
26 | #include "sprintf.h" | 27 | #include "sprintf.h" |
27 | #include "button.h" | 28 | #include "button.h" |
@@ -67,6 +68,24 @@ static unsigned short db_min = 0; | |||
67 | static unsigned short db_max = 9000; | 68 | static unsigned short db_max = 9000; |
68 | static unsigned short db_range = 9000; | 69 | static unsigned short db_range = 9000; |
69 | 70 | ||
71 | static unsigned short trig_strt_threshold; | ||
72 | static long trig_strt_duration; | ||
73 | static long trig_strt_dropout; | ||
74 | static unsigned short trig_stp_threshold; | ||
75 | static long trig_stp_hold; | ||
76 | static long trig_rstrt_gap; | ||
77 | |||
78 | /* point in time when the threshold was exceeded */ | ||
79 | static long trig_hightime; | ||
80 | |||
81 | /* point in time when the volume fell below the threshold*/ | ||
82 | static long trig_lowtime; | ||
83 | |||
84 | /* The output value of the trigger. See TRIG_XXX constants vor valid values */ | ||
85 | static int trig_status = TRIG_OFF; | ||
86 | |||
87 | static void (*trigger_listener)(int) = NULL; | ||
88 | |||
70 | #if CONFIG_HWCODEC == MASNONE | 89 | #if CONFIG_HWCODEC == MASNONE |
71 | #define MAS_REG_DQPEAK_L 0 | 90 | #define MAS_REG_DQPEAK_L 0 |
72 | #define MAS_REG_DQPEAK_R 0 | 91 | #define MAS_REG_DQPEAK_R 0 |
@@ -124,7 +143,7 @@ static const long clip_time_out[] = { | |||
124 | 143 | ||
125 | /* precalculated peak values that represent magical | 144 | /* precalculated peak values that represent magical |
126 | dBfs values. Used to draw the scale */ | 145 | dBfs values. Used to draw the scale */ |
127 | #define DB_SCALE_SRC_VALUES_SIZE 11 | 146 | #define DB_SCALE_SRC_VALUES_SIZE 12 |
128 | #if 0 | 147 | #if 0 |
129 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | 148 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { |
130 | 32767, /* 0 db */ | 149 | 32767, /* 0 db */ |
@@ -138,6 +157,7 @@ static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | |||
138 | 328, /* -40 db */ | 157 | 328, /* -40 db */ |
139 | 104, /* -50 db */ | 158 | 104, /* -50 db */ |
140 | 33, /* -60 db */ | 159 | 33, /* -60 db */ |
160 | 1, /* -inf */ | ||
141 | }; | 161 | }; |
142 | #else | 162 | #else |
143 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | 163 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { |
@@ -152,9 +172,25 @@ static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | |||
152 | 373, /* -40 db */ | 172 | 373, /* -40 db */ |
153 | 102, /* -50 db */ | 173 | 102, /* -50 db */ |
154 | 33, /* -60 db */ | 174 | 33, /* -60 db */ |
175 | 0, /* -inf */ | ||
155 | }; | 176 | }; |
156 | #endif | 177 | #endif |
157 | 178 | ||
179 | const char* peak_meter_dbnames[DB_SCALE_SRC_VALUES_SIZE] = { | ||
180 | "0 db", | ||
181 | "-3 db", | ||
182 | "-6 db", | ||
183 | "-9 db", | ||
184 | "-12 db", | ||
185 | "-18 db", | ||
186 | "-24 db", | ||
187 | "-30 db", | ||
188 | "-40 db", | ||
189 | "-50 db", | ||
190 | "-60 db", | ||
191 | "-inf", | ||
192 | }; | ||
193 | |||
158 | static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; | 194 | static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; |
159 | 195 | ||
160 | /* if db_scale_valid is false the content of | 196 | /* if db_scale_valid is false the content of |
@@ -275,8 +311,8 @@ int calc_db (int isample) { | |||
275 | 311 | ||
276 | 312 | ||
277 | /** | 313 | /** |
278 | * A helper function for db_to_sample. Don't call it separately but | 314 | * A helper function for peak_meter_db2sample. Don't call it separately but |
279 | * use db_to_sample. If one or both of min and max are outside the | 315 | * use peak_meter_db2sample. If one or both of min and max are outside the |
280 | * range 0 <= min (or max) < 8961 the behaviour of this function is | 316 | * range 0 <= min (or max) < 8961 the behaviour of this function is |
281 | * undefined. It may not return. | 317 | * undefined. It may not return. |
282 | * @param int min - The minimum of the value range that is searched. | 318 | * @param int min - The minimum of the value range that is searched. |
@@ -312,7 +348,7 @@ static int db_to_sample_bin_search(int min, int max, int db){ | |||
312 | * @return int - The return value is in the range of | 348 | * @return int - The return value is in the range of |
313 | * 0 <= return value < MAX_PEAK | 349 | * 0 <= return value < MAX_PEAK |
314 | */ | 350 | */ |
315 | static int db_to_sample(int db) { | 351 | int peak_meter_db2sample(int db) { |
316 | int retval = 0; | 352 | int retval = 0; |
317 | 353 | ||
318 | /* what is the maximum pseudo db value */ | 354 | /* what is the maximum pseudo db value */ |
@@ -351,7 +387,7 @@ static int db_to_sample(int db) { | |||
351 | */ | 387 | */ |
352 | void peak_meter_set_min(int newmin) { | 388 | void peak_meter_set_min(int newmin) { |
353 | if (peak_meter_use_dbfs) { | 389 | if (peak_meter_use_dbfs) { |
354 | peak_meter_range_min = db_to_sample(newmin); | 390 | peak_meter_range_min = peak_meter_db2sample(newmin); |
355 | 391 | ||
356 | } else { | 392 | } else { |
357 | if (newmin < peak_meter_range_max) { | 393 | if (newmin < peak_meter_range_max) { |
@@ -392,7 +428,7 @@ int peak_meter_get_min(void) { | |||
392 | */ | 428 | */ |
393 | void peak_meter_set_max(int newmax) { | 429 | void peak_meter_set_max(int newmax) { |
394 | if (peak_meter_use_dbfs) { | 430 | if (peak_meter_use_dbfs) { |
395 | peak_meter_range_max = db_to_sample(newmax); | 431 | peak_meter_range_max = peak_meter_db2sample(newmax); |
396 | } else { | 432 | } else { |
397 | if (newmax > peak_meter_range_min) { | 433 | if (newmax > peak_meter_range_min) { |
398 | peak_meter_range_max = newmax * MAX_PEAK / 100; | 434 | peak_meter_range_max = newmax * MAX_PEAK / 100; |
@@ -504,6 +540,15 @@ void peak_meter_playback(bool playback) | |||
504 | #endif | 540 | #endif |
505 | } | 541 | } |
506 | 542 | ||
543 | static void set_trig_status(int new_state) { | ||
544 | if (trig_status != new_state) { | ||
545 | trig_status = new_state; | ||
546 | if (trigger_listener != NULL) { | ||
547 | trigger_listener(trig_status); | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
507 | /** | 552 | /** |
508 | * Reads peak values from the MAS, and detects clips. The | 553 | * Reads peak values from the MAS, and detects clips. The |
509 | * values are stored in peak_meter_l peak_meter_r for later | 554 | * values are stored in peak_meter_l peak_meter_r for later |
@@ -546,6 +591,121 @@ inline void peak_meter_peek(void) | |||
546 | current_tick + clip_time_out[peak_meter_clip_hold]; | 591 | current_tick + clip_time_out[peak_meter_clip_hold]; |
547 | } | 592 | } |
548 | 593 | ||
594 | switch (trig_status) { | ||
595 | case TRIG_READY: | ||
596 | /* no more changes, if trigger was activated as release trigger */ | ||
597 | /* threshold exceeded? */ | ||
598 | if ((left > trig_strt_threshold) || (right > trig_strt_threshold)) { | ||
599 | if (trig_strt_duration) { | ||
600 | /* reset trigger duration */ | ||
601 | trig_hightime = current_tick; | ||
602 | |||
603 | /* reset dropout duration */ | ||
604 | trig_lowtime = current_tick; | ||
605 | |||
606 | /* if trig_duration is set to 0 the user wants to start | ||
607 | recording immediately */ | ||
608 | set_trig_status(TRIG_STEADY); | ||
609 | } else { | ||
610 | set_trig_status(TRIG_GO); | ||
611 | } | ||
612 | } | ||
613 | break; | ||
614 | |||
615 | case TRIG_STEADY: | ||
616 | case TRIG_RETRIG: | ||
617 | /* trigger duration exceeded */ | ||
618 | if (current_tick - trig_hightime > trig_strt_duration) { | ||
619 | set_trig_status(TRIG_GO); | ||
620 | } else { | ||
621 | /* threshold exceeded? */ | ||
622 | if ((left > trig_strt_threshold) || | ||
623 | (right > trig_strt_threshold)) { | ||
624 | /* reset lowtime */ | ||
625 | trig_lowtime = current_tick; | ||
626 | } | ||
627 | /* volume is below threshold */ | ||
628 | else { | ||
629 | /* dropout occurred? */ | ||
630 | if (current_tick - trig_lowtime > trig_strt_dropout){ | ||
631 | if (trig_status == TRIG_STEADY){ | ||
632 | set_trig_status(TRIG_READY); | ||
633 | } | ||
634 | /* trig_status == TRIG_RETRIG */ | ||
635 | else { | ||
636 | /* the gap has already expired */ | ||
637 | trig_lowtime = current_tick - trig_rstrt_gap - 1; | ||
638 | set_trig_status(TRIG_POSTREC); | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | } | ||
643 | break; | ||
644 | |||
645 | case TRIG_GO: | ||
646 | case TRIG_CONTINUE: | ||
647 | /* threshold exceeded? */ | ||
648 | if ((left > trig_stp_threshold) || (right > trig_stp_threshold)) { | ||
649 | /* restart hold time countdown */ | ||
650 | trig_lowtime = current_tick; | ||
651 | } else { | ||
652 | set_trig_status(TRIG_POSTREC); | ||
653 | trig_hightime = current_tick; | ||
654 | } | ||
655 | break; | ||
656 | |||
657 | case TRIG_POSTREC: | ||
658 | /* gap time expired? */ | ||
659 | if (current_tick - trig_lowtime > trig_rstrt_gap){ | ||
660 | /* start threshold exceeded? */ | ||
661 | if ((left > trig_strt_threshold) || | ||
662 | (right > trig_strt_threshold)) { | ||
663 | |||
664 | set_trig_status(TRIG_RETRIG); | ||
665 | trig_hightime = current_tick; | ||
666 | } | ||
667 | else | ||
668 | |||
669 | /* stop threshold exceeded */ | ||
670 | if ((left > trig_stp_threshold) || | ||
671 | (right > trig_stp_threshold)) { | ||
672 | if (current_tick - trig_hightime > trig_stp_hold){ | ||
673 | trig_lowtime = current_tick; | ||
674 | set_trig_status(TRIG_CONTINUE); | ||
675 | } else { | ||
676 | trig_lowtime = current_tick - trig_rstrt_gap - 1; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | /* below any threshold */ | ||
681 | else { | ||
682 | if (current_tick - trig_lowtime > trig_stp_hold){ | ||
683 | set_trig_status(TRIG_READY); | ||
684 | } else { | ||
685 | trig_hightime = current_tick; | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | /* still within the gap time */ | ||
691 | else { | ||
692 | /* stop threshold exceeded */ | ||
693 | if ((left > trig_stp_threshold) || | ||
694 | (right > trig_stp_threshold)) { | ||
695 | set_trig_status(TRIG_CONTINUE); | ||
696 | trig_lowtime = current_tick; | ||
697 | } | ||
698 | |||
699 | /* hold time expired */ | ||
700 | else if (current_tick - trig_lowtime > trig_stp_hold){ | ||
701 | trig_hightime = current_tick; | ||
702 | trig_lowtime = current_tick; | ||
703 | set_trig_status(TRIG_READY); | ||
704 | } | ||
705 | } | ||
706 | break; | ||
707 | } | ||
708 | |||
549 | /* peaks are searched -> we have to find the maximum. When | 709 | /* peaks are searched -> we have to find the maximum. When |
550 | many calls of peak_meter_peek the maximum value will be | 710 | many calls of peak_meter_peek the maximum value will be |
551 | stored in peak_meter_x. This maximum is reset by the | 711 | stored in peak_meter_x. This maximum is reset by the |
@@ -558,37 +718,6 @@ inline void peak_meter_peek(void) | |||
558 | #endif | 718 | #endif |
559 | } | 719 | } |
560 | 720 | ||
561 | |||
562 | /** | ||
563 | * The thread function for the peak meter calls peak_meter_peek | ||
564 | * to reas out the mas and find maxima, clips, etc. No display | ||
565 | * is performed. | ||
566 | */ | ||
567 | /* | ||
568 | void peak_meter_thread(void) { | ||
569 | sleep(5000); | ||
570 | while (1) { | ||
571 | if (peak_meter_enabled && peak_meter_use_thread){ | ||
572 | peak_meter_peek(); | ||
573 | } | ||
574 | yield(); | ||
575 | } | ||
576 | } | ||
577 | */ | ||
578 | |||
579 | /** | ||
580 | * Creates the peak meter thread | ||
581 | */ | ||
582 | /* | ||
583 | void peak_meter_init(void) { | ||
584 | create_thread( | ||
585 | peak_meter_thread, | ||
586 | peak_meter_stack, | ||
587 | sizeof peak_meter_stack, | ||
588 | "peakmeter"); | ||
589 | } | ||
590 | */ | ||
591 | |||
592 | /** | 721 | /** |
593 | * Reads out the peak volume of the left channel. | 722 | * Reads out the peak volume of the left channel. |
594 | * @return int - The maximum value that has been detected | 723 | * @return int - The maximum value that has been detected |
@@ -842,6 +971,22 @@ void peak_meter_draw(int x, int y, int width, int height) { | |||
842 | lcd_invertpixel(db_scale_lcd_coord[i], y + height / 2 - 1); | 971 | lcd_invertpixel(db_scale_lcd_coord[i], y + height / 2 - 1); |
843 | } | 972 | } |
844 | 973 | ||
974 | if (trig_status != TRIG_OFF) { | ||
975 | int start_trigx, stop_trigx, ycenter; | ||
976 | |||
977 | ycenter = y + height / 2; | ||
978 | /* display threshold value */ | ||
979 | start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth); | ||
980 | lcd_drawline(start_trigx, ycenter - 2, start_trigx, ycenter); | ||
981 | start_trigx ++; | ||
982 | if (start_trigx < LCD_WIDTH) lcd_drawpixel(start_trigx, ycenter - 1); | ||
983 | |||
984 | stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth); | ||
985 | lcd_drawline(stop_trigx, ycenter - 2, stop_trigx, ycenter); | ||
986 | if (stop_trigx > 0) lcd_drawpixel(stop_trigx - 1, ycenter - 1); | ||
987 | |||
988 | } | ||
989 | |||
845 | #ifdef PM_DEBUG | 990 | #ifdef PM_DEBUG |
846 | /* display a bar to show how many calls to peak_meter_peek | 991 | /* display a bar to show how many calls to peak_meter_peek |
847 | have ocurred since the last display */ | 992 | have ocurred since the last display */ |
@@ -866,6 +1011,161 @@ void peak_meter_draw(int x, int y, int width, int height) { | |||
866 | last_right = right; | 1011 | last_right = right; |
867 | } | 1012 | } |
868 | 1013 | ||
1014 | /** | ||
1015 | * Defines the parameters of the trigger. After these parameters are defined | ||
1016 | * the trigger can be started either by peak_meter_attack_trigger or by | ||
1017 | * peak_meter_release_trigger. Note that you can pass either linear (%) or | ||
1018 | * logarithmic (db) values to the thresholds. Positive values are intepreted as | ||
1019 | * percent (0 is 0% .. 100 is 100%). Negative values are interpreted as db. | ||
1020 | * To avoid ambiguosity of the value 0 the negative values are shifted by -1. | ||
1021 | * Thus -75 is -74db .. -1 is 0db. | ||
1022 | * @param start_threshold - The threshold used for attack trigger. Negative | ||
1023 | * values are interpreted as db -1, positive as %. | ||
1024 | * @param start_duration - The minimum time span within which start_threshold | ||
1025 | * must be exceeded to fire the attack trigger. | ||
1026 | * @param start_dropout - The maximum time span the level may fall below | ||
1027 | * start_threshold without releasing the attack trigger. | ||
1028 | * @param stop_threshold - The threshold the volume must fall below to release | ||
1029 | * the release trigger.Negative values are | ||
1030 | * interpreted as db -1, positive as %. | ||
1031 | * @param stop_hold - The minimum time the volume must fall below the | ||
1032 | * stop_threshold to release the trigger. | ||
1033 | * @param | ||
1034 | */ | ||
1035 | void peak_meter_define_trigger( | ||
1036 | int start_threshold, | ||
1037 | long start_duration, | ||
1038 | long start_dropout, | ||
1039 | int stop_threshold, | ||
1040 | long stop_hold_time, | ||
1041 | long restart_gap | ||
1042 | ) | ||
1043 | { | ||
1044 | if (start_threshold < 0) { | ||
1045 | /* db */ | ||
1046 | if (start_threshold < -89) { | ||
1047 | trig_strt_threshold = 0; | ||
1048 | } else { | ||
1049 | trig_strt_threshold =peak_meter_db2sample((start_threshold+1)*100); | ||
1050 | } | ||
1051 | } else { | ||
1052 | /* linear percent */ | ||
1053 | trig_strt_threshold = start_threshold * MAX_PEAK / 100; | ||
1054 | } | ||
1055 | trig_strt_duration = start_duration; | ||
1056 | trig_strt_dropout = start_dropout; | ||
1057 | if (stop_threshold < 0) { | ||
1058 | /* db */ | ||
1059 | trig_stp_threshold = peak_meter_db2sample((stop_threshold + 1) * 100); | ||
1060 | } else { | ||
1061 | /* linear percent */ | ||
1062 | trig_stp_threshold = stop_threshold * MAX_PEAK / 100; | ||
1063 | } | ||
1064 | trig_stp_hold = stop_hold_time; | ||
1065 | trig_rstrt_gap = restart_gap; | ||
1066 | } | ||
1067 | |||
1068 | /** | ||
1069 | * Enables or disables the trigger. | ||
1070 | * @param on - If true the trigger is turned on. | ||
1071 | */ | ||
1072 | void peak_meter_trigger(bool on) { | ||
1073 | /* don't use set_trigger here as that would fire an undesired event */ | ||
1074 | trig_status = on ? TRIG_READY : TRIG_OFF; | ||
1075 | } | ||
1076 | |||
1077 | /** | ||
1078 | * Registers the listener function that listenes on trig_status changes. | ||
1079 | * @param listener - The function that is called with each change of | ||
1080 | * trig_status. May be set to NULL if no callback is desired. | ||
1081 | */ | ||
1082 | void peak_meter_set_trigger_listener(void (*listener)(int status)) { | ||
1083 | trigger_listener = listener; | ||
1084 | } | ||
1085 | |||
1086 | /** | ||
1087 | * Fetches the status of the trigger. | ||
1088 | * TRIG_OFF: the trigger is inactive | ||
1089 | * TRIG_RELEASED: The volume level is below the threshold | ||
1090 | * TRIG_ACTIVATED: The volume level has exceeded the threshold, but the trigger | ||
1091 | * hasn't been fired yet. | ||
1092 | * TRIG_FIRED: The volume exceeds the threshold | ||
1093 | * | ||
1094 | * To activate the trigger call either peak_meter_attack_trigger or | ||
1095 | * peak_meter_release_trigger. To turn the trigger off call | ||
1096 | * peak_meter_trigger_off. | ||
1097 | */ | ||
1098 | int peak_meter_trigger_status(void) { | ||
1099 | return trig_status; /* & TRIG_PIT_MASK;*/ | ||
1100 | } | ||
1101 | |||
1102 | void peak_meter_draw_trig(int xpos, int ypos) { | ||
1103 | int x = xpos + ICON_PLAY_STATE_WIDTH + 1; | ||
1104 | switch (trig_status) { | ||
1105 | long time_left; | ||
1106 | |||
1107 | case TRIG_READY: | ||
1108 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | ||
1109 | TRIGBAR_WIDTH, 0, 0, HORIZONTAL); | ||
1110 | lcd_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos, | ||
1111 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT, false); | ||
1112 | break; | ||
1113 | |||
1114 | case TRIG_STEADY: | ||
1115 | case TRIG_RETRIG: | ||
1116 | time_left = trig_strt_duration - (current_tick - trig_hightime); | ||
1117 | time_left = time_left * TRIGBAR_WIDTH / trig_strt_duration; | ||
1118 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | ||
1119 | TRIGBAR_WIDTH, 0, TRIGBAR_WIDTH - time_left, HORIZONTAL); | ||
1120 | lcd_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos, | ||
1121 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT, false); | ||
1122 | break; | ||
1123 | |||
1124 | case TRIG_GO: | ||
1125 | case TRIG_CONTINUE: | ||
1126 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | ||
1127 | TRIGBAR_WIDTH, TRIGBAR_WIDTH, TRIGBAR_WIDTH, HORIZONTAL); | ||
1128 | lcd_bitmap(bitmap_icons_7x8[Icon_Record], | ||
1129 | TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos, | ||
1130 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT, false); | ||
1131 | break; | ||
1132 | |||
1133 | case TRIG_POSTREC: | ||
1134 | time_left = trig_stp_hold - (current_tick - trig_lowtime); | ||
1135 | time_left = time_left * TRIGBAR_WIDTH / trig_stp_hold; | ||
1136 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | ||
1137 | TRIGBAR_WIDTH, time_left, TRIGBAR_WIDTH, HORIZONTAL); | ||
1138 | lcd_bitmap(bitmap_icons_7x8[Icon_Record], | ||
1139 | TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos, | ||
1140 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT, false); | ||
1141 | break; | ||
1142 | } | ||
1143 | |||
1144 | } | ||
1145 | |||
1146 | int peak_meter_draw_get_btn(int x, int y, int width, int height) | ||
1147 | { | ||
1148 | int button; | ||
1149 | long next_refresh = current_tick; | ||
1150 | long next_big_refresh = current_tick + HZ / 10; | ||
1151 | button = BUTTON_NONE; | ||
1152 | while (!TIME_AFTER(current_tick, next_big_refresh)) { | ||
1153 | button = button_get(false); | ||
1154 | if (button != BUTTON_NONE) { | ||
1155 | break; | ||
1156 | } | ||
1157 | peak_meter_peek(); | ||
1158 | yield(); | ||
1159 | |||
1160 | if (TIME_AFTER(current_tick, next_refresh)) { | ||
1161 | peak_meter_draw(x, y, width, height); | ||
1162 | lcd_update_rect(x, y, width, height); | ||
1163 | next_refresh = current_tick + HZ / peak_meter_fps; | ||
1164 | } | ||
1165 | } | ||
1166 | return button; | ||
1167 | } | ||
1168 | |||
869 | #ifdef PM_DEBUG | 1169 | #ifdef PM_DEBUG |
870 | static void peak_meter_clear_histogram(void) { | 1170 | static void peak_meter_clear_histogram(void) { |
871 | int i = 0; | 1171 | int i = 0; |