Implement Input Monitoring

This commit is contained in:
Robin Gareus 2021-02-07 14:02:50 +01:00
parent 2556f47c2b
commit b48ce43ade
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
6 changed files with 63 additions and 9 deletions

View File

@ -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<AudioBackend> _backend;
@ -298,6 +303,8 @@ private:
void save_port_info ();
void update_input_ports (bool);
MonitorPort _monitor_port;
struct PortID {
PortID (boost::shared_ptr<AudioBackend>, DataType, bool, std::string const&);
PortID (XMLNode const&, bool old_midi_format = false);

View File

@ -922,22 +922,22 @@ public:
/* session-wide solo/mute/rec-enable */
bool muted() const;
bool muted () const;
std::vector<boost::weak_ptr<AutomationControl> > 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<RouteList>);
void prepare_momentary_solo (SoloMuteRelease* smr = NULL, bool exclusive = false, boost::shared_ptr<Route> route = boost::shared_ptr<Route> ());
static const SessionEvent::RTeventCallback rt_cleanup;
/* Control-based methods */
void set_controls (boost::shared_ptr<ControlList>, double val, PBD::Controllable::GroupControlDisposition);

View File

@ -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<AudioInputPorts> aip = _audio_input_ports.reader ();
/* find new audio ports */
@ -898,6 +899,7 @@ PortManager::update_input_ports (bool clear)
} else {
for (std::vector<std::string>::const_iterator p = old_audio.begin(); p != old_audio.end(); ++p) {
apw->erase (*p);
_monitor_port.remove_port (*p, true);
}
}
for (std::vector<std::string>::const_iterator p = new_audio.begin(); p != new_audio.end(); ++p) {
@ -1631,12 +1633,12 @@ PortManager::fill_midi_port_info_locked ()
void
PortManager::set_port_buffer_sizes (pframes_t n)
{
boost::shared_ptr<Ports> 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
@ -1741,6 +1743,9 @@ PortManager::run_input_meters (pframes_t n_samples, samplecnt_t rate)
const float falloff = falloff_cache.calc (n_samples, rate);
std::set<std::string> monitor_portset;
_monitor_port.prepare (monitor_portset);
/* calculate peak of all physical inputs (readable ports) */
std::vector<std::string> port_names;
get_physical_inputs (DataType::AUDIO, port_names);
@ -1769,6 +1774,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 */
@ -1784,6 +1793,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);

View File

@ -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

View File

@ -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<std::list<std::string> > pml (new std::list<std::string>);
_engine.monitor_port().active_monitors (*pml);
smr->set (pml);
}
if (exclusive) {
/* unset any input monitors */
_engine.monitor_port().clear_ports (false);
}
}
}
void

View File

@ -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);
}
}
}