X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdelivery.cc;h=80135baf28c0da2d77a49b5469369d7e53904eb8;hb=a406d9183adc67075a4e802fd8254c2560df9964;hp=b132a48960b1ad3771aef3d2589ae9c6fd55faed;hpb=07be98b3410ac70b3c4451592fb88def678611ef;p=ardour.git diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index b132a48960..80135baf28 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -35,6 +35,7 @@ #include "ardour/panner.h" #include "ardour/port.h" #include "ardour/session.h" +#include "ardour/audioengine.h" #include "i18n.h" @@ -42,9 +43,9 @@ using namespace std; using namespace PBD; using namespace ARDOUR; -sigc::signal Delivery::CycleStart; -sigc::signal Delivery::PannersLegal; -bool Delivery::panners_legal = false; +PBD::Signal1 Delivery::CycleStart; +PBD::Signal0 Delivery::PannersLegal; +bool Delivery::panners_legal = false; /* deliver to an existing IO object */ @@ -55,19 +56,17 @@ Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr(new Panner (_name, _session)); + _display_to_user = false; if (_output) { - _output->changed.connect (mem_fun (*this, &Delivery::output_changed)); + _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2)); } - CycleStart.connect (mem_fun (*this, &Delivery::cycle_start)); + CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1)); } /* deliver to a new IO object */ @@ -79,72 +78,23 @@ Delivery::Delivery (Session& s, boost::shared_ptr mm, const string& , _current_gain (1.0) , _output_offset (0) , _no_outs_cuz_we_no_monitor (false) - , _solo_level (0) - , _solo_isolated (false) , _mute_master (mm) , no_panner_reset (false) { _panner = boost::shared_ptr(new Panner (_name, _session)); + _display_to_user = false; if (_output) { - _output->changed.connect (mem_fun (*this, &Delivery::output_changed)); + _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2)); } - CycleStart.connect (mem_fun (*this, &Delivery::cycle_start)); + CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1)); } -/* deliver to a new IO object, reconstruct from XML */ -Delivery::Delivery (Session& s, boost::shared_ptr mm, const XMLNode& node) - : IOProcessor (s, false, true, "reset") - , _role (Role (0)) - , _output_buffers (new BufferSet()) - , _current_gain (1.0) - , _output_offset (0) - , _no_outs_cuz_we_no_monitor (false) - , _solo_level (0) - , _solo_isolated (false) - , _mute_master (mm) - , no_panner_reset (false) +Delivery::~Delivery() { - _panner = boost::shared_ptr(new Panner (_name, _session)); - - if (set_state (node)) { - throw failed_constructor (); - } - - if (_output) { - _output->changed.connect (mem_fun (*this, &Delivery::output_changed)); - } - - CycleStart.connect (mem_fun (*this, &Delivery::cycle_start)); -} - -/* deliver to an existing IO object, reconstruct from XML */ - -Delivery::Delivery (Session& s, boost::shared_ptr out, boost::shared_ptr mm, const XMLNode& node) - : IOProcessor (s, boost::shared_ptr(), out, "reset") - , _role (Role (0)) - , _output_buffers (new BufferSet()) - , _current_gain (1.0) - , _output_offset (0) - , _no_outs_cuz_we_no_monitor (false) - , _solo_level (0) - , _solo_isolated (false) - , _mute_master (mm) - , no_panner_reset (false) -{ - _panner = boost::shared_ptr(new Panner (_name, _session)); - - if (set_state (node)) { - throw failed_constructor (); - } - - if (_output) { - _output->changed.connect (mem_fun (*this, &Delivery::output_changed)); - } - - CycleStart.connect (mem_fun (*this, &Delivery::cycle_start)); + delete _output_buffers; } std::string @@ -165,24 +115,18 @@ Delivery::display_name () const } void -Delivery::cycle_start (nframes_t /*nframes*/) +Delivery::cycle_start (pframes_t /*nframes*/) { _output_offset = 0; _no_outs_cuz_we_no_monitor = false; } void -Delivery::increment_output_offset (nframes_t n) +Delivery::increment_output_offset (framecnt_t n) { _output_offset += n; } -bool -Delivery::visible () const -{ - return true; -} - bool Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const { @@ -194,7 +138,8 @@ Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) con if (_output) { if (_output->n_ports() != ChanCount::ZERO) { - out = _output->n_ports(); + /* increase number of output ports if the processor chain requires it */ + out = ChanCount::max (_output->n_ports(), in); return true; } else { /* not configured yet - we will passthru */ @@ -234,9 +179,12 @@ Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) con return false; } +/** Caller must hold process lock */ bool Delivery::configure_io (ChanCount in, ChanCount out) { + assert (!AudioEngine::instance()->process_lock().trylock()); + /* check configuration by comparison with our I/O port configuration, if appropriate. see ::can_support_io_configuration() for comments */ @@ -246,8 +194,7 @@ Delivery::configure_io (ChanCount in, ChanCount out) if (_output) { if (_output->n_ports() != out) { if (_output->n_ports() != ChanCount::ZERO) { - fatal << _name << " programming error: configure_io with nports = " << _output->n_ports() << " called with " << in << " and " << out << " with " << _output->n_ports() << " output ports" << endmsg; - /*NOTREACHED*/ + _output->ensure_io (out, false, this); } else { /* I/O not yet configured */ } @@ -266,8 +213,9 @@ Delivery::configure_io (ChanCount in, ChanCount out) } } } - } + } + if (!Processor::configure_io (in, out)) { return false; } @@ -278,7 +226,7 @@ Delivery::configure_io (ChanCount in, ChanCount out) } void -Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes) +Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required) { assert (_output); @@ -298,7 +246,7 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra processing pathway that wants to use this->output_buffers() for some reason. */ - output_buffers().attach_buffers (ports, nframes, _output_offset); + output_buffers().get_jack_port_addresses (ports, nframes, _output_offset); // this Delivery processor is not a derived type, and thus we assume // we really can modify the buffers passed in (it is almost certainly @@ -308,7 +256,6 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra tgain = target_gain (); if (tgain != _current_gain) { - /* target gain has changed */ Amp::apply_gain (bufs, nframes, _current_gain, tgain); @@ -321,7 +268,9 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra */ _output->silence (nframes); - Amp::apply_simple_gain (bufs, nframes, 0.0); + if (result_required) { + Amp::apply_simple_gain (bufs, nframes, 0.0); + } goto out; } else if (tgain != 1.0) { @@ -336,16 +285,23 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra _panner->run (bufs, output_buffers(), start_frame, end_frame, nframes); + if (result_required) { + bufs.read_from (output_buffers (), nframes); + } + } else { + // Do a 1:1 copy of data to output ports if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) { _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, _output_offset); - } + } if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) { _output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset); } + + } out: @@ -372,11 +328,11 @@ Delivery::state (bool full_state) } int -Delivery::set_state (const XMLNode& node) +Delivery::set_state (const XMLNode& node, int version) { const XMLProperty* prop; - if (IOProcessor::set_state (node)) { + if (IOProcessor::set_state (node, version)) { return -1; } @@ -390,7 +346,7 @@ Delivery::set_state (const XMLNode& node) XMLNode* pan_node = node.child (X_("Panner")); if (pan_node) { - _panner->set_state (*pan_node); + _panner->set_state (*pan_node, version); } reset_panner (); @@ -416,7 +372,7 @@ Delivery::reset_panner () } } else { panner_legal_c.disconnect (); - panner_legal_c = PannersLegal.connect (mem_fun (*this, &Delivery::panners_became_legal)); + PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this)); } } @@ -462,55 +418,54 @@ int Delivery::reset_panners () { panners_legal = true; - return PannersLegal (); + return *PannersLegal (); } void -Delivery::start_pan_touch (uint32_t which) +Delivery::start_pan_touch (uint32_t which, double when) { if (which < _panner->npanners()) { - _panner->pan_control(which)->start_touch(); + _panner->pan_control(which)->start_touch(when); } } void -Delivery::end_pan_touch (uint32_t which) +Delivery::end_pan_touch (uint32_t which, bool mark, double when) { if (which < _panner->npanners()) { - _panner->pan_control(which)->stop_touch(); + _panner->pan_control(which)->stop_touch(mark, when); } } -void -Delivery::transport_stopped (sframes_t frame) -{ - _panner->transport_stopped (frame); -} void -Delivery::flush (nframes_t nframes, nframes64_t time) +Delivery::flush_buffers (framecnt_t nframes, framepos_t time) { /* io_lock, not taken: function must be called from Session::process() calltree */ PortSet& ports (_output->ports()); - + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { (*i).flush_buffers (nframes, time, _output_offset); } } void -Delivery::transport_stopped () +Delivery::transport_stopped (framepos_t now) { - /* turn off any notes that are on */ + Processor::transport_stopped (now); - PortSet& ports (_output->ports()); + _panner->transport_stopped (now); - for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).transport_stopped (); - } + if (_output) { + PortSet& ports (_output->ports()); + + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { + (*i).transport_stopped (); + } + } } gain_t @@ -530,43 +485,38 @@ Delivery::target_gain () return 0.0; } - gain_t desired_gain; - - if (_solo_level) { - desired_gain = 1.0; - } else { - - MuteMaster::MutePoint mp; - - switch (_role) { - case Main: - mp = MuteMaster::Main; - break; - case Listen: - mp = MuteMaster::Listen; - break; - case Send: - case Insert: - case Aux: - /* XXX FIX ME this is wrong, we need per-delivery muting */ + MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning + + switch (_role) { + case Main: + mp = MuteMaster::Main; + break; + case Listen: + mp = MuteMaster::Listen; + break; + case Send: + case Insert: + case Aux: + if (_pre_fader) { mp = MuteMaster::PreFader; - break; - } - - if (_solo_isolated) { - - /* ... but we are isolated from all that nonsense */ - - desired_gain = _mute_master->mute_gain_at (mp); - - } else if (_session.soloing()) { - - desired_gain = min (Config->get_solo_mute_gain(), _mute_master->mute_gain_at (mp)); - } else { - desired_gain = _mute_master->mute_gain_at (mp); + mp = MuteMaster::PostFader; } - } + break; + } + + gain_t desired_gain = _mute_master->mute_gain_at (mp); + + if (_role == Listen && _session.monitor_out() && !_session.listening()) { + + /* nobody is soloed, and this delivery is a listen-send to the + control/monitor/listen bus, we should be silent since + it gets its signal from the master out. + */ + + desired_gain = 0.0; + + } return desired_gain; } @@ -592,8 +542,8 @@ Delivery::set_name (const std::string& name) void Delivery::output_changed (IOChange change, void* /*src*/) { - if (change & ARDOUR::ConfigurationChanged) { + if (change.type & IOChange::ConfigurationChanged) { reset_panner (); + _output_buffers->attach_buffers (_output->ports ()); } } -