diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-08-29 20:07:17 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-08-29 20:07:17 +0000 |
commit | 99a0598c284471342fcda1fdcba90d4b666bfbb3 (patch) | |
tree | 83cc502095e87277de770456498d2de6cf8f473b /apps/recorder/peakmeter.c | |
parent | 89a8ca4408c3ea34464898b0ce52a0d8351fa323 (diff) | |
download | rockbox-99a0598c284471342fcda1fdcba90d4b666bfbb3.tar.gz rockbox-99a0598c284471342fcda1fdcba90d4b666bfbb3.zip |
Major peakmeter rework: * Changed set/get functions for dbfs mode to bool type. * Removed performance setting, leaving (slightly adapted) high performance mode only. * Refresh rate is always 20 Hz now. * Readout doesn't do an extra (hidden) peek, should allow for slightly better clip detection. * Brought back high performance peakmeter for recording. Peakmeter stops hogging the CPU when the disk is spinning; this is enough to avoid the performance problem when saving data. * Optimisations, code cleanup and code policeing. * (iriver) Reduced CPU load of peakmeter by not calculating excessive overlaps. ** Bumped config block version, so save your settings before upgrading.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7415 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder/peakmeter.c')
-rw-r--r-- | apps/recorder/peakmeter.c | 524 |
1 files changed, 255 insertions, 269 deletions
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c index 002a3c48d5..088cf8e099 100644 --- a/apps/recorder/peakmeter.c +++ b/apps/recorder/peakmeter.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "thread.h" | 21 | #include "thread.h" |
22 | #include "kernel.h" | 22 | #include "kernel.h" |
23 | #include "settings.h" | 23 | #include "settings.h" |
24 | #include "ata.h" | ||
24 | #include "lcd.h" | 25 | #include "lcd.h" |
25 | #include "widgets.h" | 26 | #include "widgets.h" |
26 | #include "wps-display.h" | 27 | #include "wps-display.h" |
@@ -36,41 +37,48 @@ | |||
36 | #include "pcm_playback.h" | 37 | #include "pcm_playback.h" |
37 | #endif | 38 | #endif |
38 | 39 | ||
39 | /* no inline in simulator mode */ | 40 | #if !defined(SIMULATOR) && CONFIG_HWCODEC != MASNONE |
40 | #ifdef SIMULATOR | 41 | /* Data source */ |
41 | #define inline | 42 | static int pm_src_left = MAS_REG_DQPEAK_L; |
43 | static int pm_src_right = MAS_REG_DQPEAK_R; | ||
42 | #endif | 44 | #endif |
43 | 45 | ||
44 | /* buffer the read peak value */ | 46 | /* Current values and cumulation */ |
45 | static int peak_meter_max_l; | 47 | static int pm_cur_left; /* current values (last peak_meter_peek) */ |
46 | static int peak_meter_max_r; | 48 | static int pm_cur_right; |
47 | 49 | static int pm_max_left; /* maximum values between peak meter draws */ | |
48 | /* point in time when peak_meter_max_x becomes invalid */ | 50 | static int pm_max_right; |
49 | static long peak_meter_timeout_l; | 51 | |
50 | static long peak_meter_timeout_r; | 52 | /* Peak hold */ |
51 | 53 | static int pm_peak_left; /* buffered peak values */ | |
52 | /* when true a clip has occurred */ | 54 | static int pm_peak_right; |
53 | static bool peak_meter_l_clip = false; | 55 | static long pm_peak_timeout_l; /* peak hold timeouts */ |
54 | static bool peak_meter_r_clip = false; | 56 | static long pm_peak_timeout_r; |
55 | 57 | ||
56 | /* point in time when peak_meter_x_oveflow becomes invalid */ | 58 | /* Clip hold */ |
57 | static long peak_meter_clip_timeout_l; | 59 | static bool pm_clip_left = false; /* when true a clip has occurred */ |
58 | static long peak_meter_clip_timeout_r; | 60 | static bool pm_clip_right = false; |
59 | 61 | static long pm_clip_timeout_l; /* clip hold timeouts */ | |
60 | static int peak_meter_clip_hold; | 62 | static long pm_clip_timeout_r; |
61 | 63 | ||
62 | /* specifies the value range in peak volume values */ | 64 | /* Temporarily en- / disables peak meter. This is especially for external |
63 | unsigned short peak_meter_range_min; | 65 | applications to detect if the peak_meter is in use and needs drawing at all */ |
64 | unsigned short peak_meter_range_max; | 66 | bool peak_meter_enabled = true; |
65 | static unsigned short peak_meter_range; | ||
66 | |||
67 | /* if set to true clip timeout is disabled */ | ||
68 | static bool peak_meter_clip_eternal = false; | ||
69 | 67 | ||
70 | static bool peak_meter_use_dbfs = true; | 68 | /** Parameters **/ |
71 | static unsigned short db_min = 0; | 69 | /* Range */ |
72 | static unsigned short db_max = 9000; | 70 | unsigned short peak_meter_range_min; /* minimum of range in samples */ |
73 | static unsigned short db_range = 9000; | 71 | unsigned short peak_meter_range_max; /* maximum of range in samples */ |
72 | static unsigned short pm_range; /* range width in samples */ | ||
73 | static bool pm_use_dbfs = true; /* true if peakmeter displays dBfs */ | ||
74 | static unsigned short pm_db_min = 0; /* minimum of range in 1/100 dB */ | ||
75 | static unsigned short pm_db_max = 9000; /* maximum of range in 1/100 dB */ | ||
76 | static unsigned short pm_db_range = 9000; /* range width in 1/100 dB */ | ||
77 | /* Timing behaviour */ | ||
78 | static int pm_peak_hold = 1; /* peak hold timeout index */ | ||
79 | static int pm_peak_release = 8; /* peak release in units per read */ | ||
80 | static int pm_clip_hold = 16; /* clip hold timeout index */ | ||
81 | static bool pm_clip_eternal = false; /* true if clip timeout is disabled */ | ||
74 | 82 | ||
75 | #ifdef HAVE_RECORDING | 83 | #ifdef HAVE_RECORDING |
76 | static unsigned short trig_strt_threshold; | 84 | static unsigned short trig_strt_threshold; |
@@ -92,34 +100,6 @@ static int trig_status = TRIG_OFF; | |||
92 | static void (*trigger_listener)(int) = NULL; | 100 | static void (*trigger_listener)(int) = NULL; |
93 | #endif | 101 | #endif |
94 | 102 | ||
95 | #if CONFIG_HWCODEC == MASNONE | ||
96 | #define MAS_REG_DQPEAK_L 0 | ||
97 | #define MAS_REG_DQPEAK_R 0 | ||
98 | #endif | ||
99 | |||
100 | #if !defined(SIMULATOR) && CONFIG_HWCODEC != MASNONE | ||
101 | static int peak_meter_src_l = MAS_REG_DQPEAK_L; | ||
102 | static int peak_meter_src_r = MAS_REG_DQPEAK_R; | ||
103 | #endif | ||
104 | |||
105 | /* temporarily en- / disables peak meter. This is | ||
106 | especially for external applications to detect | ||
107 | if the peak_meter is in use and needs drawing at all */ | ||
108 | bool peak_meter_enabled = true; | ||
109 | |||
110 | /* | ||
111 | bool peak_meter_use_thread = false; | ||
112 | static char peak_meter_stack[DEFAULT_STACK_SIZE]; | ||
113 | */ | ||
114 | /* used in wps.c to set the display frame rate of the peak meter */ | ||
115 | int peak_meter_fps = 20; | ||
116 | |||
117 | static int peak_meter_l; | ||
118 | static int peak_meter_r; | ||
119 | |||
120 | static int peak_meter_hold = 1; | ||
121 | static int peak_meter_release = 8; | ||
122 | |||
123 | /* debug only */ | 103 | /* debug only */ |
124 | #ifdef PM_DEBUG | 104 | #ifdef PM_DEBUG |
125 | static int peek_calls = 0; | 105 | static int peek_calls = 0; |
@@ -132,7 +112,7 @@ static unsigned int ticks_per_redraw[TICKS_PER_DRAW_SIZE]; | |||
132 | #endif | 112 | #endif |
133 | 113 | ||
134 | /* time out values for max */ | 114 | /* time out values for max */ |
135 | static const long max_time_out[] = { | 115 | static const short peak_time_out[] = { |
136 | 0 * HZ, HZ / 5, 30, HZ / 2, HZ, 2 * HZ, | 116 | 0 * HZ, HZ / 5, 30, HZ / 2, HZ, 2 * HZ, |
137 | 3 * HZ, 4 * HZ, 5 * HZ, 6 * HZ, 7 * HZ, 8 * HZ, | 117 | 3 * HZ, 4 * HZ, 5 * HZ, 6 * HZ, 7 * HZ, 8 * HZ, |
138 | 9 * HZ, 10 * HZ, 15 * HZ, 20 * HZ, 30 * HZ, 60 * HZ | 118 | 9 * HZ, 10 * HZ, 15 * HZ, 20 * HZ, 30 * HZ, 60 * HZ |
@@ -150,22 +130,6 @@ static const long clip_time_out[] = { | |||
150 | /* precalculated peak values that represent magical | 130 | /* precalculated peak values that represent magical |
151 | dBfs values. Used to draw the scale */ | 131 | dBfs values. Used to draw the scale */ |
152 | #define DB_SCALE_SRC_VALUES_SIZE 12 | 132 | #define DB_SCALE_SRC_VALUES_SIZE 12 |
153 | #if 0 | ||
154 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | ||
155 | 32767, /* 0 db */ | ||
156 | 23197, /* - 3 db */ | ||
157 | 16422, /* - 6 db */ | ||
158 | 11626, /* - 9 db */ | ||
159 | 8231, /* -12 db */ | ||
160 | 4125, /* -18 db */ | ||
161 | 2067, /* -24 db */ | ||
162 | 1036, /* -30 db */ | ||
163 | 328, /* -40 db */ | ||
164 | 104, /* -50 db */ | ||
165 | 33, /* -60 db */ | ||
166 | 1, /* -inf */ | ||
167 | }; | ||
168 | #else | ||
169 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | 133 | static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { |
170 | 32752, /* 0 db */ | 134 | 32752, /* 0 db */ |
171 | 22784, /* - 3 db */ | 135 | 22784, /* - 3 db */ |
@@ -180,11 +144,10 @@ static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { | |||
180 | 33, /* -60 db */ | 144 | 33, /* -60 db */ |
181 | 0, /* -inf */ | 145 | 0, /* -inf */ |
182 | }; | 146 | }; |
183 | #endif | ||
184 | 147 | ||
185 | static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; | 148 | static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; |
186 | 149 | ||
187 | /* if db_scale_valid is false the content of | 150 | /* if db_scale_valid is false the content of |
188 | db_scale_lcd_coord needs recalculation */ | 151 | db_scale_lcd_coord needs recalculation */ |
189 | static bool db_scale_valid = false; | 152 | static bool db_scale_valid = false; |
190 | 153 | ||
@@ -211,7 +174,8 @@ static int db_scale_lcd_coord[sizeof db_scale_src_values / sizeof (int)]; | |||
211 | * for-loops. | 174 | * for-loops. |
212 | */ | 175 | */ |
213 | 176 | ||
214 | int calc_db (int isample) { | 177 | int calc_db (int isample) |
178 | { | ||
215 | /* return n+m*(isample-istart)/100 */ | 179 | /* return n+m*(isample-istart)/100 */ |
216 | int n; | 180 | int n; |
217 | long m; | 181 | long m; |
@@ -312,7 +276,8 @@ int calc_db (int isample) { | |||
312 | * minimal peak sample is searched. | 276 | * minimal peak sample is searched. |
313 | * @return int - A linear volume value with 0 <= value < MAX_PEAK | 277 | * @return int - A linear volume value with 0 <= value < MAX_PEAK |
314 | */ | 278 | */ |
315 | static int db_to_sample_bin_search(int min, int max, int db){ | 279 | static int db_to_sample_bin_search(int min, int max, int db) |
280 | { | ||
316 | int test = min + (max - min) / 2; | 281 | int test = min + (max - min) / 2; |
317 | 282 | ||
318 | if (min < max) { | 283 | if (min < max) { |
@@ -339,7 +304,8 @@ static int db_to_sample_bin_search(int min, int max, int db){ | |||
339 | * @return int - The return value is in the range of | 304 | * @return int - The return value is in the range of |
340 | * 0 <= return value < MAX_PEAK | 305 | * 0 <= return value < MAX_PEAK |
341 | */ | 306 | */ |
342 | int peak_meter_db2sample(int db) { | 307 | int peak_meter_db2sample(int db) |
308 | { | ||
343 | int retval = 0; | 309 | int retval = 0; |
344 | 310 | ||
345 | /* what is the maximum pseudo db value */ | 311 | /* what is the maximum pseudo db value */ |
@@ -371,13 +337,14 @@ int peak_meter_db2sample(int db) { | |||
371 | 337 | ||
372 | /** | 338 | /** |
373 | * Set the min value for restriction of the value range. | 339 | * Set the min value for restriction of the value range. |
374 | * @param int newmin - depending wether dBfs is used | 340 | * @param int newmin - depending whether dBfs is used |
375 | * newmin is a value in dBfs * 100 or in linear percent values. | 341 | * newmin is a value in dBfs * 100 or in linear percent values. |
376 | * for dBfs: -9000 < newmin <= 0 | 342 | * for dBfs: -9000 < newmin <= 0 |
377 | * for linear: 0 <= newmin <= 100 | 343 | * for linear: 0 <= newmin <= 100 |
378 | */ | 344 | */ |
379 | void peak_meter_set_min(int newmin) { | 345 | void peak_meter_set_min(int newmin) |
380 | if (peak_meter_use_dbfs) { | 346 | { |
347 | if (pm_use_dbfs) { | ||
381 | peak_meter_range_min = peak_meter_db2sample(newmin); | 348 | peak_meter_range_min = peak_meter_db2sample(newmin); |
382 | 349 | ||
383 | } else { | 350 | } else { |
@@ -386,10 +353,10 @@ void peak_meter_set_min(int newmin) { | |||
386 | } | 353 | } |
387 | } | 354 | } |
388 | 355 | ||
389 | peak_meter_range = peak_meter_range_max - peak_meter_range_min; | 356 | pm_range = peak_meter_range_max - peak_meter_range_min; |
390 | 357 | ||
391 | db_min = calc_db(peak_meter_range_min); | 358 | pm_db_min = calc_db(peak_meter_range_min); |
392 | db_range = db_max - db_min; | 359 | pm_db_range = pm_db_max - pm_db_min; |
393 | db_scale_valid = false; | 360 | db_scale_valid = false; |
394 | } | 361 | } |
395 | 362 | ||
@@ -400,9 +367,10 @@ void peak_meter_set_min(int newmin) { | |||
400 | * @return: using dBfs : -9000 < value <= 0 | 367 | * @return: using dBfs : -9000 < value <= 0 |
401 | * using linear scale: 0 <= value <= 100 | 368 | * using linear scale: 0 <= value <= 100 |
402 | */ | 369 | */ |
403 | int peak_meter_get_min(void) { | 370 | int peak_meter_get_min(void) |
371 | { | ||
404 | int retval = 0; | 372 | int retval = 0; |
405 | if (peak_meter_use_dbfs) { | 373 | if (pm_use_dbfs) { |
406 | retval = calc_db(peak_meter_range_min) - calc_db(MAX_PEAK - 1); | 374 | retval = calc_db(peak_meter_range_min) - calc_db(MAX_PEAK - 1); |
407 | } else { | 375 | } else { |
408 | retval = peak_meter_range_min * 100 / MAX_PEAK; | 376 | retval = peak_meter_range_min * 100 / MAX_PEAK; |
@@ -417,8 +385,9 @@ int peak_meter_get_min(void) { | |||
417 | * for dBfs: -9000 < newmax <= 0 | 385 | * for dBfs: -9000 < newmax <= 0 |
418 | * for linear: 0 <= newmax <= 100 | 386 | * for linear: 0 <= newmax <= 100 |
419 | */ | 387 | */ |
420 | void peak_meter_set_max(int newmax) { | 388 | void peak_meter_set_max(int newmax) |
421 | if (peak_meter_use_dbfs) { | 389 | { |
390 | if (pm_use_dbfs) { | ||
422 | peak_meter_range_max = peak_meter_db2sample(newmax); | 391 | peak_meter_range_max = peak_meter_db2sample(newmax); |
423 | } else { | 392 | } else { |
424 | if (newmax > peak_meter_range_min) { | 393 | if (newmax > peak_meter_range_min) { |
@@ -426,10 +395,10 @@ void peak_meter_set_max(int newmax) { | |||
426 | } | 395 | } |
427 | } | 396 | } |
428 | 397 | ||
429 | peak_meter_range = peak_meter_range_max - peak_meter_range_min; | 398 | pm_range = peak_meter_range_max - peak_meter_range_min; |
430 | 399 | ||
431 | db_max = calc_db(peak_meter_range_max); | 400 | pm_db_max = calc_db(peak_meter_range_max); |
432 | db_range = db_max - db_min; | 401 | pm_db_range = pm_db_max - pm_db_min; |
433 | db_scale_valid = false; | 402 | db_scale_valid = false; |
434 | } | 403 | } |
435 | 404 | ||
@@ -440,9 +409,10 @@ void peak_meter_set_max(int newmax) { | |||
440 | * @return: using dBfs : -9000 < value <= 0 | 409 | * @return: using dBfs : -9000 < value <= 0 |
441 | * using linear scale: 0 <= value <= 100 | 410 | * using linear scale: 0 <= value <= 100 |
442 | */ | 411 | */ |
443 | int peak_meter_get_max(void) { | 412 | int peak_meter_get_max(void) |
413 | { | ||
444 | int retval = 0; | 414 | int retval = 0; |
445 | if (peak_meter_use_dbfs) { | 415 | if (pm_use_dbfs) { |
446 | retval = calc_db(peak_meter_range_max) - calc_db(MAX_PEAK - 1); | 416 | retval = calc_db(peak_meter_range_max) - calc_db(MAX_PEAK - 1); |
447 | } else { | 417 | } else { |
448 | retval = peak_meter_range_max * 100 / MAX_PEAK; | 418 | retval = peak_meter_range_max * 100 / MAX_PEAK; |
@@ -451,23 +421,24 @@ int peak_meter_get_max(void) { | |||
451 | } | 421 | } |
452 | 422 | ||
453 | /** | 423 | /** |
454 | * Returns 1 if the meter currently is | 424 | * Returns whether the meter is currently displaying dBfs or percent values. |
455 | * displaying dBfs values, 0 if the meter | 425 | * @return bool - true if the meter is displaying dBfs |
456 | * displays percent values. | 426 | false if the meter is displaying percent values. |
457 | * @return int - returns 0 or 1. | ||
458 | */ | 427 | */ |
459 | int peak_meter_get_use_dbfs(void) { | 428 | bool peak_meter_get_use_dbfs(void) |
460 | return peak_meter_use_dbfs ? 1 : 0; | 429 | { |
430 | return pm_use_dbfs; | ||
461 | } | 431 | } |
462 | 432 | ||
463 | /** | 433 | /** |
464 | * Specifies wether the values displayed are scaled | 434 | * Specifies whether the values displayed are scaled |
465 | * as dBfs or as linear percent values. | 435 | * as dBfs or as linear percent values. |
466 | * @param int - Set to 0 for linear percent scale. Any other value | 436 | * @param use - set to true for dBfs, |
467 | * switches on dBfs. | 437 | * set to false for linear scaling in percent |
468 | */ | 438 | */ |
469 | void peak_meter_set_use_dbfs(int use){ | 439 | void peak_meter_set_use_dbfs(bool use) |
470 | peak_meter_use_dbfs = ((use & 1) == 1); | 440 | { |
441 | pm_use_dbfs = use; | ||
471 | db_scale_valid = false; | 442 | db_scale_valid = false; |
472 | } | 443 | } |
473 | 444 | ||
@@ -486,7 +457,7 @@ void peak_meter_set_use_dbfs(int use){ | |||
486 | */ | 457 | */ |
487 | void peak_meter_init_range( bool dbfs, int range_min, int range_max) | 458 | void peak_meter_init_range( bool dbfs, int range_min, int range_max) |
488 | { | 459 | { |
489 | peak_meter_use_dbfs = dbfs; | 460 | pm_use_dbfs = dbfs; |
490 | peak_meter_set_min(range_min); | 461 | peak_meter_set_min(range_min); |
491 | peak_meter_set_max(range_max); | 462 | peak_meter_set_max(range_max); |
492 | } | 463 | } |
@@ -497,15 +468,16 @@ void peak_meter_init_range( bool dbfs, int range_min, int range_max) | |||
497 | * to decrease with each redraw | 468 | * to decrease with each redraw |
498 | * @param int hold - Select the time preset for the time the peak indicator | 469 | * @param int hold - Select the time preset for the time the peak indicator |
499 | * is reset after a peak occurred. The preset values are | 470 | * is reset after a peak occurred. The preset values are |
500 | * stored in max_time_out. | 471 | * stored in peak_time_out. |
501 | * @param int clip_hold - Select the time preset for the time the peak | 472 | * @param int clip_hold - Select the time preset for the time the peak |
502 | * indicator is reset after a peak occurred. The preset | 473 | * indicator is reset after a peak occurred. The preset |
503 | * values are stored in clip_time_out. | 474 | * values are stored in clip_time_out. |
504 | */ | 475 | */ |
505 | void peak_meter_init_times(int release, int hold, int clip_hold) { | 476 | void peak_meter_init_times(int release, int hold, int clip_hold) |
506 | peak_meter_hold = hold; | 477 | { |
507 | peak_meter_release = release; | 478 | pm_peak_hold = hold; |
508 | peak_meter_clip_hold = clip_hold; | 479 | pm_peak_release = release; |
480 | pm_clip_hold = clip_hold; | ||
509 | } | 481 | } |
510 | 482 | ||
511 | /** | 483 | /** |
@@ -523,17 +495,18 @@ void peak_meter_playback(bool playback) | |||
523 | (void)playback; | 495 | (void)playback; |
524 | #else | 496 | #else |
525 | if (playback) { | 497 | if (playback) { |
526 | peak_meter_src_l = MAS_REG_DQPEAK_L; | 498 | pm_src_left = MAS_REG_DQPEAK_L; |
527 | peak_meter_src_r = MAS_REG_DQPEAK_R; | 499 | pm_src_right = MAS_REG_DQPEAK_R; |
528 | } else { | 500 | } else { |
529 | peak_meter_src_l = MAS_REG_QPEAK_L; | 501 | pm_src_left = MAS_REG_QPEAK_L; |
530 | peak_meter_src_r = MAS_REG_QPEAK_R; | 502 | pm_src_right = MAS_REG_QPEAK_R; |
531 | } | 503 | } |
532 | #endif | 504 | #endif |
533 | } | 505 | } |
534 | 506 | ||
535 | #ifdef HAVE_RECORDING | 507 | #ifdef HAVE_RECORDING |
536 | static void set_trig_status(int new_state) { | 508 | static void set_trig_status(int new_state) |
509 | { | ||
537 | if (trig_status != new_state) { | 510 | if (trig_status != new_state) { |
538 | trig_status = new_state; | 511 | trig_status = new_state; |
539 | if (trigger_listener != NULL) { | 512 | if (trigger_listener != NULL) { |
@@ -545,24 +518,25 @@ static void set_trig_status(int new_state) { | |||
545 | 518 | ||
546 | /** | 519 | /** |
547 | * Reads peak values from the MAS, and detects clips. The | 520 | * Reads peak values from the MAS, and detects clips. The |
548 | * values are stored in peak_meter_l peak_meter_r for later | 521 | * values are stored in pm_max_left pm_max_right for later |
549 | * evauluation. Consecutive calls to peak_meter_peek detect | 522 | * evauluation. Consecutive calls to peak_meter_peek detect |
550 | * that ocurred. This function could be used by a thread for | 523 | * that ocurred. This function could be used by a thread for |
551 | * busy reading the MAS. | 524 | * busy reading the MAS. |
552 | */ | 525 | */ |
553 | inline void peak_meter_peek(void) | 526 | void peak_meter_peek(void) |
554 | { | 527 | { |
528 | int left, right; | ||
529 | /* read current values */ | ||
555 | #ifdef SIMULATOR | 530 | #ifdef SIMULATOR |
556 | int left = 8000; | 531 | pm_cur_left = left = 8000; |
557 | int right = 9000; | 532 | pm_cur_right = right = 9000; |
558 | #elif CONFIG_HWCODEC == MASNONE | 533 | #elif CONFIG_HWCODEC == MASNONE |
559 | int left; | 534 | pcm_calculate_peaks(&pm_cur_left, &pm_cur_right); |
560 | int right; | 535 | left = pm_cur_left; |
561 | pcm_calculate_peaks(&left, &right); | 536 | right = pm_cur_right; |
562 | #else | 537 | #else |
563 | /* read the peak values */ | 538 | pm_cur_left = left = mas_codec_readreg(pm_src_left); |
564 | int left = mas_codec_readreg(peak_meter_src_l); | 539 | pm_cur_right = right = mas_codec_readreg(pm_src_right); |
565 | int right = mas_codec_readreg(peak_meter_src_r); | ||
566 | #endif | 540 | #endif |
567 | 541 | ||
568 | /* check for clips | 542 | /* check for clips |
@@ -571,26 +545,34 @@ inline void peak_meter_peek(void) | |||
571 | to be inaccurate in both ways: it may detect clips | 545 | to be inaccurate in both ways: it may detect clips |
572 | when no clip occurred and it may fail to detect | 546 | when no clip occurred and it may fail to detect |
573 | a real clip. */ | 547 | a real clip. */ |
574 | if ((left == peak_meter_l) && | 548 | if ((left == pm_max_left) && |
575 | (left == MAX_PEAK - 1)) { | 549 | (left == MAX_PEAK - 1)) { |
576 | peak_meter_l_clip = true; | 550 | pm_clip_left = true; |
577 | peak_meter_clip_timeout_l = | 551 | pm_clip_timeout_l = |
578 | current_tick + clip_time_out[peak_meter_clip_hold]; | 552 | current_tick + clip_time_out[pm_clip_hold]; |
579 | } | 553 | } |
580 | 554 | ||
581 | if ((right == peak_meter_r) && | 555 | if ((right == pm_max_right) && |
582 | (right == MAX_PEAK - 1)) { | 556 | (right == MAX_PEAK - 1)) { |
583 | peak_meter_r_clip = true; | 557 | pm_clip_right = true; |
584 | peak_meter_clip_timeout_r = | 558 | pm_clip_timeout_r = |
585 | current_tick + clip_time_out[peak_meter_clip_hold]; | 559 | current_tick + clip_time_out[pm_clip_hold]; |
586 | } | 560 | } |
587 | 561 | ||
562 | /* peaks are searched -> we have to find the maximum. When | ||
563 | many calls of peak_meter_peek the maximum value will be | ||
564 | stored in pm_max_xxx. This maximum is reset by the | ||
565 | functions peak_meter_read_x. */ | ||
566 | pm_max_left = MAX(pm_max_left, left); | ||
567 | pm_max_right = MAX(pm_max_right, right); | ||
568 | |||
588 | #ifdef HAVE_RECORDING | 569 | #ifdef HAVE_RECORDING |
589 | switch (trig_status) { | 570 | switch (trig_status) { |
590 | case TRIG_READY: | 571 | case TRIG_READY: |
591 | /* no more changes, if trigger was activated as release trigger */ | 572 | /* no more changes, if trigger was activated as release trigger */ |
592 | /* threshold exceeded? */ | 573 | /* threshold exceeded? */ |
593 | if ((left > trig_strt_threshold) || (right > trig_strt_threshold)) { | 574 | if ((left > trig_strt_threshold) |
575 | || (right > trig_strt_threshold)) { | ||
594 | if (trig_strt_duration) { | 576 | if (trig_strt_duration) { |
595 | /* reset trigger duration */ | 577 | /* reset trigger duration */ |
596 | trig_hightime = current_tick; | 578 | trig_hightime = current_tick; |
@@ -614,8 +596,8 @@ inline void peak_meter_peek(void) | |||
614 | set_trig_status(TRIG_GO); | 596 | set_trig_status(TRIG_GO); |
615 | } else { | 597 | } else { |
616 | /* threshold exceeded? */ | 598 | /* threshold exceeded? */ |
617 | if ((left > trig_strt_threshold) || | 599 | if ((left > trig_strt_threshold) |
618 | (right > trig_strt_threshold)) { | 600 | || (right > trig_strt_threshold)) { |
619 | /* reset lowtime */ | 601 | /* reset lowtime */ |
620 | trig_lowtime = current_tick; | 602 | trig_lowtime = current_tick; |
621 | } | 603 | } |
@@ -640,7 +622,8 @@ inline void peak_meter_peek(void) | |||
640 | case TRIG_GO: | 622 | case TRIG_GO: |
641 | case TRIG_CONTINUE: | 623 | case TRIG_CONTINUE: |
642 | /* threshold exceeded? */ | 624 | /* threshold exceeded? */ |
643 | if ((left > trig_stp_threshold) || (right > trig_stp_threshold)) { | 625 | if ((left > trig_stp_threshold) |
626 | || (right > trig_stp_threshold)) { | ||
644 | /* restart hold time countdown */ | 627 | /* restart hold time countdown */ |
645 | trig_lowtime = current_tick; | 628 | trig_lowtime = current_tick; |
646 | } else { | 629 | } else { |
@@ -653,8 +636,8 @@ inline void peak_meter_peek(void) | |||
653 | /* gap time expired? */ | 636 | /* gap time expired? */ |
654 | if (current_tick - trig_lowtime > trig_rstrt_gap){ | 637 | if (current_tick - trig_lowtime > trig_rstrt_gap){ |
655 | /* start threshold exceeded? */ | 638 | /* start threshold exceeded? */ |
656 | if ((left > trig_strt_threshold) || | 639 | if ((left > trig_strt_threshold) |
657 | (right > trig_strt_threshold)) { | 640 | || (right > trig_strt_threshold)) { |
658 | 641 | ||
659 | set_trig_status(TRIG_RETRIG); | 642 | set_trig_status(TRIG_RETRIG); |
660 | trig_hightime = current_tick; | 643 | trig_hightime = current_tick; |
@@ -662,8 +645,8 @@ inline void peak_meter_peek(void) | |||
662 | else | 645 | else |
663 | 646 | ||
664 | /* stop threshold exceeded */ | 647 | /* stop threshold exceeded */ |
665 | if ((left > trig_stp_threshold) || | 648 | if ((left > trig_stp_threshold) |
666 | (right > trig_stp_threshold)) { | 649 | || (right > trig_stp_threshold)) { |
667 | if (current_tick - trig_hightime > trig_stp_hold){ | 650 | if (current_tick - trig_hightime > trig_stp_hold){ |
668 | trig_lowtime = current_tick; | 651 | trig_lowtime = current_tick; |
669 | set_trig_status(TRIG_CONTINUE); | 652 | set_trig_status(TRIG_CONTINUE); |
@@ -685,8 +668,8 @@ inline void peak_meter_peek(void) | |||
685 | /* still within the gap time */ | 668 | /* still within the gap time */ |
686 | else { | 669 | else { |
687 | /* stop threshold exceeded */ | 670 | /* stop threshold exceeded */ |
688 | if ((left > trig_stp_threshold) || | 671 | if ((left > trig_stp_threshold) |
689 | (right > trig_stp_threshold)) { | 672 | || (right > trig_stp_threshold)) { |
690 | set_trig_status(TRIG_CONTINUE); | 673 | set_trig_status(TRIG_CONTINUE); |
691 | trig_lowtime = current_tick; | 674 | trig_lowtime = current_tick; |
692 | } | 675 | } |
@@ -702,13 +685,6 @@ inline void peak_meter_peek(void) | |||
702 | } | 685 | } |
703 | #endif | 686 | #endif |
704 | 687 | ||
705 | /* peaks are searched -> we have to find the maximum. When | ||
706 | many calls of peak_meter_peek the maximum value will be | ||
707 | stored in peak_meter_x. This maximum is reset by the | ||
708 | functions peak_meter_read_x. */ | ||
709 | peak_meter_l = MAX(peak_meter_l, left); | ||
710 | peak_meter_r = MAX(peak_meter_r, right); | ||
711 | |||
712 | #ifdef PM_DEBUG | 688 | #ifdef PM_DEBUG |
713 | peek_calls++; | 689 | peek_calls++; |
714 | #endif | 690 | #endif |
@@ -720,26 +696,18 @@ inline void peak_meter_peek(void) | |||
720 | * since the last call of peak_meter_read_l. The value | 696 | * since the last call of peak_meter_read_l. The value |
721 | * is in the range 0 <= value < MAX_PEAK. | 697 | * is in the range 0 <= value < MAX_PEAK. |
722 | */ | 698 | */ |
723 | static int peak_meter_read_l (void) | 699 | static int peak_meter_read_l(void) |
724 | { | 700 | { |
725 | /* peak_meter_l contains the maximum of | 701 | /* pm_max_left contains the maximum of all peak values that were read |
726 | all peak values that were read by peak_meter_peek | 702 | by peak_meter_peek since the last call of peak_meter_read_l */ |
727 | since the last call of peak_meter_read_r */ | 703 | int retval = pm_max_left; |
728 | int retval = peak_meter_l; | 704 | |
729 | #ifdef PM_DEBUG | 705 | #ifdef PM_DEBUG |
730 | peek_calls = 0; | 706 | peek_calls = 0; |
731 | #endif | 707 | #endif |
732 | 708 | /* reset pm_max_left so that subsequent calls of peak_meter_peek don't | |
733 | #ifdef SIMULATOR | 709 | get fooled by an old maximum value */ |
734 | peak_meter_l = 8000; | 710 | pm_max_left = pm_cur_left; |
735 | #elif CONFIG_HWCODEC == MASNONE | ||
736 | pcm_calculate_peaks(&peak_meter_l, NULL); | ||
737 | #else | ||
738 | /* reset peak_meter_l so that subsequent calls of | ||
739 | peak_meter_peek doesn't get fooled by an old | ||
740 | maximum value */ | ||
741 | peak_meter_l = mas_codec_readreg(peak_meter_src_l); | ||
742 | #endif | ||
743 | return retval; | 711 | return retval; |
744 | } | 712 | } |
745 | 713 | ||
@@ -749,25 +717,18 @@ static int peak_meter_read_l (void) | |||
749 | * since the last call of peak_meter_read_l. The value | 717 | * since the last call of peak_meter_read_l. The value |
750 | * is in the range 0 <= value < MAX_PEAK. | 718 | * is in the range 0 <= value < MAX_PEAK. |
751 | */ | 719 | */ |
752 | static int peak_meter_read_r (void) { | 720 | static int peak_meter_read_r(void) |
753 | /* peak_meter_r contains the maximum of | 721 | { |
754 | all peak values that were read by peak_meter_peek | 722 | /* peak_meter_r contains the maximum of all peak values that were read |
755 | since the last call of peak_meter_read_r */ | 723 | by peak_meter_peek since the last call of peak_meter_read_r */ |
756 | int retval = peak_meter_r; | 724 | int retval = pm_max_right; |
725 | |||
757 | #ifdef PM_DEBUG | 726 | #ifdef PM_DEBUG |
758 | peek_calls = 0; | 727 | peek_calls = 0; |
759 | #endif | 728 | #endif |
760 | 729 | /* reset pm_max_right so that subsequent calls of peak_meter_peek don't | |
761 | #ifdef SIMULATOR | 730 | get fooled by an old maximum value */ |
762 | peak_meter_l = 8000; | 731 | pm_max_right = pm_cur_right; |
763 | #elif CONFIG_HWCODEC == MASNONE | ||
764 | pcm_calculate_peaks(NULL, &peak_meter_r); | ||
765 | #else | ||
766 | /* reset peak_meter_r so that subsequent calls of | ||
767 | peak_meter_peek doesn't get fooled by an old | ||
768 | maximum value */ | ||
769 | peak_meter_r = mas_codec_readreg(peak_meter_src_r); | ||
770 | #endif | ||
771 | return retval; | 732 | return retval; |
772 | } | 733 | } |
773 | 734 | ||
@@ -777,13 +738,14 @@ static int peak_meter_read_r (void) { | |||
777 | * @param int unused - This parameter was added to | 738 | * @param int unused - This parameter was added to |
778 | * make the function compatible with set_int | 739 | * make the function compatible with set_int |
779 | */ | 740 | */ |
780 | void peak_meter_set_clip_hold(int time) { | 741 | void peak_meter_set_clip_hold(int time) |
781 | peak_meter_clip_eternal = false; | 742 | { |
743 | pm_clip_eternal = false; | ||
782 | 744 | ||
783 | if (time <= 0) { | 745 | if (time <= 0) { |
784 | peak_meter_l_clip = false; | 746 | pm_clip_left = false; |
785 | peak_meter_r_clip = false; | 747 | pm_clip_right = false; |
786 | peak_meter_clip_eternal = true; | 748 | pm_clip_eternal = true; |
787 | } | 749 | } |
788 | } | 750 | } |
789 | 751 | ||
@@ -795,7 +757,8 @@ void peak_meter_set_clip_hold(int time) { | |||
795 | * @param int meterwidht - The widht of the meter in pixel | 757 | * @param int meterwidht - The widht of the meter in pixel |
796 | * @return unsigned short - A value 0 <= return value <= meterwidth | 758 | * @return unsigned short - A value 0 <= return value <= meterwidth |
797 | */ | 759 | */ |
798 | unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){ | 760 | unsigned short peak_meter_scale_value(unsigned short val, int meterwidth) |
761 | { | ||
799 | int retval; | 762 | int retval; |
800 | 763 | ||
801 | if (val <= peak_meter_range_min) { | 764 | if (val <= peak_meter_range_min) { |
@@ -809,10 +772,10 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){ | |||
809 | retval = val; | 772 | retval = val; |
810 | 773 | ||
811 | /* different scaling is used for dBfs and linear percent */ | 774 | /* different scaling is used for dBfs and linear percent */ |
812 | if (peak_meter_use_dbfs) { | 775 | if (pm_use_dbfs) { |
813 | 776 | ||
814 | /* scale the samples dBfs */ | 777 | /* scale the samples dBfs */ |
815 | retval = (calc_db(retval) - db_min) * meterwidth / db_range; | 778 | retval = (calc_db(retval) - pm_db_min) * meterwidth / pm_db_range; |
816 | } | 779 | } |
817 | 780 | ||
818 | /* Scale for linear percent display */ | 781 | /* Scale for linear percent display */ |
@@ -820,7 +783,7 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){ | |||
820 | { | 783 | { |
821 | /* scale the samples */ | 784 | /* scale the samples */ |
822 | retval = ((retval - peak_meter_range_min) * meterwidth) | 785 | retval = ((retval - peak_meter_range_min) * meterwidth) |
823 | / peak_meter_range; | 786 | / pm_range; |
824 | } | 787 | } |
825 | return retval; | 788 | return retval; |
826 | } | 789 | } |
@@ -854,8 +817,7 @@ void peak_meter_draw(int x, int y, int width, int height) | |||
854 | 817 | ||
855 | /* read the volume info from MAS */ | 818 | /* read the volume info from MAS */ |
856 | left = peak_meter_read_l(); | 819 | left = peak_meter_read_l(); |
857 | right = peak_meter_read_r(); | 820 | right = peak_meter_read_r(); |
858 | /*peak_meter_peek();*/ | ||
859 | 821 | ||
860 | /* scale the samples dBfs */ | 822 | /* scale the samples dBfs */ |
861 | left = peak_meter_scale_value(left, meterwidth); | 823 | left = peak_meter_scale_value(left, meterwidth); |
@@ -865,7 +827,7 @@ void peak_meter_draw(int x, int y, int width, int height) | |||
865 | (The scale becomes invalid when the range changed.) */ | 827 | (The scale becomes invalid when the range changed.) */ |
866 | if (!db_scale_valid){ | 828 | if (!db_scale_valid){ |
867 | 829 | ||
868 | if (peak_meter_use_dbfs) { | 830 | if (pm_use_dbfs) { |
869 | db_scale_count = DB_SCALE_SRC_VALUES_SIZE; | 831 | db_scale_count = DB_SCALE_SRC_VALUES_SIZE; |
870 | for (i = 0; i < db_scale_count; i++){ | 832 | for (i = 0; i < db_scale_count; i++){ |
871 | /* find the real x-coords for predefined interesting | 833 | /* find the real x-coords for predefined interesting |
@@ -884,7 +846,7 @@ void peak_meter_draw(int x, int y, int width, int height) | |||
884 | for (i = 0; i < db_scale_count; i++) { | 846 | for (i = 0; i < db_scale_count; i++) { |
885 | db_scale_lcd_coord[i] = | 847 | db_scale_lcd_coord[i] = |
886 | (i * (MAX_PEAK / 10) - peak_meter_range_min) * | 848 | (i * (MAX_PEAK / 10) - peak_meter_range_min) * |
887 | meterwidth / peak_meter_range; | 849 | meterwidth / pm_range; |
888 | } | 850 | } |
889 | } | 851 | } |
890 | 852 | ||
@@ -894,41 +856,41 @@ void peak_meter_draw(int x, int y, int width, int height) | |||
894 | } | 856 | } |
895 | 857 | ||
896 | /* apply release */ | 858 | /* apply release */ |
897 | left = MAX(left , last_left - peak_meter_release); | 859 | left = MAX(left , last_left - pm_peak_release); |
898 | right = MAX(right, last_right - peak_meter_release); | 860 | right = MAX(right, last_right - pm_peak_release); |
899 | 861 | ||
900 | /* reset max values after timeout */ | 862 | /* reset max values after timeout */ |
901 | if (TIME_AFTER(current_tick, peak_meter_timeout_l)){ | 863 | if (TIME_AFTER(current_tick, pm_peak_timeout_l)){ |
902 | peak_meter_max_l = 0; | 864 | pm_peak_left = 0; |
903 | } | 865 | } |
904 | 866 | ||
905 | if (TIME_AFTER(current_tick, peak_meter_timeout_r)){ | 867 | if (TIME_AFTER(current_tick, pm_peak_timeout_r)){ |
906 | peak_meter_max_r = 0; | 868 | pm_peak_right = 0; |
907 | } | 869 | } |
908 | 870 | ||
909 | if (!peak_meter_clip_eternal) { | 871 | if (!pm_clip_eternal) { |
910 | if (peak_meter_l_clip && | 872 | if (pm_clip_left && |
911 | TIME_AFTER(current_tick, peak_meter_clip_timeout_l)){ | 873 | TIME_AFTER(current_tick, pm_clip_timeout_l)){ |
912 | peak_meter_l_clip = false; | 874 | pm_clip_left = false; |
913 | } | 875 | } |
914 | 876 | ||
915 | if (peak_meter_r_clip && | 877 | if (pm_clip_right && |
916 | TIME_AFTER(current_tick, peak_meter_clip_timeout_r)){ | 878 | TIME_AFTER(current_tick, pm_clip_timeout_r)){ |
917 | peak_meter_r_clip = false; | 879 | pm_clip_right = false; |
918 | } | 880 | } |
919 | } | 881 | } |
920 | 882 | ||
921 | /* check for new max values */ | 883 | /* check for new max values */ |
922 | if (left > peak_meter_max_l) { | 884 | if (left > pm_peak_left) { |
923 | peak_meter_max_l = left - 1; | 885 | pm_peak_left = left - 1; |
924 | peak_meter_timeout_l = | 886 | pm_peak_timeout_l = |
925 | current_tick + max_time_out[peak_meter_hold]; | 887 | current_tick + peak_time_out[pm_peak_hold]; |
926 | } | 888 | } |
927 | 889 | ||
928 | if (right > peak_meter_max_r) { | 890 | if (right > pm_peak_right) { |
929 | peak_meter_max_r = right - 1; | 891 | pm_peak_right = right - 1; |
930 | peak_meter_timeout_r = | 892 | pm_peak_timeout_r = |
931 | current_tick + max_time_out[peak_meter_hold]; | 893 | current_tick + peak_time_out[pm_peak_hold]; |
932 | } | 894 | } |
933 | } | 895 | } |
934 | 896 | ||
@@ -939,19 +901,19 @@ void peak_meter_draw(int x, int y, int width, int height) | |||
939 | 901 | ||
940 | /* draw left */ | 902 | /* draw left */ |
941 | lcd_fillrect (x, y, left, height / 2 - 2 ); | 903 | lcd_fillrect (x, y, left, height / 2 - 2 ); |
942 | if (peak_meter_max_l > 0) { | 904 | if (pm_peak_left > 0) { |
943 | lcd_vline(x + peak_meter_max_l, y, y + height / 2 - 2 ); | 905 | lcd_vline(x + pm_peak_left, y, y + height / 2 - 2 ); |
944 | } | 906 | } |
945 | if (peak_meter_l_clip) { | 907 | if (pm_clip_left) { |
946 | lcd_fillrect(x + meterwidth, y, 3, height / 2 - 1); | 908 | lcd_fillrect(x + meterwidth, y, 3, height / 2 - 1); |
947 | } | 909 | } |
948 | 910 | ||
949 | /* draw right */ | 911 | /* draw right */ |
950 | lcd_fillrect(x, y + height / 2 + 1, right, height / 2 - 2); | 912 | lcd_fillrect(x, y + height / 2 + 1, right, height / 2 - 2); |
951 | if (peak_meter_max_r > 0) { | 913 | if (pm_peak_right > 0) { |
952 | lcd_vline( x + peak_meter_max_r, y + height / 2, y + height - 2); | 914 | lcd_vline( x + pm_peak_right, y + height / 2, y + height - 2); |
953 | } | 915 | } |
954 | if (peak_meter_r_clip) { | 916 | if (pm_clip_right) { |
955 | lcd_fillrect(x + meterwidth, y + height / 2, 3, height / 2 - 1); | 917 | lcd_fillrect(x + meterwidth, y + height / 2, 3, height / 2 - 1); |
956 | } | 918 | } |
957 | 919 | ||
@@ -1071,7 +1033,8 @@ void peak_meter_define_trigger( | |||
1071 | * Enables or disables the trigger. | 1033 | * Enables or disables the trigger. |
1072 | * @param on - If true the trigger is turned on. | 1034 | * @param on - If true the trigger is turned on. |
1073 | */ | 1035 | */ |
1074 | void peak_meter_trigger(bool on) { | 1036 | void peak_meter_trigger(bool on) |
1037 | { | ||
1075 | /* don't use set_trigger here as that would fire an undesired event */ | 1038 | /* don't use set_trigger here as that would fire an undesired event */ |
1076 | trig_status = on ? TRIG_READY : TRIG_OFF; | 1039 | trig_status = on ? TRIG_READY : TRIG_OFF; |
1077 | } | 1040 | } |
@@ -1081,7 +1044,8 @@ void peak_meter_trigger(bool on) { | |||
1081 | * @param listener - The function that is called with each change of | 1044 | * @param listener - The function that is called with each change of |
1082 | * trig_status. May be set to NULL if no callback is desired. | 1045 | * trig_status. May be set to NULL if no callback is desired. |
1083 | */ | 1046 | */ |
1084 | void peak_meter_set_trigger_listener(void (*listener)(int status)) { | 1047 | void peak_meter_set_trigger_listener(void (*listener)(int status)) |
1048 | { | ||
1085 | trigger_listener = listener; | 1049 | trigger_listener = listener; |
1086 | } | 1050 | } |
1087 | 1051 | ||
@@ -1097,78 +1061,99 @@ void peak_meter_set_trigger_listener(void (*listener)(int status)) { | |||
1097 | * peak_meter_release_trigger. To turn the trigger off call | 1061 | * peak_meter_release_trigger. To turn the trigger off call |
1098 | * peak_meter_trigger_off. | 1062 | * peak_meter_trigger_off. |
1099 | */ | 1063 | */ |
1100 | int peak_meter_trigger_status(void) { | 1064 | int peak_meter_trigger_status(void) |
1065 | { | ||
1101 | return trig_status; /* & TRIG_PIT_MASK;*/ | 1066 | return trig_status; /* & TRIG_PIT_MASK;*/ |
1102 | } | 1067 | } |
1103 | 1068 | ||
1104 | void peak_meter_draw_trig(int xpos, int ypos) { | 1069 | void peak_meter_draw_trig(int xpos, int ypos) |
1105 | int x = xpos + ICON_PLAY_STATE_WIDTH + 1; | 1070 | { |
1071 | int barstart, barend; | ||
1072 | int icon, ixpos; | ||
1106 | switch (trig_status) { | 1073 | switch (trig_status) { |
1107 | long time_left; | ||
1108 | 1074 | ||
1109 | case TRIG_READY: | 1075 | case TRIG_READY: |
1110 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | 1076 | barstart = 0; |
1111 | TRIGBAR_WIDTH, 0, 0, HORIZONTAL); | 1077 | barend = 0; |
1112 | lcd_mono_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos, | 1078 | icon = Icon_Stop; |
1113 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT); | 1079 | ixpos = xpos; |
1114 | break; | 1080 | break; |
1115 | 1081 | ||
1116 | case TRIG_STEADY: | 1082 | case TRIG_STEADY: |
1117 | case TRIG_RETRIG: | 1083 | case TRIG_RETRIG: |
1118 | time_left = trig_strt_duration - (current_tick - trig_hightime); | 1084 | barstart = 0; |
1119 | time_left = time_left * TRIGBAR_WIDTH / trig_strt_duration; | 1085 | barend = TRIGBAR_WIDTH * (current_tick - trig_hightime) |
1120 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | 1086 | / trig_strt_duration; |
1121 | TRIGBAR_WIDTH, 0, TRIGBAR_WIDTH - time_left, HORIZONTAL); | 1087 | icon = Icon_Stop; |
1122 | lcd_mono_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos, | 1088 | ixpos = xpos; |
1123 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT); | ||
1124 | break; | 1089 | break; |
1125 | 1090 | ||
1126 | case TRIG_GO: | 1091 | case TRIG_GO: |
1127 | case TRIG_CONTINUE: | 1092 | case TRIG_CONTINUE: |
1128 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | 1093 | barstart = TRIGBAR_WIDTH; |
1129 | TRIGBAR_WIDTH, TRIGBAR_WIDTH, TRIGBAR_WIDTH, HORIZONTAL); | 1094 | barend = TRIGBAR_WIDTH; |
1130 | lcd_mono_bitmap(bitmap_icons_7x8[Icon_Record], | 1095 | icon = Icon_Record; |
1131 | TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos, | 1096 | ixpos = TRIG_WIDTH - ICON_PLAY_STATE_WIDTH; |
1132 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT); | ||
1133 | break; | 1097 | break; |
1134 | 1098 | ||
1135 | case TRIG_POSTREC: | 1099 | case TRIG_POSTREC: |
1136 | time_left = trig_stp_hold - (current_tick - trig_lowtime); | 1100 | barstart = TRIGBAR_WIDTH |
1137 | time_left = time_left * TRIGBAR_WIDTH / trig_stp_hold; | 1101 | - TRIGBAR_WIDTH * (current_tick - trig_lowtime) |
1138 | scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | 1102 | / trig_stp_hold; |
1139 | TRIGBAR_WIDTH, time_left, TRIGBAR_WIDTH, HORIZONTAL); | 1103 | barend = TRIGBAR_WIDTH; |
1140 | lcd_mono_bitmap(bitmap_icons_7x8[Icon_Record], | 1104 | icon = Icon_Record; |
1141 | TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos, | 1105 | ixpos = TRIG_WIDTH - ICON_PLAY_STATE_WIDTH; |
1142 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT); | ||
1143 | break; | 1106 | break; |
1144 | } | ||
1145 | 1107 | ||
1108 | default: | ||
1109 | return; | ||
1110 | } | ||
1111 | scrollbar(xpos + ICON_PLAY_STATE_WIDTH + 1, ypos + 1, | ||
1112 | TRIGBAR_WIDTH, TRIG_HEIGHT - 2, | ||
1113 | TRIGBAR_WIDTH, barstart, barend, HORIZONTAL); | ||
1114 | lcd_mono_bitmap(bitmap_icons_7x8[icon], ixpos, ypos, | ||
1115 | ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT); | ||
1146 | } | 1116 | } |
1147 | #endif | 1117 | #endif |
1148 | 1118 | ||
1149 | int peak_meter_draw_get_btn(int x, int y, int width, int height) | 1119 | int peak_meter_draw_get_btn(int x, int y, int width, int height) |
1150 | { | 1120 | { |
1151 | int button; | 1121 | int button = BUTTON_NONE; |
1152 | long next_refresh = current_tick; | 1122 | long next_refresh = current_tick; |
1153 | long next_big_refresh = current_tick + HZ / 10; | 1123 | long next_big_refresh = current_tick + HZ / 10; |
1154 | button = BUTTON_NONE; | 1124 | #ifndef SIMULATOR |
1125 | bool highperf = !ata_disk_is_active(); | ||
1126 | #else | ||
1127 | bool highperf = false; | ||
1128 | #endif | ||
1129 | bool dopeek = true; | ||
1155 | 1130 | ||
1156 | while (!TIME_AFTER(current_tick, next_big_refresh)) { | 1131 | while (TIME_BEFORE(current_tick, next_big_refresh)) { |
1157 | button = button_get(false); | 1132 | button = button_get(false); |
1158 | if (button != BUTTON_NONE) { | 1133 | if (button != BUTTON_NONE) { |
1159 | break; | 1134 | break; |
1160 | } | 1135 | } |
1161 | sleep(MAX(next_refresh - current_tick, 0) - 1); | 1136 | if (dopeek) { /* Peek only once per refresh when disk is */ |
1162 | next_refresh = current_tick + HZ / peak_meter_fps; | 1137 | peak_meter_peek(); /* spinning, but as often as possible */ |
1163 | peak_meter_peek(); | 1138 | dopeek = highperf; /* otherwise. */ |
1164 | peak_meter_draw(x, y, width, height); | 1139 | yield(); |
1165 | lcd_update_rect(x, y, width, height); | 1140 | } else { |
1141 | sleep(0); /* Sleep until end of current tick. */ | ||
1142 | } | ||
1143 | if (TIME_AFTER(current_tick, next_refresh)) { | ||
1144 | peak_meter_draw(x, y, width, height); | ||
1145 | lcd_update_rect(x, y, width, height); | ||
1146 | next_refresh += HZ / PEAK_METER_FPS; | ||
1147 | dopeek = true; | ||
1148 | } | ||
1166 | } | 1149 | } |
1150 | |||
1167 | return button; | 1151 | return button; |
1168 | } | 1152 | } |
1169 | 1153 | ||
1170 | #ifdef PM_DEBUG | 1154 | #ifdef PM_DEBUG |
1171 | static void peak_meter_clear_histogram(void) { | 1155 | static void peak_meter_clear_histogram(void) |
1156 | { | ||
1172 | int i = 0; | 1157 | int i = 0; |
1173 | for (i = 0; i < TICKS_PER_DRAW_SIZE; i++) { | 1158 | for (i = 0; i < TICKS_PER_DRAW_SIZE; i++) { |
1174 | ticks_per_redraw[i] = (unsigned int)0; | 1159 | ticks_per_redraw[i] = (unsigned int)0; |
@@ -1179,7 +1164,8 @@ static void peak_meter_clear_histogram(void) { | |||
1179 | } | 1164 | } |
1180 | } | 1165 | } |
1181 | 1166 | ||
1182 | bool peak_meter_histogram(void) { | 1167 | bool peak_meter_histogram(void) |
1168 | { | ||
1183 | int i; | 1169 | int i; |
1184 | int btn = BUTTON_NONE; | 1170 | int btn = BUTTON_NONE; |
1185 | while ((btn & BUTTON_OFF) != BUTTON_OFF ) | 1171 | while ((btn & BUTTON_OFF) != BUTTON_OFF ) |
@@ -1210,7 +1196,7 @@ bool peak_meter_histogram(void) { | |||
1210 | lcd_hline(0, x, y + i); | 1196 | lcd_hline(0, x, y + i); |
1211 | } | 1197 | } |
1212 | lcd_update(); | 1198 | lcd_update(); |
1213 | 1199 | ||
1214 | btn = button_get(true); | 1200 | btn = button_get(true); |
1215 | if (btn == BUTTON_PLAY) { | 1201 | if (btn == BUTTON_PLAY) { |
1216 | peak_meter_clear_histogram(); | 1202 | peak_meter_clear_histogram(); |