X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdelivery.cc;h=c7ce380a48a34822e48429ed80453560324449cf;hb=60872a8504cccc0d7e6c2485af8c0362577f5723;hp=efdb4d9ad0a354f4540a7c539727aacc916999dc;hpb=ca84e02b48e0c36755963a35713d272c409d9317;p=ardour.git diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index efdb4d9ad0..c7ce380a48 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -53,7 +53,7 @@ bool Delivery::panners_legal = false; /* deliver to an existing IO object */ -Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr pannable, +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) @@ -61,10 +61,12 @@ Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr(new PannerShell (_name, _session, pannable)); + if (pannable) { + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + } + _display_to_user = false; if (_output) { @@ -83,10 +85,12 @@ Delivery::Delivery (Session& s, boost::shared_ptr pannable, boost::sha , _current_gain (1.0) , _no_outs_cuz_we_no_monitor (false) , _mute_master (mm) - , no_panner_reset (false) - , scnt (0) + , _no_panner_reset (false) { - _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + if (pannable) { + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + } + _display_to_user = false; if (_output) { @@ -99,7 +103,16 @@ Delivery::Delivery (Session& s, boost::shared_ptr pannable, boost::sha Delivery::~Delivery() { - DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name)); + DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name)); + + /* this object should vanish from any signal callback lists + that it is on before we get any further. The full qualification + of the method name is not necessary, but is here to make it + clear that this call is about signals, not data flow connections. + */ + + ScopedConnectionList::drop_connections (); + delete _output_buffers; } @@ -214,7 +227,7 @@ Delivery::configure_io (ChanCount in, ChanCount out) } } - + if (!Processor::configure_io (in, out)) { return false; } @@ -227,8 +240,6 @@ Delivery::configure_io (ChanCount in, ChanCount out) void Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required) { - boost::shared_ptr panner; - assert (_output); PortSet& ports (_output->ports()); @@ -270,6 +281,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf _output->silence (nframes); if (result_required) { + bufs.set_count (output_buffers().count ()); Amp::apply_simple_gain (bufs, nframes, 0.0); } goto out; @@ -280,29 +292,17 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf Amp::apply_simple_gain (bufs, nframes, tgain); } - panner = _panshell->panner(); - -#if 0 - if (_session.transport_rolling()) { - cerr << name() << " first value written : " << scnt << endl; - for (BufferSet::audio_iterator b = bufs.audio_begin(); b != bufs.audio_end(); ++b) { - Sample* p = b->data (); - float s = (float) scnt; - for (pframes_t n = 0; n < nframes; ++n) { - p[n] = s * 0.001; - s += 1.0; - } - } - scnt += nframes; - } -#endif + if (_panshell && !_panshell->bypassed() && _panshell->panner()) { - if (panner && !panner->bypassed()) { - // Use the panner to distribute audio to output port buffers _panshell->run (bufs, output_buffers(), start_frame, end_frame, 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 { @@ -339,7 +339,10 @@ Delivery::state (bool full_state) } node.add_property("role", enum_2_string(_role)); - node.add_child_nocopy (_panshell->state (full_state)); + + if (_panshell) { + node.add_child_nocopy (_panshell->get_state ()); + } return node; } @@ -360,9 +363,9 @@ 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) { + if (pan_node && _panshell) { _panshell->set_state (*pan_node, version); } @@ -372,29 +375,36 @@ Delivery::set_state (const XMLNode& node, int version) } void -Delivery::reset_panner () +Delivery::unpan () { - if (_role == Listen) { - /* monitor out gets no panner */ - return; - } + /* caller must hold process lock */ - if (panners_legal) { - if (!no_panner_reset) { + _panshell.reset (); +} - uint32_t ntargets; +uint32_t +Delivery::pan_outs () const +{ + if (_output) { + return _output->n_ports().n_audio(); + } - if (_output) { - ntargets = _output->n_ports().n_audio(); - } else { - ntargets = _configured_output.n_audio(); - } + return _configured_output.n_audio(); +} - _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, ntargets)); +void +Delivery::reset_panner () +{ + if (panners_legal) { + if (!_no_panner_reset) { - if (_role == Main) { - _panshell->pannable()->set_panner (_panshell->panner()); - } + if (_panshell) { + _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs())); + + if (_role == Main) { + _panshell->pannable()->set_panner (_panshell->panner()); + } + } } } else { @@ -406,20 +416,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()); + } } - _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, ntargets)); - - if (_role == Main) { - _panshell->pannable()->set_panner (_panshell->panner()); - } - panner_legal_c.disconnect (); return 0; } @@ -427,19 +431,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; @@ -457,10 +461,14 @@ 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); + i->flush_buffers (nframes, time); } } @@ -468,13 +476,28 @@ void Delivery::transport_stopped (framepos_t now) { Processor::transport_stopped (now); - _panshell->pannable()->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 (); + i->transport_stopped (); + } + } +} + +void +Delivery::realtime_locate () +{ + if (_output) { + PortSet& ports (_output->ports()); + + for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { + i->realtime_locate (); } } } @@ -497,7 +520,7 @@ Delivery::target_gain () } MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning - + switch (_role) { case Main: mp = MuteMaster::Main; @@ -517,17 +540,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; } @@ -550,6 +573,8 @@ Delivery::set_name (const std::string& name) return ret; } +bool ignore_output_change = false; + void Delivery::output_changed (IOChange change, void* /*src*/) { @@ -562,5 +587,10 @@ Delivery::output_changed (IOChange change, void* /*src*/) boost::shared_ptr Delivery::panner () const { - return _panshell->panner(); + if (_panshell) { + return _panshell->panner(); + } else { + return boost::shared_ptr(); + } } +