Implement Input Monitoring
This commit is contained in:
parent
2556f47c2b
commit
b48ce43ade
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "ardour/chan_count.h"
|
#include "ardour/chan_count.h"
|
||||||
#include "ardour/midiport_manager.h"
|
#include "ardour/midiport_manager.h"
|
||||||
|
#include "ardour/monitor_port.h"
|
||||||
#include "ardour/port.h"
|
#include "ardour/port.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
@ -251,6 +252,10 @@ public:
|
||||||
AudioInputPorts audio_input_ports () const;
|
AudioInputPorts audio_input_ports () const;
|
||||||
MIDIInputPorts midi_input_ports () const;
|
MIDIInputPorts midi_input_ports () const;
|
||||||
|
|
||||||
|
MonitorPort& monitor_port () {
|
||||||
|
return _monitor_port;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boost::shared_ptr<AudioBackend> _backend;
|
boost::shared_ptr<AudioBackend> _backend;
|
||||||
|
|
||||||
|
@ -298,6 +303,8 @@ private:
|
||||||
void save_port_info ();
|
void save_port_info ();
|
||||||
void update_input_ports (bool);
|
void update_input_ports (bool);
|
||||||
|
|
||||||
|
MonitorPort _monitor_port;
|
||||||
|
|
||||||
struct PortID {
|
struct PortID {
|
||||||
PortID (boost::shared_ptr<AudioBackend>, DataType, bool, std::string const&);
|
PortID (boost::shared_ptr<AudioBackend>, DataType, bool, std::string const&);
|
||||||
PortID (XMLNode const&, bool old_midi_format = false);
|
PortID (XMLNode const&, bool old_midi_format = false);
|
||||||
|
|
|
@ -922,22 +922,22 @@ public:
|
||||||
|
|
||||||
/* session-wide solo/mute/rec-enable */
|
/* session-wide solo/mute/rec-enable */
|
||||||
|
|
||||||
bool muted() const;
|
bool muted () const;
|
||||||
std::vector<boost::weak_ptr<AutomationControl> > cancel_all_mute ();
|
std::vector<boost::weak_ptr<AutomationControl> > cancel_all_mute ();
|
||||||
|
|
||||||
bool soloing() const { return _non_soloed_outs_muted; }
|
bool soloing () const { return _non_soloed_outs_muted; }
|
||||||
bool listening() const { return _listen_cnt > 0; }
|
bool listening () const;
|
||||||
bool solo_isolated() const { return _solo_isolated_cnt > 0; }
|
bool solo_isolated () const { return _solo_isolated_cnt > 0; }
|
||||||
void cancel_all_solo ();
|
void cancel_all_solo ();
|
||||||
|
|
||||||
bool solo_selection_active();
|
bool solo_selection_active ();
|
||||||
void solo_selection( StripableList&, bool );
|
void solo_selection (StripableList&, bool);
|
||||||
|
|
||||||
static const SessionEvent::RTeventCallback rt_cleanup;
|
|
||||||
|
|
||||||
void clear_all_solo_state (boost::shared_ptr<RouteList>);
|
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> ());
|
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 */
|
/* Control-based methods */
|
||||||
|
|
||||||
void set_controls (boost::shared_ptr<ControlList>, double val, PBD::Controllable::GroupControlDisposition);
|
void set_controls (boost::shared_ptr<ControlList>, double val, PBD::Controllable::GroupControlDisposition);
|
||||||
|
|
|
@ -852,6 +852,7 @@ PortManager::update_input_ports (bool clear)
|
||||||
if (clear) {
|
if (clear) {
|
||||||
new_audio = audio_ports;
|
new_audio = audio_ports;
|
||||||
new_midi = midi_ports;
|
new_midi = midi_ports;
|
||||||
|
_monitor_port.clear_ports (true);
|
||||||
} else {
|
} else {
|
||||||
boost::shared_ptr<AudioInputPorts> aip = _audio_input_ports.reader ();
|
boost::shared_ptr<AudioInputPorts> aip = _audio_input_ports.reader ();
|
||||||
/* find new audio ports */
|
/* find new audio ports */
|
||||||
|
@ -898,6 +899,7 @@ PortManager::update_input_ports (bool clear)
|
||||||
} else {
|
} else {
|
||||||
for (std::vector<std::string>::const_iterator p = old_audio.begin(); p != old_audio.end(); ++p) {
|
for (std::vector<std::string>::const_iterator p = old_audio.begin(); p != old_audio.end(); ++p) {
|
||||||
apw->erase (*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) {
|
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
|
void
|
||||||
PortManager::set_port_buffer_sizes (pframes_t n)
|
PortManager::set_port_buffer_sizes (pframes_t n)
|
||||||
{
|
{
|
||||||
|
|
||||||
boost::shared_ptr<Ports> all = ports.reader();
|
boost::shared_ptr<Ports> all = ports.reader();
|
||||||
|
|
||||||
for (Ports::iterator p = all->begin(); p != all->end(); ++p) {
|
for (Ports::iterator p = all->begin(); p != all->end(); ++p) {
|
||||||
p->second->set_buffer_size (n);
|
p->second->set_buffer_size (n);
|
||||||
}
|
}
|
||||||
|
_monitor_port.set_buffer_size (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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);
|
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) */
|
/* calculate peak of all physical inputs (readable ports) */
|
||||||
std::vector<std::string> port_names;
|
std::vector<std::string> port_names;
|
||||||
get_physical_inputs (DataType::AUDIO, 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (monitor_portset.find (*p) != monitor_portset.end ()) {
|
||||||
|
_monitor_port.monitor (buf, n_samples, *p);
|
||||||
|
}
|
||||||
|
|
||||||
ai->second.scope->write (buf, n_samples);
|
ai->second.scope->write (buf, n_samples);
|
||||||
|
|
||||||
/* falloff */
|
/* 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);
|
ai->second.meter->peak = std::max (ai->second.meter->peak, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_monitor_port.finalize (n_samples);
|
||||||
|
|
||||||
/* MIDI */
|
/* MIDI */
|
||||||
port_names.clear ();
|
port_names.clear ();
|
||||||
get_physical_inputs (DataType::MIDI, port_names);
|
get_physical_inputs (DataType::MIDI, port_names);
|
||||||
|
|
|
@ -987,6 +987,7 @@ Session::remove_monitor_section ()
|
||||||
|
|
||||||
if (!deletion_in_progress ()) {
|
if (!deletion_in_progress ()) {
|
||||||
setup_route_monitor_sends (false, true);
|
setup_route_monitor_sends (false, true);
|
||||||
|
_engine.monitor_port().clear_ports (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_route (_monitor_out);
|
remove_route (_monitor_out);
|
||||||
|
@ -3549,6 +3550,8 @@ Session::route_listen_changed (Controllable::GroupControlDisposition group_overr
|
||||||
|
|
||||||
if (Config->get_exclusive_solo()) {
|
if (Config->get_exclusive_solo()) {
|
||||||
|
|
||||||
|
_engine.monitor_port().clear_ports (false);
|
||||||
|
|
||||||
RouteGroup* rg = route->route_group ();
|
RouteGroup* rg = route->route_group ();
|
||||||
const bool group_already_accounted_for = (group_override == Controllable::ForGroup);
|
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()) {
|
if (delta == 1 && Config->get_exclusive_solo()) {
|
||||||
|
|
||||||
/* new solo: disable all other solos, but not the group if its solo-enabled */
|
/* 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) {
|
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);
|
set_controls (stripable_list_to_control_list (sl, &Stripable::solo_control), 0.0, Controllable::NoGroup);
|
||||||
clear_all_solo_state (routes.reader());
|
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
|
void
|
||||||
|
|
|
@ -119,6 +119,18 @@ Session::prepare_momentary_solo (SoloMuteRelease* smr, bool exclusive, boost::sh
|
||||||
if (smr) {
|
if (smr) {
|
||||||
smr->set (routes_on, routes_off);
|
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
|
void
|
||||||
|
|
|
@ -83,5 +83,9 @@ SoloMuteRelease::release (Session* s, bool mute) const
|
||||||
} else {
|
} 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_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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user