2 Copyright (C) 2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "pbd/enumwriter.h"
23 #include "pbd/convert.h"
25 #include "ardour/midi_buffer.h"
27 #include "ardour/debug.h"
28 #include "ardour/delivery.h"
29 #include "ardour/audio_buffer.h"
30 #include "ardour/audio_port.h"
31 #include "ardour/amp.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/configuration.h"
34 #include "ardour/io.h"
35 #include "ardour/meter.h"
36 #include "ardour/mute_master.h"
37 #include "ardour/panner.h"
38 #include "ardour/panner_shell.h"
39 #include "ardour/pannable.h"
40 #include "ardour/port.h"
41 #include "ardour/session.h"
42 #include "ardour/audioengine.h"
48 using namespace ARDOUR;
50 PBD::Signal0<void> Delivery::PannersLegal;
51 bool Delivery::panners_legal = false;
53 /* deliver to an existing IO object */
55 Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
56 boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
57 : IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name)
59 , _output_buffers (new BufferSet())
61 , _no_outs_cuz_we_no_monitor (false)
63 , _no_panner_reset (false)
66 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
69 _display_to_user = false;
72 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
76 /* deliver to a new IO object */
78 Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
79 : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name)
81 , _output_buffers (new BufferSet())
83 , _no_outs_cuz_we_no_monitor (false)
85 , _no_panner_reset (false)
88 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
91 _display_to_user = false;
94 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
101 DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
103 /* this object should vanish from any signal callback lists
104 that it is on before we get any further. The full qualification
105 of the method name is not necessary, but is here to make it
106 clear that this call is about signals, not data flow connections.
109 ScopedConnectionList::drop_connections ();
111 delete _output_buffers;
115 Delivery::display_name () const
119 return _("main outs");
132 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
136 /* the out buffers will be set to point to the port output buffers
137 of our output object.
141 if (_output->n_ports() != ChanCount::ZERO) {
142 /* increase number of output ports if the processor chain requires it */
143 out = ChanCount::max (_output->n_ports(), in);
146 /* not configured yet - we will passthru */
151 fatal << "programming error: this should never be reached" << endmsg;
156 } else if (_role == Insert) {
158 /* the output buffers will be filled with data from the *input* ports
163 if (_input->n_ports() != ChanCount::ZERO) {
164 out = _input->n_ports();
167 /* not configured yet - we will passthru */
172 fatal << "programming error: this should never be reached" << endmsg;
177 fatal << "programming error: this should never be reached" << endmsg;
183 /** Caller must hold process lock */
185 Delivery::configure_io (ChanCount in, ChanCount out)
187 assert (!AudioEngine::instance()->process_lock().trylock());
189 /* check configuration by comparison with our I/O port configuration, if appropriate.
190 see ::can_support_io_configuration() for comments
196 if (_output->n_ports() != out) {
197 if (_output->n_ports() != ChanCount::ZERO) {
198 _output->ensure_io (out, false, this);
200 /* I/O not yet configured */
205 } else if (_role == Insert) {
208 if (_input->n_ports() != in) {
209 if (_input->n_ports() != ChanCount::ZERO) {
210 fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
213 /* I/O not yet configured */
220 if (!Processor::configure_io (in, out)) {
230 Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
234 PortSet& ports (_output->ports());
237 if (_output->n_ports ().get (_output->default_type()) == 0) {
241 if (!_active && !_pending_active) {
242 _output->silence (nframes);
246 /* this setup is not just for our purposes, but for anything that comes after us in the
247 processing pathway that wants to use this->output_buffers() for some reason.
250 output_buffers().get_jack_port_addresses (ports, nframes);
252 // this Delivery processor is not a derived type, and thus we assume
253 // we really can modify the buffers passed in (it is almost certainly
254 // the main output stage of a Route). Contrast with Send::run()
255 // which cannot do this.
257 tgain = target_gain ();
259 if (tgain != _current_gain) {
260 /* target gain has changed */
262 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
263 _current_gain = tgain;
265 } else if (tgain == 0.0) {
267 /* we were quiet last time, and we're still supposed to be quiet.
268 Silence the outputs, and make sure the buffers are quiet too,
271 _output->silence (nframes);
272 if (result_required) {
273 bufs.set_count (output_buffers().count ());
274 Amp::apply_simple_gain (bufs, nframes, 0.0);
278 } else if (tgain != 1.0) {
280 /* target gain has not changed, but is not unity */
281 Amp::apply_simple_gain (bufs, nframes, tgain);
284 if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
286 // Use the panner to distribute audio to output port buffers
288 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
290 // MIDI data will not have been delivered by the panner
292 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
293 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
298 // Do a 1:1 copy of data to output ports
300 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
301 _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
304 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
305 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
309 if (result_required) {
310 bufs.read_from (output_buffers (), nframes);
314 _active = _pending_active;
318 Delivery::state (bool full_state)
320 XMLNode& node (IOProcessor::state (full_state));
323 node.add_property("type", "main-outs");
324 } else if (_role & Listen) {
325 node.add_property("type", "listen");
327 node.add_property("type", "delivery");
330 node.add_property("role", enum_2_string(_role));
333 node.add_child_nocopy (_panshell->get_state ());
340 Delivery::set_state (const XMLNode& node, int version)
342 const XMLProperty* prop;
344 if (IOProcessor::set_state (node, version)) {
348 if ((prop = node.property ("role")) != 0) {
349 _role = Role (string_2_enum (prop->value(), _role));
350 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
352 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
355 XMLNode* pan_node = node.child (X_("PannerShell"));
357 if (pan_node && _panshell) {
358 _panshell->set_state (*pan_node, version);
369 /* caller must hold process lock */
375 Delivery::pan_outs () const
378 return _output->n_ports().n_audio();
381 return _configured_output.n_audio();
385 Delivery::reset_panner ()
388 if (!_no_panner_reset) {
391 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
394 _panshell->pannable()->set_panner (_panshell->panner());
400 panner_legal_c.disconnect ();
401 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
406 Delivery::panners_became_legal ()
409 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
412 _panshell->pannable()->set_panner (_panshell->panner());
416 panner_legal_c.disconnect ();
420 Delivery::defer_pan_reset ()
422 _no_panner_reset = true;
426 Delivery::allow_pan_reset ()
428 _no_panner_reset = false;
434 Delivery::disable_panners ()
436 panners_legal = false;
441 Delivery::reset_panners ()
443 panners_legal = true;
448 Delivery::flush_buffers (framecnt_t nframes)
450 /* io_lock, not taken: function must be called from Session::process() calltree */
456 PortSet& ports (_output->ports());
458 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
459 i->flush_buffers (nframes);
464 Delivery::transport_stopped (framepos_t now)
466 Processor::transport_stopped (now);
469 _panshell->pannable()->transport_stopped (now);
473 PortSet& ports (_output->ports());
475 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
476 i->transport_stopped ();
482 Delivery::realtime_locate ()
485 PortSet& ports (_output->ports());
487 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
488 i->realtime_locate ();
494 Delivery::target_gain ()
496 /* if we've been requested to deactivate, our target gain is zero */
498 if (!_pending_active) {
502 /* if we've been told not to output because its a monitoring situation and
503 we're not monitoring, then be quiet.
506 if (_no_outs_cuz_we_no_monitor) {
510 MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
514 mp = MuteMaster::Main;
517 mp = MuteMaster::Listen;
523 mp = MuteMaster::PreFader;
525 mp = MuteMaster::PostFader;
530 gain_t desired_gain = _mute_master->mute_gain_at (mp);
532 if (_role == Listen && _session.monitor_out() && !_session.listening()) {
534 /* nobody is soloed, and this delivery is a listen-send to the
535 control/monitor/listen bus, we should be silent since
536 it gets its signal from the master out.
547 Delivery::no_outs_cuz_we_no_monitor (bool yn)
549 _no_outs_cuz_we_no_monitor = yn;
553 Delivery::set_name (const std::string& name)
555 bool ret = IOProcessor::set_name (name);
558 ret = _panshell->set_name (name);
564 bool ignore_output_change = false;
567 Delivery::output_changed (IOChange change, void* /*src*/)
569 if (change.type & IOChange::ConfigurationChanged) {
571 _output_buffers->attach_buffers (_output->ports ());
575 boost::shared_ptr<Panner>
576 Delivery::panner () const
579 return _panshell->panner();
581 return boost::shared_ptr<Panner>();