From b0db646029c928695777f7f8045db4cbd06b2df1 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 8 Jun 2021 14:34:01 +0200 Subject: [PATCH] Refactor input port monitoring * avoid memory allocation (remove std:set<>&) * skip nested loop using port-names as IDs However this adds a bit of extra cost in case input ports are monitored: get_port_by_name() and get_buffer() --- libs/ardour/ardour/monitor_port.h | 12 ++++++------ libs/ardour/monitor_port.cc | 30 +++++++++++++++++++----------- libs/ardour/port_manager.cc | 8 +------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/libs/ardour/ardour/monitor_port.h b/libs/ardour/ardour/monitor_port.h index 8d57cd9f03..f8166a4fab 100644 --- a/libs/ardour/ardour/monitor_port.h +++ b/libs/ardour/ardour/monitor_port.h @@ -19,6 +19,7 @@ #ifndef _ardour_monitor_port_h_ #define _ardour_monitor_port_h_ +#include #include #include "zita-resampler/vmresampler.h" @@ -26,6 +27,7 @@ #include "pbd/rcu.h" #include "ardour/audio_buffer.h" +#include "ardour/port_engine.h" namespace ARDOUR { @@ -50,10 +52,7 @@ public: protected: friend class PortManager; MonitorPort (); - - void prepare (std::set&); - void monitor (Sample*, pframes_t, std::string const&); - void finalize (pframes_t); + void monitor (PortEngine&, pframes_t); private: struct MonitorInfo { @@ -67,10 +66,11 @@ private: bool remove; }; - typedef std::map > MonitorPorts; + void collect (boost::shared_ptr, Sample*, pframes_t, std::string const&); + void finalize (pframes_t); + typedef std::map > MonitorPorts; SerializedRCUManager _monitor_ports; - boost::shared_ptr _cycle_ports; AudioBuffer* _buffer; ArdourZita::VMResampler _src; diff --git a/libs/ardour/monitor_port.cc b/libs/ardour/monitor_port.cc index b59cd536ee..4fac23e947 100644 --- a/libs/ardour/monitor_port.cc +++ b/libs/ardour/monitor_port.cc @@ -78,28 +78,37 @@ MonitorPort::silent () const } void -MonitorPort::prepare (std::set& portset) +MonitorPort::monitor (PortEngine& e, pframes_t n_samples) { if (!_silent) { memset (_input, 0, sizeof (Sample) * _insize); _silent = true; } + boost::shared_ptr cycle_ports = _monitor_ports.reader (); - _cycle_ports = _monitor_ports.reader (); - for (MonitorPorts::iterator i = _cycle_ports->begin (); i != _cycle_ports->end(); ++i) { + for (MonitorPorts::iterator i = cycle_ports->begin (); i != cycle_ports->end(); ++i) { if (i->second->remove && i->second->gain == 0) { continue; } - portset.insert (i->first); + + PortEngine::PortHandle ph = e.get_port_by_name (i->first); + if (!ph) { + continue; + } + Sample* buf = (Sample*) e.get_buffer (ph, n_samples); + if (!buf) { + continue; + } + collect (i->second, buf, n_samples, i->first); } + finalize (n_samples); } void -MonitorPort::monitor (Sample* buf, pframes_t n_samples, std::string const& pn) +MonitorPort::collect (boost::shared_ptr mi, Sample* buf, pframes_t n_samples, std::string const& pn) { - MonitorPorts::iterator i = _cycle_ports->find (pn); - gain_t target_gain = i->second->remove ? 0.0 : 1.0; - gain_t current_gain = i->second->gain; + gain_t target_gain = mi->remove ? 0.0 : 1.0; + gain_t current_gain = mi->gain; if (target_gain == current_gain && target_gain == 0) { return; @@ -129,7 +138,7 @@ MonitorPort::monitor (Sample* buf, pframes_t n_samples, std::string const& pn) offset += n_proc; } if (fabsf (current_gain - target_gain) < GAIN_COEFF_DELTA) { - i->second->gain = target_gain; + mi->gain = target_gain; #if 1 // not strictly needed if (target_gain == 0) { /* remove port from list, uses RCUWriter */ @@ -137,7 +146,7 @@ MonitorPort::monitor (Sample* buf, pframes_t n_samples, std::string const& pn) } #endif } else { - i->second->gain = current_gain; + mi->gain = current_gain; } } _silent = false; @@ -158,7 +167,6 @@ MonitorPort::finalize (pframes_t n_samples) ++_src.out_data; --_src.out_count; } - _cycle_ports.reset (); } ARDOUR::AudioBuffer& diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc index 32b170d84b..3e0f014ccc 100644 --- a/libs/ardour/port_manager.cc +++ b/libs/ardour/port_manager.cc @@ -1765,8 +1765,7 @@ PortManager::run_input_meters (pframes_t n_samples, samplecnt_t rate) const float falloff = falloff_cache.calc (n_samples, rate); - std::set monitor_portset; - _monitor_port.prepare (monitor_portset); + _monitor_port.monitor (port_engine (), n_samples); /* calculate peak of all physical inputs (readable ports) */ std::vector port_names; @@ -1799,9 +1798,6 @@ PortManager::run_input_meters (pframes_t n_samples, samplecnt_t rate) continue; } - if (monitor_portset.find (*p) != monitor_portset.end ()) { - _monitor_port.monitor (buf, n_samples, *p); - } ai->second.scope->write (buf, n_samples); @@ -1818,8 +1814,6 @@ PortManager::run_input_meters (pframes_t n_samples, samplecnt_t rate) ai->second.meter->peak = std::max (ai->second.meter->peak, level); } - _monitor_port.finalize (n_samples); - /* MIDI */ port_names.clear (); get_physical_inputs (DataType::MIDI, port_names);