summaryrefslogtreecommitdiffstats
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 @@
#include "thread.h"
#include "kernel.h"
#include "settings.h"
+#include "ata.h"
#include "lcd.h"
#include "widgets.h"
#include "wps-display.h"
@@ -36,41 +37,48 @@
#include "pcm_playback.h"
#endif
-/* no inline in simulator mode */
-#ifdef SIMULATOR
-#define inline
+#if !defined(SIMULATOR) && CONFIG_HWCODEC != MASNONE
+/* Data source */
+static int pm_src_left = MAS_REG_DQPEAK_L;
+static int pm_src_right = MAS_REG_DQPEAK_R;
#endif
-/* buffer the read peak value */
-static int peak_meter_max_l;
-static int peak_meter_max_r;
-
-/* point in time when peak_meter_max_x becomes invalid */
-static long peak_meter_timeout_l;
-static long peak_meter_timeout_r;
-
-/* when true a clip has occurred */
-static bool peak_meter_l_clip = false;
-static bool peak_meter_r_clip = false;
-
-/* point in time when peak_meter_x_oveflow becomes invalid */
-static long peak_meter_clip_timeout_l;
-static long peak_meter_clip_timeout_r;
-
-static int peak_meter_clip_hold;
-
-/* specifies the value range in peak volume values */
-unsigned short peak_meter_range_min;
-unsigned short peak_meter_range_max;
-static unsigned short peak_meter_range;
-
-/* if set to true clip timeout is disabled */
-static bool peak_meter_clip_eternal = false;
+/* Current values and cumulation */
+static int pm_cur_left; /* current values (last peak_meter_peek) */
+static int pm_cur_right;
+static int pm_max_left; /* maximum values between peak meter draws */
+static int pm_max_right;
+
+/* Peak hold */
+static int pm_peak_left; /* buffered peak values */
+static int pm_peak_right;
+static long pm_peak_timeout_l; /* peak hold timeouts */
+static long pm_peak_timeout_r;
+
+/* Clip hold */
+static bool pm_clip_left = false; /* when true a clip has occurred */
+static bool pm_clip_right = false;
+static long pm_clip_timeout_l; /* clip hold timeouts */
+static long pm_clip_timeout_r;
+
+/* Temporarily en- / disables peak meter. This is especially for external
+ applications to detect if the peak_meter is in use and needs drawing at all */
+bool peak_meter_enabled = true;
-static bool peak_meter_use_dbfs = true;
-static unsigned short db_min = 0;
-static unsigned short db_max = 9000;
-static unsigned short db_range = 9000;
+/** Parameters **/
+/* Range */
+unsigned short peak_meter_range_min; /* minimum of range in samples */
+unsigned short peak_meter_range_max; /* maximum of range in samples */
+static unsigned short pm_range; /* range width in samples */
+static bool pm_use_dbfs = true; /* true if peakmeter displays dBfs */
+static unsigned short pm_db_min = 0; /* minimum of range in 1/100 dB */
+static unsigned short pm_db_max = 9000; /* maximum of range in 1/100 dB */
+static unsigned short pm_db_range = 9000; /* range width in 1/100 dB */
+/* Timing behaviour */
+static int pm_peak_hold = 1; /* peak hold timeout index */
+static int pm_peak_release = 8; /* peak release in units per read */
+static int pm_clip_hold = 16; /* clip hold timeout index */
+static bool pm_clip_eternal = false; /* true if clip timeout is disabled */
#ifdef HAVE_RECORDING
static unsigned short trig_strt_threshold;
@@ -92,34 +100,6 @@ static int trig_status = TRIG_OFF;
static void (*trigger_listener)(int) = NULL;
#endif
-#if CONFIG_HWCODEC == MASNONE
-#define MAS_REG_DQPEAK_L 0
-#define MAS_REG_DQPEAK_R 0
-#endif
-
-#if !defined(SIMULATOR) && CONFIG_HWCODEC != MASNONE
-static int peak_meter_src_l = MAS_REG_DQPEAK_L;
-static int peak_meter_src_r = MAS_REG_DQPEAK_R;
-#endif
-
-/* temporarily en- / disables peak meter. This is
- especially for external applications to detect
- if the peak_meter is in use and needs drawing at all */
-bool peak_meter_enabled = true;
-
-/*
-bool peak_meter_use_thread = false;
-static char peak_meter_stack[DEFAULT_STACK_SIZE];
-*/
-/* used in wps.c to set the display frame rate of the peak meter */
-int peak_meter_fps = 20;
-
-static int peak_meter_l;
-static int peak_meter_r;
-
-static int peak_meter_hold = 1;
-static int peak_meter_release = 8;
-
/* debug only */
#ifdef PM_DEBUG
static int peek_calls = 0;
@@ -132,7 +112,7 @@ static unsigned int ticks_per_redraw[TICKS_PER_DRAW_SIZE];
#endif
/* time out values for max */
-static const long max_time_out[] = {
+static const short peak_time_out[] = {
0 * HZ, HZ / 5, 30, HZ / 2, HZ, 2 * HZ,
3 * HZ, 4 * HZ, 5 * HZ, 6 * HZ, 7 * HZ, 8 * HZ,
9 * HZ, 10 * HZ, 15 * HZ, 20 * HZ, 30 * HZ, 60 * HZ
@@ -150,22 +130,6 @@ static const long clip_time_out[] = {
/* precalculated peak values that represent magical
dBfs values. Used to draw the scale */
#define DB_SCALE_SRC_VALUES_SIZE 12
-#if 0
-static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
- 32767, /* 0 db */
- 23197, /* - 3 db */
- 16422, /* - 6 db */
- 11626, /* - 9 db */
- 8231, /* -12 db */
- 4125, /* -18 db */
- 2067, /* -24 db */
- 1036, /* -30 db */
- 328, /* -40 db */
- 104, /* -50 db */
- 33, /* -60 db */
- 1, /* -inf */
-};
-#else
static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
32752, /* 0 db */
22784, /* - 3 db */
@@ -180,11 +144,10 @@ static const int db_scale_src_values[DB_SCALE_SRC_VALUES_SIZE] = {
33, /* -60 db */
0, /* -inf */
};
-#endif
static int db_scale_count = DB_SCALE_SRC_VALUES_SIZE;
-/* if db_scale_valid is false the content of
+/* if db_scale_valid is false the content of
db_scale_lcd_coord needs recalculation */
static bool db_scale_valid = false;
@@ -211,7 +174,8 @@ static int db_scale_lcd_coord[sizeof db_scale_src_values / sizeof (int)];
* for-loops.
*/
-int calc_db (int isample) {
+int calc_db (int isample)
+{
/* return n+m*(isample-istart)/100 */
int n;
long m;
@@ -312,7 +276,8 @@ int calc_db (int isample) {
* minimal peak sample is searched.
* @return int - A linear volume value with 0 <= value < MAX_PEAK
*/
-static int db_to_sample_bin_search(int min, int max, int db){
+static int db_to_sample_bin_search(int min, int max, int db)
+{
int test = min + (max - min) / 2;
if (min < max) {
@@ -339,7 +304,8 @@ static int db_to_sample_bin_search(int min, int max, int db){
* @return int - The return value is in the range of
* 0 <= return value < MAX_PEAK
*/
-int peak_meter_db2sample(int db) {
+int peak_meter_db2sample(int db)
+{
int retval = 0;
/* what is the maximum pseudo db value */
@@ -371,13 +337,14 @@ int peak_meter_db2sample(int db) {
/**
* Set the min value for restriction of the value range.
- * @param int newmin - depending wether dBfs is used
+ * @param int newmin - depending whether dBfs is used
* newmin is a value in dBfs * 100 or in linear percent values.
* for dBfs: -9000 < newmin <= 0
* for linear: 0 <= newmin <= 100
*/
-void peak_meter_set_min(int newmin) {
- if (peak_meter_use_dbfs) {
+void peak_meter_set_min(int newmin)
+{
+ if (pm_use_dbfs) {
peak_meter_range_min = peak_meter_db2sample(newmin);
} else {
@@ -386,10 +353,10 @@ void peak_meter_set_min(int newmin) {
}
}
- peak_meter_range = peak_meter_range_max - peak_meter_range_min;
+ pm_range = peak_meter_range_max - peak_meter_range_min;
- db_min = calc_db(peak_meter_range_min);
- db_range = db_max - db_min;
+ pm_db_min = calc_db(peak_meter_range_min);
+ pm_db_range = pm_db_max - pm_db_min;
db_scale_valid = false;
}
@@ -400,9 +367,10 @@ void peak_meter_set_min(int newmin) {
* @return: using dBfs : -9000 < value <= 0
* using linear scale: 0 <= value <= 100
*/
-int peak_meter_get_min(void) {
+int peak_meter_get_min(void)
+{
int retval = 0;
- if (peak_meter_use_dbfs) {
+ if (pm_use_dbfs) {
retval = calc_db(peak_meter_range_min) - calc_db(MAX_PEAK - 1);
} else {
retval = peak_meter_range_min * 100 / MAX_PEAK;
@@ -417,8 +385,9 @@ int peak_meter_get_min(void) {
* for dBfs: -9000 < newmax <= 0
* for linear: 0 <= newmax <= 100
*/
-void peak_meter_set_max(int newmax) {
- if (peak_meter_use_dbfs) {
+void peak_meter_set_max(int newmax)
+{
+ if (pm_use_dbfs) {
peak_meter_range_max = peak_meter_db2sample(newmax);
} else {
if (newmax > peak_meter_range_min) {
@@ -426,10 +395,10 @@ void peak_meter_set_max(int newmax) {
}
}
- peak_meter_range = peak_meter_range_max - peak_meter_range_min;
+ pm_range = peak_meter_range_max - peak_meter_range_min;
- db_max = calc_db(peak_meter_range_max);
- db_range = db_max - db_min;
+ pm_db_max = calc_db(peak_meter_range_max);
+ pm_db_range = pm_db_max - pm_db_min;
db_scale_valid = false;
}
@@ -440,9 +409,10 @@ void peak_meter_set_max(int newmax) {
* @return: using dBfs : -9000 < value <= 0
* using linear scale: 0 <= value <= 100
*/
-int peak_meter_get_max(void) {
+int peak_meter_get_max(void)
+{
int retval = 0;
- if (peak_meter_use_dbfs) {
+ if (pm_use_dbfs) {
retval = calc_db(peak_meter_range_max) - calc_db(MAX_PEAK - 1);
} else {
retval = peak_meter_range_max * 100 / MAX_PEAK;
@@ -451,23 +421,24 @@ int peak_meter_get_max(void) {
}
/**
- * Returns 1 if the meter currently is
- * displaying dBfs values, 0 if the meter
- * displays percent values.
- * @return int - returns 0 or 1.
+ * Returns whether the meter is currently displaying dBfs or percent values.
+ * @return bool - true if the meter is displaying dBfs
+ false if the meter is displaying percent values.
*/
-int peak_meter_get_use_dbfs(void) {
- return peak_meter_use_dbfs ? 1 : 0;
+bool peak_meter_get_use_dbfs(void)
+{
+ return pm_use_dbfs;
}
/**
- * Specifies wether the values displayed are scaled
+ * Specifies whether the values displayed are scaled
* as dBfs or as linear percent values.
- * @param int - Set to 0 for linear percent scale. Any other value
- * switches on dBfs.
+ * @param use - set to true for dBfs,
+ * set to false for linear scaling in percent
*/
-void peak_meter_set_use_dbfs(int use){
- peak_meter_use_dbfs = ((use & 1) == 1);
+void peak_meter_set_use_dbfs(bool use)
+{
+ pm_use_dbfs = use;
db_scale_valid = false;
}
@@ -486,7 +457,7 @@ void peak_meter_set_use_dbfs(int use){
*/
void peak_meter_init_range( bool dbfs, int range_min, int range_max)
{
- peak_meter_use_dbfs = dbfs;
+ pm_use_dbfs = dbfs;
peak_meter_set_min(range_min);
peak_meter_set_max(range_max);
}
@@ -497,15 +468,16 @@ void peak_meter_init_range( bool dbfs, int range_min, int range_max)
* to decrease with each redraw
* @param int hold - Select the time preset for the time the peak indicator
* is reset after a peak occurred. The preset values are
- * stored in max_time_out.
+ * stored in peak_time_out.
* @param int clip_hold - Select the time preset for the time the peak
* indicator is reset after a peak occurred. The preset
* values are stored in clip_time_out.
*/
-void peak_meter_init_times(int release, int hold, int clip_hold) {
- peak_meter_hold = hold;
- peak_meter_release = release;
- peak_meter_clip_hold = clip_hold;
+void peak_meter_init_times(int release, int hold, int clip_hold)
+{
+ pm_peak_hold = hold;
+ pm_peak_release = release;
+ pm_clip_hold = clip_hold;
}
/**
@@ -523,17 +495,18 @@ void peak_meter_playback(bool playback)
(void)playback;
#else
if (playback) {
- peak_meter_src_l = MAS_REG_DQPEAK_L;
- peak_meter_src_r = MAS_REG_DQPEAK_R;
+ pm_src_left = MAS_REG_DQPEAK_L;
+ pm_src_right = MAS_REG_DQPEAK_R;
} else {
- peak_meter_src_l = MAS_REG_QPEAK_L;
- peak_meter_src_r = MAS_REG_QPEAK_R;
+ pm_src_left = MAS_REG_QPEAK_L;
+ pm_src_right = MAS_REG_QPEAK_R;
}
#endif
}
#ifdef HAVE_RECORDING
-static void set_trig_status(int new_state) {
+static void set_trig_status(int new_state)
+{
if (trig_status != new_state) {
trig_status = new_state;
if (trigger_listener != NULL) {
@@ -545,24 +518,25 @@ static void set_trig_status(int new_state) {
/**
* Reads peak values from the MAS, and detects clips. The
- * values are stored in peak_meter_l peak_meter_r for later
+ * values are stored in pm_max_left pm_max_right for later
* evauluation. Consecutive calls to peak_meter_peek detect
* that ocurred. This function could be used by a thread for
* busy reading the MAS.
*/
-inline void peak_meter_peek(void)
+void peak_meter_peek(void)
{
+ int left, right;
+ /* read current values */
#ifdef SIMULATOR
- int left = 8000;
- int right = 9000;
+ pm_cur_left = left = 8000;
+ pm_cur_right = right = 9000;
#elif CONFIG_HWCODEC == MASNONE
- int left;
- int right;
- pcm_calculate_peaks(&left, &right);
+ pcm_calculate_peaks(&pm_cur_left, &pm_cur_right);
+ left = pm_cur_left;
+ right = pm_cur_right;
#else
- /* read the peak values */
- int left = mas_codec_readreg(peak_meter_src_l);
- int right = mas_codec_readreg(peak_meter_src_r);
+ pm_cur_left = left = mas_codec_readreg(pm_src_left);
+ pm_cur_right = right = mas_codec_readreg(pm_src_right);
#endif
/* check for clips
@@ -571,26 +545,34 @@ inline void peak_meter_peek(void)
to be inaccurate in both ways: it may detect clips
when no clip occurred and it may fail to detect
a real clip. */
- if ((left == peak_meter_l) &&
- (left == MAX_PEAK - 1)) {
- peak_meter_l_clip = true;
- peak_meter_clip_timeout_l =
- current_tick + clip_time_out[peak_meter_clip_hold];
+ if ((left == pm_max_left) &&
+ (left == MAX_PEAK - 1)) {
+ pm_clip_left = true;
+ pm_clip_timeout_l =
+ current_tick + clip_time_out[pm_clip_hold];
}
- if ((right == peak_meter_r) &&
+ if ((right == pm_max_right) &&
(right == MAX_PEAK - 1)) {
- peak_meter_r_clip = true;
- peak_meter_clip_timeout_r =
- current_tick + clip_time_out[peak_meter_clip_hold];
+ pm_clip_right = true;
+ pm_clip_timeout_r =
+ current_tick + clip_time_out[pm_clip_hold];
}
+ /* peaks are searched -> we have to find the maximum. When
+ many calls of peak_meter_peek the maximum value will be
+ stored in pm_max_xxx. This maximum is reset by the
+ functions peak_meter_read_x. */
+ pm_max_left = MAX(pm_max_left, left);
+ pm_max_right = MAX(pm_max_right, right);
+
#ifdef HAVE_RECORDING
switch (trig_status) {
case TRIG_READY:
/* no more changes, if trigger was activated as release trigger */
/* threshold exceeded? */
- if ((left > trig_strt_threshold) || (right > trig_strt_threshold)) {
+ if ((left > trig_strt_threshold)
+ || (right > trig_strt_threshold)) {
if (trig_strt_duration) {
/* reset trigger duration */
trig_hightime = current_tick;
@@ -614,8 +596,8 @@ inline void peak_meter_peek(void)
set_trig_status(TRIG_GO);
} else {
/* threshold exceeded? */
- if ((left > trig_strt_threshold) ||
- (right > trig_strt_threshold)) {
+ if ((left > trig_strt_threshold)
+ || (right > trig_strt_threshold)) {
/* reset lowtime */
trig_lowtime = current_tick;
}
@@ -640,7 +622,8 @@ inline void peak_meter_peek(void)
case TRIG_GO:
case TRIG_CONTINUE:
/* threshold exceeded? */
- if ((left > trig_stp_threshold) || (right > trig_stp_threshold)) {
+ if ((left > trig_stp_threshold)
+ || (right > trig_stp_threshold)) {
/* restart hold time countdown */
trig_lowtime = current_tick;
} else {
@@ -653,8 +636,8 @@ inline void peak_meter_peek(void)
/* gap time expired? */
if (current_tick - trig_lowtime > trig_rstrt_gap){
/* start threshold exceeded? */
- if ((left > trig_strt_threshold) ||
- (right > trig_strt_threshold)) {
+ if ((left > trig_strt_threshold)
+ || (right > trig_strt_threshold)) {
set_trig_status(TRIG_RETRIG);
trig_hightime = current_tick;
@@ -662,8 +645,8 @@ inline void peak_meter_peek(void)
else
/* stop threshold exceeded */
- if ((left > trig_stp_threshold) ||
- (right > trig_stp_threshold)) {
+ if ((left > trig_stp_threshold)
+ || (right > trig_stp_threshold)) {
if (current_tick - trig_hightime > trig_stp_hold){
trig_lowtime = current_tick;
set_trig_status(TRIG_CONTINUE);
@@ -685,8 +668,8 @@ inline void peak_meter_peek(void)
/* still within the gap time */
else {
/* stop threshold exceeded */
- if ((left > trig_stp_threshold) ||
- (right > trig_stp_threshold)) {
+ if ((left > trig_stp_threshold)
+ || (right > trig_stp_threshold)) {
set_trig_status(TRIG_CONTINUE);
trig_lowtime = current_tick;
}
@@ -702,13 +685,6 @@ inline void peak_meter_peek(void)
}
#endif
- /* peaks are searched -> we have to find the maximum. When
- many calls of peak_meter_peek the maximum value will be
- stored in peak_meter_x. This maximum is reset by the
- functions peak_meter_read_x. */
- peak_meter_l = MAX(peak_meter_l, left);
- peak_meter_r = MAX(peak_meter_r, right);
-
#ifdef PM_DEBUG
peek_calls++;
#endif
@@ -720,26 +696,18 @@ inline void peak_meter_peek(void)
* since the last call of peak_meter_read_l. The value
* is in the range 0 <= value < MAX_PEAK.
*/
-static int peak_meter_read_l (void)
+static int peak_meter_read_l(void)
{
- /* peak_meter_l contains the maximum of
- all peak values that were read by peak_meter_peek
- since the last call of peak_meter_read_r */
- int retval = peak_meter_l;
+ /* pm_max_left contains the maximum of all peak values that were read
+ by peak_meter_peek since the last call of peak_meter_read_l */
+ int retval = pm_max_left;
+
#ifdef PM_DEBUG
peek_calls = 0;
#endif
-
-#ifdef SIMULATOR
- peak_meter_l = 8000;
-#elif CONFIG_HWCODEC == MASNONE
- pcm_calculate_peaks(&peak_meter_l, NULL);
-#else
- /* reset peak_meter_l so that subsequent calls of
- peak_meter_peek doesn't get fooled by an old
- maximum value */
- peak_meter_l = mas_codec_readreg(peak_meter_src_l);
-#endif
+ /* reset pm_max_left so that subsequent calls of peak_meter_peek don't
+ get fooled by an old maximum value */
+ pm_max_left = pm_cur_left;
return retval;
}
@@ -749,25 +717,18 @@ static int peak_meter_read_l (void)
* since the last call of peak_meter_read_l. The value
* is in the range 0 <= value < MAX_PEAK.
*/
-static int peak_meter_read_r (void) {
- /* peak_meter_r contains the maximum of
- all peak values that were read by peak_meter_peek
- since the last call of peak_meter_read_r */
- int retval = peak_meter_r;
+static int peak_meter_read_r(void)
+{
+ /* peak_meter_r contains the maximum of all peak values that were read
+ by peak_meter_peek since the last call of peak_meter_read_r */
+ int retval = pm_max_right;
+
#ifdef PM_DEBUG
peek_calls = 0;
#endif
-
-#ifdef SIMULATOR
- peak_meter_l = 8000;
-#elif CONFIG_HWCODEC == MASNONE
- pcm_calculate_peaks(NULL, &peak_meter_r);
-#else
- /* reset peak_meter_r so that subsequent calls of
- peak_meter_peek doesn't get fooled by an old
- maximum value */
- peak_meter_r = mas_codec_readreg(peak_meter_src_r);
-#endif
+ /* reset pm_max_right so that subsequent calls of peak_meter_peek don't
+ get fooled by an old maximum value */
+ pm_max_right = pm_cur_right;
return retval;
}
@@ -777,13 +738,14 @@ static int peak_meter_read_r (void) {
* @param int unused - This parameter was added to
* make the function compatible with set_int
*/
-void peak_meter_set_clip_hold(int time) {
- peak_meter_clip_eternal = false;
+void peak_meter_set_clip_hold(int time)
+{
+ pm_clip_eternal = false;
if (time <= 0) {
- peak_meter_l_clip = false;
- peak_meter_r_clip = false;
- peak_meter_clip_eternal = true;
+ pm_clip_left = false;
+ pm_clip_right = false;
+ pm_clip_eternal = true;
}
}
@@ -795,7 +757,8 @@ void peak_meter_set_clip_hold(int time) {
* @param int meterwidht - The widht of the meter in pixel
* @return unsigned short - A value 0 <= return value <= meterwidth
*/
-unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){
+unsigned short peak_meter_scale_value(unsigned short val, int meterwidth)
+{
int retval;
if (val <= peak_meter_range_min) {
@@ -809,10 +772,10 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){
retval = val;
/* different scaling is used for dBfs and linear percent */
- if (peak_meter_use_dbfs) {
+ if (pm_use_dbfs) {
/* scale the samples dBfs */
- retval = (calc_db(retval) - db_min) * meterwidth / db_range;
+ retval = (calc_db(retval) - pm_db_min) * meterwidth / pm_db_range;
}
/* Scale for linear percent display */
@@ -820,7 +783,7 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth){
{
/* scale the samples */
retval = ((retval - peak_meter_range_min) * meterwidth)
- / peak_meter_range;
+ / pm_range;
}
return retval;
}
@@ -854,8 +817,7 @@ void peak_meter_draw(int x, int y, int width, int height)
/* read the volume info from MAS */
left = peak_meter_read_l();
- right = peak_meter_read_r();
- /*peak_meter_peek();*/
+ right = peak_meter_read_r();
/* scale the samples dBfs */
left = peak_meter_scale_value(left, meterwidth);
@@ -865,7 +827,7 @@ void peak_meter_draw(int x, int y, int width, int height)
(The scale becomes invalid when the range changed.) */
if (!db_scale_valid){
- if (peak_meter_use_dbfs) {
+ if (pm_use_dbfs) {
db_scale_count = DB_SCALE_SRC_VALUES_SIZE;
for (i = 0; i < db_scale_count; i++){
/* find the real x-coords for predefined interesting
@@ -884,7 +846,7 @@ void peak_meter_draw(int x, int y, int width, int height)
for (i = 0; i < db_scale_count; i++) {
db_scale_lcd_coord[i] =
(i * (MAX_PEAK / 10) - peak_meter_range_min) *
- meterwidth / peak_meter_range;
+ meterwidth / pm_range;
}
}
@@ -894,41 +856,41 @@ void peak_meter_draw(int x, int y, int width, int height)
}
/* apply release */
- left = MAX(left , last_left - peak_meter_release);
- right = MAX(right, last_right - peak_meter_release);
+ left = MAX(left , last_left - pm_peak_release);
+ right = MAX(right, last_right - pm_peak_release);
/* reset max values after timeout */
- if (TIME_AFTER(current_tick, peak_meter_timeout_l)){
- peak_meter_max_l = 0;
+ if (TIME_AFTER(current_tick, pm_peak_timeout_l)){
+ pm_peak_left = 0;
}
- if (TIME_AFTER(current_tick, peak_meter_timeout_r)){
- peak_meter_max_r = 0;
+ if (TIME_AFTER(current_tick, pm_peak_timeout_r)){
+ pm_peak_right = 0;
}
- if (!peak_meter_clip_eternal) {
- if (peak_meter_l_clip &&
- TIME_AFTER(current_tick, peak_meter_clip_timeout_l)){
- peak_meter_l_clip = false;
+ if (!pm_clip_eternal) {
+ if (pm_clip_left &&
+ TIME_AFTER(current_tick, pm_clip_timeout_l)){
+ pm_clip_left = false;
}
- if (peak_meter_r_clip &&
- TIME_AFTER(current_tick, peak_meter_clip_timeout_r)){
- peak_meter_r_clip = false;
+ if (pm_clip_right &&
+ TIME_AFTER(current_tick, pm_clip_timeout_r)){
+ pm_clip_right = false;
}
}
/* check for new max values */
- if (left > peak_meter_max_l) {
- peak_meter_max_l = left - 1;
- peak_meter_timeout_l =
- current_tick + max_time_out[peak_meter_hold];
+ if (left > pm_peak_left) {
+ pm_peak_left = left - 1;
+ pm_peak_timeout_l =
+ current_tick + peak_time_out[pm_peak_hold];
}
- if (right > peak_meter_max_r) {
- peak_meter_max_r = right - 1;
- peak_meter_timeout_r =
- current_tick + max_time_out[peak_meter_hold];
+ if (right > pm_peak_right) {
+ pm_peak_right = right - 1;
+ pm_peak_timeout_r =
+ current_tick + peak_time_out[pm_peak_hold];
}
}
@@ -939,19 +901,19 @@ void peak_meter_draw(int x, int y, int width, int height)
/* draw left */
lcd_fillrect (x, y, left, height / 2 - 2 );
- if (peak_meter_max_l > 0) {
- lcd_vline(x + peak_meter_max_l, y, y + height / 2 - 2 );
+ if (pm_peak_left > 0) {
+ lcd_vline(x + pm_peak_left, y, y + height / 2 - 2 );
}
- if (peak_meter_l_clip) {
+ if (pm_clip_left) {
lcd_fillrect(x + meterwidth, y, 3, height / 2 - 1);
}
/* draw right */
lcd_fillrect(x, y + height / 2 + 1, right, height / 2 - 2);
- if (peak_meter_max_r > 0) {
- lcd_vline( x + peak_meter_max_r, y + height / 2, y + height - 2);
+ if (pm_peak_right > 0) {
+ lcd_vline( x + pm_peak_right, y + height / 2, y + height - 2);
}
- if (peak_meter_r_clip) {
+ if (pm_clip_right) {
lcd_fillrect(x + meterwidth, y + height / 2, 3, height / 2 - 1);
}
@@ -1071,7 +1033,8 @@ void peak_meter_define_trigger(
* Enables or disables the trigger.
* @param on - If true the trigger is turned on.
*/
-void peak_meter_trigger(bool on) {
+void peak_meter_trigger(bool on)
+{
/* don't use set_trigger here as that would fire an undesired event */
trig_status = on ? TRIG_READY : TRIG_OFF;
}
@@ -1081,7 +1044,8 @@ void peak_meter_trigger(bool on) {
* @param listener - The function that is called with each change of
* trig_status. May be set to NULL if no callback is desired.
*/
-void peak_meter_set_trigger_listener(void (*listener)(int status)) {
+void peak_meter_set_trigger_listener(void (*listener)(int status))
+{
trigger_listener = listener;
}
@@ -1097,78 +1061,99 @@ void peak_meter_set_trigger_listener(void (*listener)(int status)) {
* peak_meter_release_trigger. To turn the trigger off call
* peak_meter_trigger_off.
*/
-int peak_meter_trigger_status(void) {
+int peak_meter_trigger_status(void)
+{
return trig_status; /* & TRIG_PIT_MASK;*/
}
-void peak_meter_draw_trig(int xpos, int ypos) {
- int x = xpos + ICON_PLAY_STATE_WIDTH + 1;
+void peak_meter_draw_trig(int xpos, int ypos)
+{
+ int barstart, barend;
+ int icon, ixpos;
switch (trig_status) {
- long time_left;
case TRIG_READY:
- scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2,
- TRIGBAR_WIDTH, 0, 0, HORIZONTAL);
- lcd_mono_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos,
- ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT);
+ barstart = 0;
+ barend = 0;
+ icon = Icon_Stop;
+ ixpos = xpos;
break;
case TRIG_STEADY:
- case TRIG_RETRIG:
- time_left = trig_strt_duration - (current_tick - trig_hightime);
- time_left = time_left * TRIGBAR_WIDTH / trig_strt_duration;
- scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2,
- TRIGBAR_WIDTH, 0, TRIGBAR_WIDTH - time_left, HORIZONTAL);
- lcd_mono_bitmap(bitmap_icons_7x8[Icon_Stop], xpos, ypos,
- ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT);
+ case TRIG_RETRIG:
+ barstart = 0;
+ barend = TRIGBAR_WIDTH * (current_tick - trig_hightime)
+ / trig_strt_duration;
+ icon = Icon_Stop;
+ ixpos = xpos;
break;
case TRIG_GO:
case TRIG_CONTINUE:
- scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2,
- TRIGBAR_WIDTH, TRIGBAR_WIDTH, TRIGBAR_WIDTH, HORIZONTAL);
- lcd_mono_bitmap(bitmap_icons_7x8[Icon_Record],
- TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos,
- ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT);
+ barstart = TRIGBAR_WIDTH;
+ barend = TRIGBAR_WIDTH;
+ icon = Icon_Record;
+ ixpos = TRIG_WIDTH - ICON_PLAY_STATE_WIDTH;
break;
- case TRIG_POSTREC:
- time_left = trig_stp_hold - (current_tick - trig_lowtime);
- time_left = time_left * TRIGBAR_WIDTH / trig_stp_hold;
- scrollbar(x, ypos + 1, TRIGBAR_WIDTH, TRIG_HEIGHT - 2,
- TRIGBAR_WIDTH, time_left, TRIGBAR_WIDTH, HORIZONTAL);
- lcd_mono_bitmap(bitmap_icons_7x8[Icon_Record],
- TRIG_WIDTH - ICON_PLAY_STATE_WIDTH, ypos,
- ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT);
+ case TRIG_POSTREC:
+ barstart = TRIGBAR_WIDTH
+ - TRIGBAR_WIDTH * (current_tick - trig_lowtime)
+ / trig_stp_hold;
+ barend = TRIGBAR_WIDTH;
+ icon = Icon_Record;
+ ixpos = TRIG_WIDTH - ICON_PLAY_STATE_WIDTH;
break;
- }
+ default:
+ return;
+ }
+ scrollbar(xpos + ICON_PLAY_STATE_WIDTH + 1, ypos + 1,
+ TRIGBAR_WIDTH, TRIG_HEIGHT - 2,
+ TRIGBAR_WIDTH, barstart, barend, HORIZONTAL);
+ lcd_mono_bitmap(bitmap_icons_7x8[icon], ixpos, ypos,
+ ICON_PLAY_STATE_WIDTH, STATUSBAR_HEIGHT);
}
#endif
int peak_meter_draw_get_btn(int x, int y, int width, int height)
{
- int button;
+ int button = BUTTON_NONE;
long next_refresh = current_tick;
long next_big_refresh = current_tick + HZ / 10;
- button = BUTTON_NONE;
+#ifndef SIMULATOR
+ bool highperf = !ata_disk_is_active();
+#else
+ bool highperf = false;
+#endif
+ bool dopeek = true;
- while (!TIME_AFTER(current_tick, next_big_refresh)) {
+ while (TIME_BEFORE(current_tick, next_big_refresh)) {
button = button_get(false);
if (button != BUTTON_NONE) {
break;
}
- sleep(MAX(next_refresh - current_tick, 0) - 1);
- next_refresh = current_tick + HZ / peak_meter_fps;
- peak_meter_peek();
- peak_meter_draw(x, y, width, height);
- lcd_update_rect(x, y, width, height);
+ if (dopeek) { /* Peek only once per refresh when disk is */
+ peak_meter_peek(); /* spinning, but as often as possible */
+ dopeek = highperf; /* otherwise. */
+ yield();
+ } else {
+ sleep(0); /* Sleep until end of current tick. */
+ }
+ if (TIME_AFTER(current_tick, next_refresh)) {
+ peak_meter_draw(x, y, width, height);
+ lcd_update_rect(x, y, width, height);
+ next_refresh += HZ / PEAK_METER_FPS;
+ dopeek = true;
+ }
}
+
return button;
}
#ifdef PM_DEBUG
-static void peak_meter_clear_histogram(void) {
+static void peak_meter_clear_histogram(void)
+{
int i = 0;
for (i = 0; i < TICKS_PER_DRAW_SIZE; i++) {
ticks_per_redraw[i] = (unsigned int)0;
@@ -1179,7 +1164,8 @@ static void peak_meter_clear_histogram(void) {
}
}
-bool peak_meter_histogram(void) {
+bool peak_meter_histogram(void)
+{
int i;
int btn = BUTTON_NONE;
while ((btn & BUTTON_OFF) != BUTTON_OFF )
@@ -1210,7 +1196,7 @@ bool peak_meter_histogram(void) {
lcd_hline(0, x, y + i);
}
lcd_update();
-
+
btn = button_get(true);
if (btn == BUTTON_PLAY) {
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 @@
#ifndef __PEAKMETER_H__
#define __PEAKMETER_H__
+#define PEAK_METER_FPS 20
+
/*#define PM_DEBUG */
#ifdef PM_DEBUG
extern bool peak_meter_histogram(void);
#endif
extern bool peak_meter_enabled;
-extern int peak_meter_fps;
extern void peak_meter_playback(bool playback);
extern void peak_meter_draw(int x, int y, int width, int height);
@@ -39,8 +40,8 @@ extern void peak_meter_set_min(int newmin);
extern int peak_meter_get_min(void);
extern void peak_meter_set_max(int newmax);
extern int peak_meter_get_max(void);
-extern void peak_meter_set_use_dbfs(int use);
-extern int peak_meter_get_use_dbfs(void);
+extern void peak_meter_set_use_dbfs(bool use);
+extern bool peak_meter_get_use_dbfs(void);
extern int calc_db (int isample);
extern int peak_meter_db2sample(int db);
extern 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)
if(search_dir)
button = button_get(false);
else
- button = button_get_w_tmo(HZ / peak_meter_fps);
+ button = button_get_w_tmo(HZ / PEAK_METER_FPS);
switch(button)
{
case FM_STOP:
@@ -479,13 +479,10 @@ bool radio_screen(void)
/* Only display the peak meter when not recording */
if(!audio_status())
{
- lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- lcd_fillrect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
- lcd_set_drawmode(DRMODE_SOLID);
peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
}
-
+
if(TIME_AFTER(current_tick, timeout))
{
timeout = current_tick + HZ;