use accurate log10 for meter (fast_log2 is unsuitable inaccurate)
fast_coefficient_to_dB() returns a lower bound value, unsuitable to catch audio peaks. The difference to 20*log10 is as large as 0.4 dB! The effective speedup of fast_log10 compared to log10f is marginal (sweep of all 24bit values) i686 (1.6GHz Intel core): 2.36 [times faster] x86_64 (core2 2.4GHz): 1.63 x86_64 (I3 2.80GHz): 2.03 the execution time of one log10f() averaged over a sweep of all 24 bit values i686 (1.6GHz Intel core): 0.131 usec x86_64 (core2 2.4GHz): 0.033 usec x86_64 (I3 2.80GHz): 0.044 usec PeakMeter::run() is called from dedicated non-rt, no harm done.
This commit is contained in:
parent
617f73f8a9
commit
ee97942165
@ -31,7 +31,7 @@ static inline float fast_coefficient_to_dB (float coeff) {
|
||||
}
|
||||
|
||||
static inline float accurate_coefficient_to_dB (float coeff) {
|
||||
return 20.0f * log10 (coeff);
|
||||
return 20.0f * log10f (coeff);
|
||||
}
|
||||
|
||||
extern double zero_db_as_fraction;
|
||||
|
@ -55,6 +55,8 @@ PeakMeter::~PeakMeter ()
|
||||
* Input acceptance is lenient - the first n buffers from @a bufs will
|
||||
* be metered, where n was set by the last call to setup(), excess meters will
|
||||
* be set to 0.
|
||||
*
|
||||
* (runs in jack realtime context)
|
||||
*/
|
||||
void
|
||||
PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
|
||||
@ -95,7 +97,7 @@ PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_fr
|
||||
// Meter audio in to the rest of the peaks
|
||||
for (uint32_t i = 0; i < n_audio; ++i, ++n) {
|
||||
_peak_signal[n] = compute_peak (bufs.get_audio(i).data(), nframes, _peak_signal[n]);
|
||||
if (/* TODO use separate bit-flags for mixer,meterbridge,.. */ /* 1 || */ _meter_type & MeterKrms) {
|
||||
if (_meter_type & MeterKrms) {
|
||||
_kmeter[i]->process(bufs.get_audio(i).data(), nframes);
|
||||
}
|
||||
}
|
||||
@ -239,11 +241,7 @@ PeakMeter::meter ()
|
||||
;
|
||||
} else {
|
||||
/* empirical WRT to falloff times , 0.01f ^= 100 Hz update rate */
|
||||
#if 1
|
||||
new_peak = _visible_peak_power[n] - _visible_peak_power[n] * Config->get_meter_falloff() * 0.01f * 0.05f;
|
||||
#else
|
||||
new_peak = _visible_peak_power[n] - sqrt(_visible_peak_power[n] * Config->get_meter_falloff() * 0.01f * 0.0002f);
|
||||
#endif
|
||||
if (new_peak < (1.0 / 512.0)) new_peak = 0;
|
||||
}
|
||||
_visible_peak_power[n] = new_peak;
|
||||
@ -257,7 +255,7 @@ PeakMeter::meter ()
|
||||
_max_peak_signal[n] = std::max(new_peak, _max_peak_signal[n]);
|
||||
|
||||
if (new_peak > 0.0) {
|
||||
new_peak = fast_coefficient_to_dB (new_peak);
|
||||
new_peak = accurate_coefficient_to_dB (new_peak);
|
||||
} else {
|
||||
new_peak = minus_infinity();
|
||||
}
|
||||
@ -283,7 +281,11 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
|
||||
{
|
||||
const uint32_t n_midi = current_meters.n_midi();
|
||||
if ((n - n_midi) < _kmeter.size() && (n - n_midi) >= 0) {
|
||||
#if 0
|
||||
return fast_coefficient_to_dB (_kmeter[n-n_midi]->read());
|
||||
#else
|
||||
return accurate_coefficient_to_dB (_kmeter[n-n_midi]->read());
|
||||
#endif
|
||||
}
|
||||
return minus_infinity();
|
||||
}
|
||||
@ -304,6 +306,7 @@ PeakMeter::meter_level(uint32_t n, MeterType type) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeakMeter::set_type(MeterType t)
|
||||
{
|
||||
@ -329,5 +332,3 @@ PeakMeter::state (bool full_state)
|
||||
node.add_property("type", "meter");
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user