From f212ace6f6d4df6f4a1f5464b909ecc8a23d3cbe Mon Sep 17 00:00:00 2001 From: Todd Naugle Date: Fri, 2 Jul 2021 15:39:01 -0500 Subject: [PATCH] Change Mackie Control combined meter to use a peak meter with falloff Mackie surfaces use a special peak meter type that returns the maximum peak for all channels in the strip. The issue was that the implementation of this meter did not follow the falloff the other peak meters. If a real peak meter and a combined peak meter were displayed on the surface at the same time the missing falloff was obvious. Don't calculate the combined meter during run. Instead calculate it only when needed based on the already existing individual peak meters. --- libs/ardour/ardour/meter.h | 1 - libs/ardour/meter.cc | 31 +++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h index f52a0658c3..41d65e8776 100644 --- a/libs/ardour/ardour/meter.h +++ b/libs/ardour/ardour/meter.h @@ -107,7 +107,6 @@ private: std::vector _peak_buffer; // internal, integrate std::vector _peak_power; // includes accurate falloff, hence dB std::vector _max_peak_signal; // dB calculation is done on demand - float _combined_peak; // Mackie surfaces expect the highest peak of all track channels std::vector _kmeter; std::vector _iec1meter; diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc index 0329365569..299768f831 100644 --- a/libs/ardour/meter.cc +++ b/libs/ardour/meter.cc @@ -52,7 +52,6 @@ PeakMeter::PeakMeter (Session& s, const std::string& name) _pending_active = true; _meter_type = MeterPeak; _bufcnt = 0; - _combined_peak = 0; g_atomic_int_set (&_reset_dpm, 1); g_atomic_int_set (&_reset_max, 1); @@ -101,8 +100,6 @@ PeakMeter::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t /*end /* max-peak is set from DPM's peak-buffer, so DPM also needs to be reset in sync */ const bool reset_dpm = g_atomic_int_compare_and_exchange (&_reset_dpm, 1, 0) || reset_max; - _combined_peak = 0; - const uint32_t n_audio = min (current_meters.n_audio (), bufs.count ().n_audio ()); const uint32_t n_midi = min (current_meters.n_midi (), bufs.count ().n_midi ()); @@ -128,11 +125,6 @@ PeakMeter::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t /*end if (this_vel > val) { val = this_vel; } - if (val > 0.01) { - if (_combined_peak < 0.01) { - _combined_peak = 0.01; - } - } } else { val += 1.0 / bufs.get_midi (n).capacity (); if (val > 1.0) { @@ -158,7 +150,6 @@ PeakMeter::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t /*end _peak_buffer[n] = compute_peak (bufs.get_audio (i).data (), nframes, _peak_buffer[n]); _peak_buffer[n] = std::min (_peak_buffer[n], 100.f); // cut off at +40dBFS for falloff. _max_peak_signal[n] = std::max (_peak_buffer[n], _max_peak_signal[n]); - _combined_peak = std::max (_peak_buffer[n], _combined_peak); } if (reset_max) { @@ -202,10 +193,6 @@ PeakMeter::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t /*end _max_peak_signal[n] = 0; } - if (reset_dpm) { - _combined_peak = 0; - } - if (_bufcnt > zoh) { _bufcnt = 0; } @@ -365,7 +352,6 @@ PeakMeter::meter_level (uint32_t n, MeterType type) } } - float mcptmp; switch (type) { case MeterKrms: case MeterK20: @@ -411,8 +397,21 @@ PeakMeter::meter_level (uint32_t n, MeterType type) } break; case MeterMCP: - mcptmp = _combined_peak; - return accurate_coefficient_to_dB (mcptmp); + { + float mcptmp = -std::numeric_limits::infinity (); + /* prefer to report audio only on mixed tracks */ + if (current_meters.n_audio ()) { + for (uint32_t i = current_meters.n_midi (); i < _peak_power.size (); ++i) { + mcptmp = std::max (mcptmp, _peak_power[i]); + } + } + else { + for (uint32_t i = 0; i < current_meters.n_midi () && i < _peak_power.size (); ++i) { + mcptmp = std::max (mcptmp, accurate_coefficient_to_dB (_peak_power[i])); + } + } + return mcptmp; + } case MeterMaxSignal: assert (0); break;