X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdelivery.cc;h=f9ff3be83e3a635e2a155a337cda00532293e719;hb=fa40fb2d98db1a854f00a911857149db5ec414c2;hp=700efd8ac1eae88e52036f5e456c2e4b62431e04;hpb=54cbc45a5a40f4eefd64fa41ad9029f5f8f6a84f;p=ardour.git diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 700efd8ac1..f9ff3be83e 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -24,8 +24,10 @@ #include "ardour/midi_buffer.h" +#include "ardour/debug.h" #include "ardour/delivery.h" #include "ardour/audio_buffer.h" +#include "ardour/audio_port.h" #include "ardour/amp.h" #include "ardour/buffer_set.h" #include "ardour/configuration.h" @@ -33,6 +35,8 @@ #include "ardour/meter.h" #include "ardour/mute_master.h" #include "ardour/panner.h" +#include "ardour/panner_shell.h" +#include "ardour/pannable.h" #include "ardour/port.h" #include "ardour/session.h" #include "ardour/audioengine.h" @@ -43,23 +47,26 @@ using namespace std; using namespace PBD; using namespace ARDOUR; -PBD::Signal1 Delivery::CycleStart; -PBD::Signal0 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 */ -Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr mm, const string& name, Role r) +Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr pannable, + boost::shared_ptr mm, const string& name, Role r) : IOProcessor(s, boost::shared_ptr(), (role_requires_output_ports (r) ? io : boost::shared_ptr()), name) , _role (r) , _output_buffers (new BufferSet()) , _current_gain (1.0) - , _output_offset (0) , _no_outs_cuz_we_no_monitor (false) , _mute_master (mm) - , no_panner_reset (false) + , _no_panner_reset (false) { - _panner = boost::shared_ptr(new Panner (_name, _session)); + if (pannable) { + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + } + _display_to_user = false; if (_output) { @@ -71,17 +78,19 @@ Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr mm, const string& name, Role r) +Delivery::Delivery (Session& s, boost::shared_ptr pannable, boost::shared_ptr mm, const string& name, Role r) : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name) , _role (r) , _output_buffers (new BufferSet()) , _current_gain (1.0) - , _output_offset (0) , _no_outs_cuz_we_no_monitor (false) , _mute_master (mm) - , no_panner_reset (false) + , _no_panner_reset (false) { - _panner = boost::shared_ptr(new Panner (_name, _session)); + if (pannable) { + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + } + _display_to_user = false; if (_output) { @@ -94,6 +103,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr mm, const string& Delivery::~Delivery() { + DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name)); delete _output_buffers; } @@ -115,18 +125,11 @@ 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) -{ - _output_offset += n; -} - bool Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const { @@ -215,7 +218,7 @@ Delivery::configure_io (ChanCount in, ChanCount out) } } - + if (!Processor::configure_io (in, out)) { return false; } @@ -226,7 +229,7 @@ Delivery::configure_io (ChanCount in, ChanCount out) } void -Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, nframes_t nframes, bool result_required) +Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required) { assert (_output); @@ -246,7 +249,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, nf 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); // this Delivery processor is not a derived type, and thus we assume // we really can modify the buffers passed in (it is almost certainly @@ -269,6 +272,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, nf _output->silence (nframes); if (result_required) { + bufs.set_count (output_buffers().count ()); Amp::apply_simple_gain (bufs, nframes, 0.0); } goto out; @@ -279,14 +283,16 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, nf Amp::apply_simple_gain (bufs, nframes, tgain); } - if (_panner && _panner->npanners() && !_panner->bypassed()) { + if (_panshell && !_panshell->bypassed() && _panshell->panner()) { // Use the panner to distribute audio to output port buffers - _panner->run (bufs, output_buffers(), start_frame, end_frame, nframes); + _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes); - if (result_required) { - bufs.read_from (output_buffers (), nframes); + // MIDI data will not have been delivered by the panner + + if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) { + _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0); } } else { @@ -294,16 +300,18 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, nf // 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); + _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0); } if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) { - _output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset); + _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0); } - - } + if (result_required) { + bufs.read_from (output_buffers (), nframes); + } + out: _active = _pending_active; } @@ -322,7 +330,10 @@ Delivery::state (bool full_state) } node.add_property("role", enum_2_string(_role)); - node.add_child_nocopy (_panner->state (full_state)); + + if (_panshell) { + node.add_child_nocopy (_panshell->get_state ()); + } return node; } @@ -343,10 +354,10 @@ Delivery::set_state (const XMLNode& node, int version) // std::cerr << this << ' ' << _name << " NO ROLE INFO\n"; } - XMLNode* pan_node = node.child (X_("Panner")); + XMLNode* pan_node = node.child (X_("PannerShell")); - if (pan_node) { - _panner->set_state (*pan_node, version); + if (pan_node && _panshell) { + _panshell->set_state (*pan_node, version); } reset_panner (); @@ -354,22 +365,39 @@ Delivery::set_state (const XMLNode& node, int version) return 0; } +void +Delivery::unpan () +{ + /* caller must hold process lock */ + + _panshell.reset (); +} + +uint32_t +Delivery::pan_outs () const +{ + if (_output) { + return _output->n_ports().n_audio(); + } + + return _configured_output.n_audio(); +} + void Delivery::reset_panner () { if (panners_legal) { - if (!no_panner_reset) { + if (!_no_panner_reset) { - uint32_t ntargets; - - if (_output) { - ntargets = _output->n_ports().n_audio(); - } else { - ntargets = _configured_output.n_audio(); + if (_panshell) { + _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs())); + + if (_role == Main) { + _panshell->pannable()->set_panner (_panshell->panner()); + } } - - _panner->reset (ntargets, pans_required()); } + } else { panner_legal_c.disconnect (); PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this)); @@ -379,16 +407,14 @@ Delivery::reset_panner () int Delivery::panners_became_legal () { - uint32_t ntargets; - - if (_output) { - ntargets = _output->n_ports().n_audio(); - } else { - ntargets = _configured_output.n_audio(); + if (_panshell) { + _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs())); + + if (_role == Main) { + _panshell->pannable()->set_panner (_panshell->panner()); + } } - _panner->reset (ntargets, pans_required()); - _panner->load (); // automation panner_legal_c.disconnect (); return 0; } @@ -396,19 +422,19 @@ Delivery::panners_became_legal () void Delivery::defer_pan_reset () { - no_panner_reset = true; + _no_panner_reset = true; } void Delivery::allow_pan_reset () { - no_panner_reset = false; + _no_panner_reset = false; reset_panner (); } int -Delivery::disable_panners (void) +Delivery::disable_panners () { panners_legal = false; return 0; @@ -421,34 +447,19 @@ Delivery::reset_panners () return *PannersLegal (); } - -void -Delivery::start_pan_touch (uint32_t which, double when) -{ - if (which < _panner->npanners()) { - _panner->pan_control(which)->start_touch(when); - } -} - void -Delivery::end_pan_touch (uint32_t which, bool mark, double when) -{ - if (which < _panner->npanners()) { - _panner->pan_control(which)->stop_touch(mark, when); - } - -} - - -void -Delivery::flush_buffers (nframes_t nframes, framepos_t time) +Delivery::flush_buffers (framecnt_t nframes, framepos_t time) { /* io_lock, not taken: function must be called from Session::process() calltree */ + if (!_output) { + return; + } + PortSet& ports (_output->ports()); - + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).flush_buffers (nframes, time, _output_offset); + i->flush_buffers (nframes, time); } } @@ -457,13 +468,27 @@ Delivery::transport_stopped (framepos_t now) { Processor::transport_stopped (now); - _panner->transport_stopped (now); + if (_panshell) { + _panshell->pannable()->transport_stopped (now); + } + + if (_output) { + PortSet& ports (_output->ports()); + + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { + i->transport_stopped (); + } + } +} +void +Delivery::realtime_locate () +{ if (_output) { PortSet& ports (_output->ports()); - + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).transport_stopped (); + i->realtime_locate (); } } } @@ -486,7 +511,7 @@ Delivery::target_gain () } MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning - + switch (_role) { case Main: mp = MuteMaster::Main; @@ -506,17 +531,17 @@ Delivery::target_gain () } 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; } @@ -533,17 +558,30 @@ Delivery::set_name (const std::string& name) bool ret = IOProcessor::set_name (name); if (ret) { - ret = _panner->set_name (name); + ret = _panshell->set_name (name); } return ret; } +bool ignore_output_change = false; + void Delivery::output_changed (IOChange change, void* /*src*/) { if (change.type & IOChange::ConfigurationChanged) { reset_panner (); + _output_buffers->attach_buffers (_output->ports ()); + } +} + +boost::shared_ptr +Delivery::panner () const +{ + if (_panshell) { + return _panshell->panner(); + } else { + return boost::shared_ptr(); } }