summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-08-29 20:07:17 +0000
committerJens Arnold <amiconn@rockbox.org>2005-08-29 20:07:17 +0000
commit99a0598c284471342fcda1fdcba90d4b666bfbb3 (patch)
tree83cc502095e87277de770456498d2de6cf8f473b /apps/recorder
parent89a8ca4408c3ea34464898b0ce52a0d8351fa323 (diff)
downloadrockbox-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')
-rw-r--r--apps/recorder/peakmeter.c524
-rw-r--r--apps/recorder/peakmeter.h7
-rw-r--r--apps/recorder/radio.c7
3 files changed, 261 insertions, 277 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 42static int pm_src_left = MAS_REG_DQPEAK_L;
43static 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 */
45static int peak_meter_max_l; 47static int pm_cur_left; /* current values (last peak_meter_peek) */
46static int peak_meter_max_r; 48static int pm_cur_right;
47 49static int pm_max_left; /* maximum values between peak meter draws */
48/* point in time when peak_meter_max_x becomes invalid */ 50static int pm_max_right;
49static long peak_meter_timeout_l; 51
50static long peak_meter_timeout_r; 52/* Peak hold */
51 53static int pm_peak_left; /* buffered peak values */
52/* when true a clip has occurred */ 54static int pm_peak_right;
53static bool peak_meter_l_clip = false; 55static long pm_peak_timeout_l; /* peak hold timeouts */
54static bool peak_meter_r_clip = false; 56static long pm_peak_timeout_r;
55 57
56/* point in time when peak_meter_x_oveflow becomes invalid */ 58/* Clip hold */
57static long peak_meter_clip_timeout_l; 59static bool pm_clip_left = false; /* when true a clip has occurred */
58static long peak_meter_clip_timeout_r; 60static bool pm_clip_right = false;
59 61static long pm_clip_timeout_l; /* clip hold timeouts */
60static int peak_meter_clip_hold; 62static 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
63unsigned short peak_meter_range_min; 65 applications to detect if the peak_meter is in use and needs drawing at all */
64unsigned short peak_meter_range_max; 66bool peak_meter_enabled = true;
65static unsigned short peak_meter_range;
66
67/* if set to true clip timeout is disabled */
68static bool peak_meter_clip_eternal = false;
69 67
70static bool peak_meter_use_dbfs = true; 68/** Parameters **/
71static unsigned short db_min = 0; 69/* Range */
72static unsigned short db_max = 9000; 70unsigned short peak_meter_range_min; /* minimum of range in samples */
73static unsigned short db_range = 9000; 71unsigned short peak_meter_range_max; /* maximum of range in samples */
72static unsigned short pm_range; /* range width in samples */
73static bool pm_use_dbfs = true; /* true if peakmeter displays dBfs */
74static unsigned short pm_db_min = 0; /* minimum of range in 1/100 dB */
75static unsigned short pm_db_max = 9000; /* maximum of range in 1/100 dB */
76static unsigned short pm_db_range = 9000; /* range width in 1/100 dB */
77/* Timing behaviour */
78static int pm_peak_hold = 1; /* peak hold timeout index */
79static int pm_peak_release = 8; /* peak release in units per read */
80static int pm_clip_hold = 16; /* clip hold timeout index */
81static bool pm_clip_eternal = false; /* true if clip timeout is disabled */
74 82
75#ifdef HAVE_RECORDING 83#ifdef HAVE_RECORDING
76static unsigned short trig_strt_threshold; 84static unsigned short trig_strt_threshold;
@@ -92,34 +100,6 @@ static int trig_status = TRIG_OFF;
92static void (*trigger_listener)(int) = NULL; 100static 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
101static int peak_meter_src_l = MAS_REG_DQPEAK_L;
102static 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 */
108bool peak_meter_enabled = true;
109
110/*
111bool peak_meter_use_thread = false;
112static char peak_meter_stack[DEFAULT_STACK_SIZE];
113*/
114/* used in wps.c to set the display frame rate of the peak meter */
115int peak_meter_fps = 20;
116
117static int peak_meter_l;
118static int peak_meter_r;
119
120static int peak_meter_hold = 1;
121static int peak_meter_release = 8;
122
123/* debug only */ 103/* debug only */
124#ifdef PM_DEBUG 104#ifdef PM_DEBUG
125static int peek_calls = 0; 105static 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 */
135static const long max_time_out[] = { 115static 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
154static 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
169static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = { 133static 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
185static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE; 148static 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 */
189static bool db_scale_valid = false; 152static 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
214int calc_db (int isample) { 177int 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 */
315static int db_to_sample_bin_search(int min, int max, int db){ 279static 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 */
342int peak_meter_db2sample(int db) { 307int 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 */
379void peak_meter_set_min(int newmin) { 345void 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 */
403int peak_meter_get_min(void) { 370int 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 */
420void peak_meter_set_max(int newmax) { 388void 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 */
443int peak_meter_get_max(void) { 412int 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 */
459int peak_meter_get_use_dbfs(void) { 428bool 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 */
469void peak_meter_set_use_dbfs(int use){ 439void 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 */
487void peak_meter_init_range( bool dbfs, int range_min, int range_max) 458void 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 */
505void peak_meter_init_times(int release, int hold, int clip_hold) { 476void 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
536static void set_trig_status(int new_state) { 508static 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 */
553inline void peak_meter_peek(void) 526void 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 */
723static int peak_meter_read_l (void) 699static 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 */
752static int peak_meter_read_r (void) { 720static 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 */
780void peak_meter_set_clip_hold(int time) { 741void 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 */
798unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){ 760unsigned 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 */
1074void peak_meter_trigger(bool on) { 1036void 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 */
1084void peak_meter_set_trigger_listener(void (*listener)(int status)) { 1047void 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 */
1100int peak_meter_trigger_status(void) { 1064int peak_meter_trigger_status(void)
1065{
1101 return trig_status; /* & TRIG_PIT_MASK;*/ 1066 return trig_status; /* & TRIG_PIT_MASK;*/
1102} 1067}
1103 1068
1104void peak_meter_draw_trig(int xpos, int ypos) { 1069void 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
1149int peak_meter_draw_get_btn(int x, int y, int width, int height) 1119int 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
1171static void peak_meter_clear_histogram(void) { 1155static 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
1182bool peak_meter_histogram(void) { 1167bool 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();
diff --git a/apps/recorder/peakmeter.h b/apps/recorder/peakmeter.h
index 3c0a28bf3b..5513dfacf1 100644
--- a/apps/recorder/peakmeter.h
+++ b/apps/recorder/peakmeter.h
@@ -19,13 +19,14 @@
19#ifndef __PEAKMETER_H__ 19#ifndef __PEAKMETER_H__
20#define __PEAKMETER_H__ 20#define __PEAKMETER_H__
21 21
22#define PEAK_METER_FPS 20
23
22/*#define PM_DEBUG */ 24/*#define PM_DEBUG */
23#ifdef PM_DEBUG 25#ifdef PM_DEBUG
24extern bool peak_meter_histogram(void); 26extern bool peak_meter_histogram(void);
25#endif 27#endif
26 28
27extern bool peak_meter_enabled; 29extern bool peak_meter_enabled;
28extern int peak_meter_fps;
29 30
30extern void peak_meter_playback(bool playback); 31extern void peak_meter_playback(bool playback);
31extern void peak_meter_draw(int x, int y, int width, int height); 32extern void peak_meter_draw(int x, int y, int width, int height);
@@ -39,8 +40,8 @@ extern void peak_meter_set_min(int newmin);
39extern int peak_meter_get_min(void); 40extern int peak_meter_get_min(void);
40extern void peak_meter_set_max(int newmax); 41extern void peak_meter_set_max(int newmax);
41extern int peak_meter_get_max(void); 42extern int peak_meter_get_max(void);
42extern void peak_meter_set_use_dbfs(int use); 43extern void peak_meter_set_use_dbfs(bool use);
43extern int peak_meter_get_use_dbfs(void); 44extern bool peak_meter_get_use_dbfs(void);
44extern int calc_db (int isample); 45extern int calc_db (int isample);
45extern int peak_meter_db2sample(int db); 46extern int peak_meter_db2sample(int db);
46extern unsigned short peak_meter_scale_value(unsigned short val, int meterwidth); 47extern unsigned short peak_meter_scale_value(unsigned short val, int meterwidth);
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 4e6c52ea84..a0280ecf1f 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -304,7 +304,7 @@ bool radio_screen(void)
304 if(search_dir) 304 if(search_dir)
305 button = button_get(false); 305 button = button_get(false);
306 else 306 else
307 button = button_get_w_tmo(HZ / peak_meter_fps); 307 button = button_get_w_tmo(HZ / PEAK_METER_FPS);
308 switch(button) 308 switch(button)
309 { 309 {
310 case FM_STOP: 310 case FM_STOP:
@@ -479,13 +479,10 @@ bool radio_screen(void)
479 /* Only display the peak meter when not recording */ 479 /* Only display the peak meter when not recording */
480 if(!audio_status()) 480 if(!audio_status())
481 { 481 {
482 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
483 lcd_fillrect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
484 lcd_set_drawmode(DRMODE_SOLID);
485 peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh); 482 peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
486 lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh); 483 lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
487 } 484 }
488 485
489 if(TIME_AFTER(current_tick, timeout)) 486 if(TIME_AFTER(current_tick, timeout))
490 { 487 {
491 timeout = current_tick + HZ; 488 timeout = current_tick + HZ;