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
This commit is contained in:
parent
89a8ca4408
commit
99a0598c28
|
@ -79,12 +79,12 @@
|
|||
#endif
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define CODEC_API_VERSION 41
|
||||
#define CODEC_API_VERSION 42
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define CODEC_MIN_API_VERSION 40
|
||||
#define CODEC_MIN_API_VERSION 42
|
||||
|
||||
/* codec return codes */
|
||||
enum codec_status {
|
||||
|
@ -314,8 +314,8 @@ struct codec_api {
|
|||
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
||||
unsigned short (*peak_meter_scale_value)(unsigned short val,
|
||||
int meterwidth);
|
||||
void (*peak_meter_set_use_dbfs)(int use);
|
||||
int (*peak_meter_get_use_dbfs)(void);
|
||||
void (*peak_meter_set_use_dbfs)(bool use);
|
||||
bool (*peak_meter_get_use_dbfs)(void);
|
||||
#endif
|
||||
|
||||
/* new stuff at the end, sort into place next time
|
||||
|
|
|
@ -878,21 +878,21 @@ voice: "Numeric"
|
|||
new:
|
||||
|
||||
id: LANG_PM_PERFORMANCE
|
||||
desc: in the peak meter menu
|
||||
eng: "Performance"
|
||||
voice: "Performance"
|
||||
desc: DEPRECATED
|
||||
eng: ""
|
||||
voice:
|
||||
new:
|
||||
|
||||
id: LANG_PM_HIGH_PERFORMANCE
|
||||
desc: in the peak meter menu
|
||||
eng: "High performance"
|
||||
voice: "High performance"
|
||||
desc: DEPRECATED
|
||||
eng: ""
|
||||
voice: ""
|
||||
new:
|
||||
|
||||
id: LANG_PM_ENERGY_SAVER
|
||||
desc: in the peak meter menu
|
||||
eng: "Save Energy"
|
||||
voice: "Save Energy"
|
||||
desc: DEPRECATED
|
||||
eng: ""
|
||||
voice: ""
|
||||
new:
|
||||
|
||||
id: LANG_PM_SCALE
|
||||
|
|
|
@ -88,12 +88,12 @@
|
|||
#endif
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define PLUGIN_API_VERSION 47
|
||||
#define PLUGIN_API_VERSION 48
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define PLUGIN_MIN_API_VERSION 47
|
||||
#define PLUGIN_MIN_API_VERSION 48
|
||||
|
||||
/* plugin return codes */
|
||||
enum plugin_status {
|
||||
|
@ -413,8 +413,8 @@ struct plugin_api {
|
|||
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
||||
unsigned short (*peak_meter_scale_value)(unsigned short val,
|
||||
int meterwidth);
|
||||
void (*peak_meter_set_use_dbfs)(int use);
|
||||
int (*peak_meter_get_use_dbfs)(void);
|
||||
void (*peak_meter_set_use_dbfs)(bool use);
|
||||
bool (*peak_meter_get_use_dbfs)(void);
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
int (*read_bmp_file)(char* filename, int *get_width, int *get_height,
|
||||
|
|
|
@ -271,7 +271,7 @@ static void update_icons(void)
|
|||
|
||||
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
||||
/* The scale icon */
|
||||
rb->lcd_mono_bitmap(SCALE_BMP[rb->peak_meter_get_use_dbfs()],
|
||||
rb->lcd_mono_bitmap(SCALE_BMP[rb->peak_meter_get_use_dbfs() ? 1 : 0],
|
||||
2 *LCD_WIDTH/3 + LCD_WIDTH/3 / 2 - BMPWIDTH/2, LCD_HEIGHT - BMPHEIGHT,
|
||||
BMPWIDTH, BMPHEIGHT);
|
||||
#else
|
||||
|
@ -1134,7 +1134,7 @@ unsigned long splitedit_editor(struct mp3entry * mp3_to_split,
|
|||
|
||||
case SPLITEDIT_SCALE:
|
||||
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
||||
rb->peak_meter_set_use_dbfs(rb->peak_meter_get_use_dbfs() +1);
|
||||
rb->peak_meter_set_use_dbfs(!rb->peak_meter_get_use_dbfs());
|
||||
#endif
|
||||
splitedit_invalidate_osci();
|
||||
update_icons();
|
||||
|
|
|
@ -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;
|
||||
/* 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;
|
||||
|
||||
/* point in time when peak_meter_max_x becomes invalid */
|
||||
static long peak_meter_timeout_l;
|
||||
static long peak_meter_timeout_r;
|
||||
/* 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;
|
||||
|
||||
/* when true a clip has occurred */
|
||||
static bool peak_meter_l_clip = false;
|
||||
static bool peak_meter_r_clip = false;
|
||||
/* 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;
|
||||
|
||||
/* point in time when peak_meter_x_oveflow becomes invalid */
|
||||
static long peak_meter_clip_timeout_l;
|
||||
static long peak_meter_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 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;
|
||||
|
||||
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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -78,7 +78,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
|
|||
#include "pcm_playback.h"
|
||||
#endif
|
||||
|
||||
#define CONFIG_BLOCK_VERSION 25
|
||||
#define CONFIG_BLOCK_VERSION 26
|
||||
#define CONFIG_BLOCK_SIZE 512
|
||||
#define RTC_BLOCK_SIZE 44
|
||||
|
||||
|
@ -349,8 +349,7 @@ static const struct bit_entry hd_bits[] =
|
|||
/* peak meter */
|
||||
{5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */
|
||||
"on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min,3min,5min,10min,20min,45min,90min" },
|
||||
{1, S_O(peak_meter_performance), false, "peak meter busy", off_on },
|
||||
{5, S_O(peak_meter_hold), 3, "peak meter hold",
|
||||
{5, S_O(peak_meter_hold), 3, "peak meter hold",
|
||||
"off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" },
|
||||
{7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */
|
||||
{1, S_O(peak_meter_dbfs), true, "peak meter dbfs", off_on },
|
||||
|
|
|
@ -250,7 +250,6 @@ struct user_settings
|
|||
int peak_meter_hold; /* hold time for peak meter in 1/100 s */
|
||||
int peak_meter_clip_hold; /* hold time for clips */
|
||||
bool peak_meter_dbfs; /* show linear or dbfs values */
|
||||
bool peak_meter_performance; /* true: high performance, else save energy*/
|
||||
int peak_meter_min; /* range minimum */
|
||||
int peak_meter_max; /* range maximum */
|
||||
bool car_adapter_mode; /* 0=off 1=on */
|
||||
|
|
|
@ -318,16 +318,6 @@ static bool volume_type(void)
|
|||
INT, names, 2, NULL);
|
||||
}
|
||||
|
||||
#ifdef PM_DEBUG
|
||||
static bool peak_meter_fps_menu(void) {
|
||||
bool retval = false;
|
||||
retval = set_int( "Refresh rate", "/s", UNIT_PER_SEC,
|
||||
&peak_meter_fps,
|
||||
NULL, 1, 5, 40, NULL);
|
||||
return retval;
|
||||
}
|
||||
#endif /* PM_DEBUG */
|
||||
|
||||
/**
|
||||
* Menu to set the hold time of normal peaks.
|
||||
*/
|
||||
|
@ -544,25 +534,6 @@ static bool peak_meter_max(void) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu to select wether the meter is in
|
||||
* precision or in energy saver mode
|
||||
*/
|
||||
static bool peak_meter_performance(void) {
|
||||
bool retval = false;
|
||||
retval = set_bool_options(str(LANG_PM_PERFORMANCE),
|
||||
&global_settings.peak_meter_performance,
|
||||
STR(LANG_PM_HIGH_PERFORMANCE), STR(LANG_PM_ENERGY_SAVER),
|
||||
NULL);
|
||||
|
||||
if (global_settings.peak_meter_performance) {
|
||||
peak_meter_fps = 25;
|
||||
} else {
|
||||
peak_meter_fps = 20;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu to configure the peak meter
|
||||
*/
|
||||
|
@ -575,10 +546,6 @@ static bool peak_meter_menu(void)
|
|||
{ ID2P(LANG_PM_RELEASE) , peak_meter_release },
|
||||
{ ID2P(LANG_PM_PEAK_HOLD), peak_meter_hold },
|
||||
{ ID2P(LANG_PM_CLIP_HOLD), peak_meter_clip_hold },
|
||||
{ ID2P(LANG_PM_PERFORMANCE), peak_meter_performance },
|
||||
#ifdef PM_DEBUG
|
||||
{ "Refresh rate" , -1 , peak_meter_fps_menu },
|
||||
#endif
|
||||
{ ID2P(LANG_PM_SCALE) , peak_meter_scale },
|
||||
{ ID2P(LANG_PM_MIN) , peak_meter_min },
|
||||
{ ID2P(LANG_PM_MAX) , peak_meter_max },
|
||||
|
|
51
apps/wps.c
51
apps/wps.c
|
@ -391,46 +391,29 @@ long wps_show(void)
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
/* when the peak meter is enabled we want to have a
|
||||
few extra updates to make it look smooth. On the
|
||||
other hand we don't want to waste energy if it
|
||||
other hand we don't want to waste energy if it
|
||||
isn't displayed */
|
||||
if (peak_meter_enabled) {
|
||||
int i;
|
||||
|
||||
/* In high performance mode we read out the mas as
|
||||
often as we can. There is no sleep for cpu */
|
||||
if (global_settings.peak_meter_performance) {
|
||||
long next_refresh = current_tick;
|
||||
long next_big_refresh = current_tick + HZ / 5;
|
||||
button = BUTTON_NONE;
|
||||
while (!TIME_AFTER(current_tick, next_big_refresh)) {
|
||||
button = button_get(false);
|
||||
if (button != BUTTON_NONE) {
|
||||
break;
|
||||
}
|
||||
peak_meter_peek();
|
||||
sleep(1);
|
||||
|
||||
if (TIME_AFTER(current_tick, next_refresh)) {
|
||||
wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
|
||||
next_refresh = current_tick + HZ / peak_meter_fps;
|
||||
}
|
||||
long next_refresh = current_tick;
|
||||
long next_big_refresh = current_tick + HZ / 5;
|
||||
button = BUTTON_NONE;
|
||||
while (TIME_BEFORE(current_tick, next_big_refresh)) {
|
||||
button = button_get(false);
|
||||
if (button != BUTTON_NONE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* In energy saver mode the cpu may sleep a
|
||||
little bit while waiting for buttons */
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
button = button_get_w_tmo(HZ / peak_meter_fps);
|
||||
if (button != 0) {
|
||||
break;
|
||||
}
|
||||
peak_meter_peek();
|
||||
sleep(0); /* Sleep until end of current tick. */
|
||||
|
||||
if (TIME_AFTER(current_tick, next_refresh)) {
|
||||
wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
|
||||
next_refresh += HZ / PEAK_METER_FPS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The peak meter is disabled
|
||||
|
||||
}
|
||||
|
||||
/* The peak meter is disabled
|
||||
-> no additional screen updates needed */
|
||||
else {
|
||||
button = button_get_w_tmo(HZ/5);
|
||||
|
|
|
@ -99,15 +99,15 @@ static void dma_stop(void)
|
|||
|
||||
/*
|
||||
* This function goes directly into the DMA buffer to calculate the left and
|
||||
* right peak values. To avoid missing peaks it tries to look forward a full
|
||||
* refresh period (1/20 sec) although it's always possible that the entire
|
||||
* period will not be visible. To reduce CPU load it only looks at every
|
||||
* third sample, and this can be reduced even further if needed (even every
|
||||
* tenth sample would still be pretty accurate).
|
||||
* right peak values. To avoid missing peaks it tries to look forward two full
|
||||
* peek periods (2/HZ sec, 100% overlap), although it's always possible that
|
||||
* the entire period will not be visible. To reduce CPU load it only looks at
|
||||
* every third sample, and this can be reduced even further if needed (even
|
||||
* every tenth sample would still be pretty accurate).
|
||||
*/
|
||||
|
||||
#define PEAK_SAMPLES 2205 /* 44100 sample rate / 20 Hz refresh */
|
||||
#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
|
||||
#define PEAK_SAMPLES (44100*2/HZ) /* 44100 samples * 2 / 100 Hz tick */
|
||||
#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
|
||||
|
||||
void pcm_calculate_peaks(int *left, int *right)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user