From daf611d9ba899a3ab0431e973d9d76db6b57a0a3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 7 Feb 2021 14:02:50 +0100 Subject: [PATCH] Implement Input Monitoring --- libs/ardour/ardour/port_manager.h | 7 +++++++ libs/ardour/ardour/session.h | 16 ++++++++-------- libs/ardour/port_manager.cc | 13 ++++++++++++- libs/ardour/session.cc | 20 ++++++++++++++++++++ libs/ardour/session_rtevents.cc | 12 ++++++++++++ libs/ardour/solo_mute_release.cc | 4 ++++ 6 files changed, 63 insertions(+), 9 deletions(-) diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h index aa508d4c5c..c2131c630b 100644 --- a/libs/ardour/ardour/port_manager.h +++ b/libs/ardour/ardour/port_manager.h @@ -35,6 +35,7 @@ #include "ardour/chan_count.h" #include "ardour/midiport_manager.h" +#include "ardour/monitor_port.h" #include "ardour/port.h" namespace ARDOUR { @@ -251,6 +252,10 @@ public: AudioInputPorts audio_input_ports () const; MIDIInputPorts midi_input_ports () const; + MonitorPort& monitor_port () { + return _monitor_port; + } + protected: boost::shared_ptr _backend; @@ -298,6 +303,8 @@ private: void save_port_info (); void update_input_ports (bool); + MonitorPort _monitor_port; + struct PortID { PortID (boost::shared_ptr, DataType, bool, std::string const&); PortID (XMLNode const&, bool old_midi_format = false); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index ef4754b3c5..35335fc782 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -922,22 +922,22 @@ public: /* session-wide solo/mute/rec-enable */ - bool muted() const; + bool muted () const; std::vector > cancel_all_mute (); - bool soloing() const { return _non_soloed_outs_muted; } - bool listening() const { return _listen_cnt > 0; } - bool solo_isolated() const { return _solo_isolated_cnt > 0; } + bool soloing () const { return _non_soloed_outs_muted; } + bool listening () const; + bool solo_isolated () const { return _solo_isolated_cnt > 0; } void cancel_all_solo (); - bool solo_selection_active(); - void solo_selection( StripableList&, bool ); - - static const SessionEvent::RTeventCallback rt_cleanup; + bool solo_selection_active (); + void solo_selection (StripableList&, bool); void clear_all_solo_state (boost::shared_ptr); void prepare_momentary_solo (SoloMuteRelease* smr = NULL, bool exclusive = false, boost::shared_ptr route = boost::shared_ptr ()); + static const SessionEvent::RTeventCallback rt_cleanup; + /* Control-based methods */ void set_controls (boost::shared_ptr, double val, PBD::Controllable::GroupControlDisposition); diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc index 08d1c8f7da..078f9447b2 100644 --- a/libs/ardour/port_manager.cc +++ b/libs/ardour/port_manager.cc @@ -852,6 +852,7 @@ PortManager::update_input_ports (bool clear) if (clear) { new_audio = audio_ports; new_midi = midi_ports; + _monitor_port.clear_ports (true); } else { boost::shared_ptr aip = _audio_input_ports.reader (); /* find new audio ports */ @@ -898,6 +899,7 @@ PortManager::update_input_ports (bool clear) } else { for (std::vector::const_iterator p = old_audio.begin(); p != old_audio.end(); ++p) { apw->erase (*p); + _monitor_port.remove_port (*p, true); } } for (std::vector::const_iterator p = new_audio.begin(); p != new_audio.end(); ++p) { @@ -1633,12 +1635,12 @@ PortManager::fill_midi_port_info_locked () void PortManager::set_port_buffer_sizes (pframes_t n) { - boost::shared_ptr all = ports.reader(); for (Ports::iterator p = all->begin(); p != all->end(); ++p) { p->second->set_buffer_size (n); } + _monitor_port.set_buffer_size (n); } bool @@ -1743,6 +1745,9 @@ 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); + /* calculate peak of all physical inputs (readable ports) */ std::vector port_names; get_physical_inputs (DataType::AUDIO, port_names); @@ -1771,6 +1776,10 @@ 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); /* falloff */ @@ -1786,6 +1795,8 @@ 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); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 43547c676b..a10888cfb1 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -987,6 +987,7 @@ Session::remove_monitor_section () if (!deletion_in_progress ()) { setup_route_monitor_sends (false, true); + _engine.monitor_port().clear_ports (true); } remove_route (_monitor_out); @@ -3549,6 +3550,8 @@ Session::route_listen_changed (Controllable::GroupControlDisposition group_overr if (Config->get_exclusive_solo()) { + _engine.monitor_port().clear_ports (false); + RouteGroup* rg = route->route_group (); const bool group_already_accounted_for = (group_override == Controllable::ForGroup); @@ -3666,6 +3669,7 @@ Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlD if (delta == 1 && Config->get_exclusive_solo()) { /* new solo: disable all other solos, but not the group if its solo-enabled */ + _engine.monitor_port().clear_ports (false); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { @@ -7186,6 +7190,22 @@ Session::cancel_all_solo () set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup); clear_all_solo_state (routes.reader()); + + _engine.monitor_port().clear_ports (false); +} + +bool +Session::listening () const +{ + if (_listen_cnt > 0) { + return true; + } + + if (_monitor_out && _engine.monitor_port().monitoring ()) { + return true; + } + + return false; } void diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc index bb552ce981..5c50de1b9a 100644 --- a/libs/ardour/session_rtevents.cc +++ b/libs/ardour/session_rtevents.cc @@ -119,6 +119,18 @@ Session::prepare_momentary_solo (SoloMuteRelease* smr, bool exclusive, boost::sh if (smr) { smr->set (routes_on, routes_off); } + + if (_monitor_out) { + if (smr) { + boost::shared_ptr > pml (new std::list); + _engine.monitor_port().active_monitors (*pml); + smr->set (pml); + } + if (exclusive) { + /* unset any input monitors */ + _engine.monitor_port().clear_ports (false); + } + } } void diff --git a/libs/ardour/solo_mute_release.cc b/libs/ardour/solo_mute_release.cc index 474884e47b..3eab207a78 100644 --- a/libs/ardour/solo_mute_release.cc +++ b/libs/ardour/solo_mute_release.cc @@ -83,5 +83,9 @@ SoloMuteRelease::release (Session* s, bool mute) const } else { s->set_controls (route_list_to_control_list (routes_off, &Stripable::solo_control), 0.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); s->set_controls (route_list_to_control_list (routes_on, &Stripable::solo_control), 1.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); + + if (port_monitors && s->monitor_out ()) { + s->engine().monitor_port().set_active_monitors (*port_monitors); + } } }