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::Signal1<void, pframes_t> Delivery::CycleStart;
51 PBD::Signal0<int> Delivery::PannersLegal;
52 bool Delivery::panners_legal = false;
54 /* deliver to an existing IO object */
56 Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
57 boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
58 : IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name)
60 , _output_buffers (new BufferSet())
62 , _no_outs_cuz_we_no_monitor (false)
64 , _no_panner_reset (false)
67 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
70 _display_to_user = false;
73 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
76 CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
79 /* deliver to a new IO object */
81 Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
82 : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name)
84 , _output_buffers (new BufferSet())
86 , _no_outs_cuz_we_no_monitor (false)
88 , _no_panner_reset (false)
91 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
94 _display_to_user = false;
97 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
100 CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
104 Delivery::~Delivery()
106 DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
108 /* this object should vanish from any signal callback lists
109 that it is on before we get any further. The full qualification
110 of the method name is not necessary, but is here to make it
111 clear that this call is about signals, not data flow connections.
114 ScopedConnectionList::drop_connections ();
116 delete _output_buffers;
120 Delivery::display_name () const
124 return _("main outs");
137 Delivery::cycle_start (pframes_t /*nframes*/)
139 _no_outs_cuz_we_no_monitor = false;
143 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
147 /* the out buffers will be set to point to the port output buffers
148 of our output object.
152 if (_output->n_ports() != ChanCount::ZERO) {
153 /* increase number of output ports if the processor chain requires it */
154 out = ChanCount::max (_output->n_ports(), in);
157 /* not configured yet - we will passthru */
162 fatal << "programming error: this should never be reached" << endmsg;
167 } else if (_role == Insert) {
169 /* the output buffers will be filled with data from the *input* ports
174 if (_input->n_ports() != ChanCount::ZERO) {
175 out = _input->n_ports();
178 /* not configured yet - we will passthru */
183 fatal << "programming error: this should never be reached" << endmsg;
188 fatal << "programming error: this should never be reached" << endmsg;
194 /** Caller must hold process lock */
196 Delivery::configure_io (ChanCount in, ChanCount out)
198 assert (!AudioEngine::instance()->process_lock().trylock());
200 /* check configuration by comparison with our I/O port configuration, if appropriate.
201 see ::can_support_io_configuration() for comments
207 if (_output->n_ports() != out) {
208 if (_output->n_ports() != ChanCount::ZERO) {
209 _output->ensure_io (out, false, this);
211 /* I/O not yet configured */
216 } else if (_role == Insert) {
219 if (_input->n_ports() != in) {
220 if (_input->n_ports() != ChanCount::ZERO) {
221 fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
224 /* I/O not yet configured */
231 if (!Processor::configure_io (in, out)) {
241 Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
245 PortSet& ports (_output->ports());
248 if (_output->n_ports ().get (_output->default_type()) == 0) {
252 if (!_active && !_pending_active) {
253 _output->silence (nframes);
257 /* this setup is not just for our purposes, but for anything that comes after us in the
258 processing pathway that wants to use this->output_buffers() for some reason.
261 output_buffers().get_jack_port_addresses (ports, nframes);
263 // this Delivery processor is not a derived type, and thus we assume
264 // we really can modify the buffers passed in (it is almost certainly
265 // the main output stage of a Route). Contrast with Send::run()
266 // which cannot do this.
268 tgain = target_gain ();
270 if (tgain != _current_gain) {
271 /* target gain has changed */
273 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
274 _current_gain = tgain;
276 } else if (tgain == 0.0) {
278 /* we were quiet last time, and we're still supposed to be quiet.
279 Silence the outputs, and make sure the buffers are quiet too,
282 _output->silence (nframes);
283 if (result_required) {
284 bufs.set_count (output_buffers().count ());
285 Amp::apply_simple_gain (bufs, nframes, 0.0);
289 } else if (tgain != 1.0) {
291 /* target gain has not changed, but is not unity */
292 Amp::apply_simple_gain (bufs, nframes, tgain);
295 if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
297 // Use the panner to distribute audio to output port buffers
299 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
301 // MIDI data will not have been delivered by the panner
303 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
304 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
309 // Do a 1:1 copy of data to output ports
311 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
312 _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
315 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
316 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
320 if (result_required) {
321 bufs.read_from (output_buffers (), nframes);
325 _active = _pending_active;
329 Delivery::state (bool full_state)
331 XMLNode& node (IOProcessor::state (full_state));
334 node.add_property("type", "main-outs");
335 } else if (_role & Listen) {
336 node.add_property("type", "listen");
338 node.add_property("type", "delivery");
341 node.add_property("role", enum_2_string(_role));
344 node.add_child_nocopy (_panshell->get_state ());
351 Delivery::set_state (const XMLNode& node, int version)
353 const XMLProperty* prop;
355 if (IOProcessor::set_state (node, version)) {
359 if ((prop = node.property ("role")) != 0) {
360 _role = Role (string_2_enum (prop->value(), _role));
361 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
363 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
366 XMLNode* pan_node = node.child (X_("PannerShell"));
368 if (pan_node && _panshell) {
369 _panshell->set_state (*pan_node, version);
380 /* caller must hold process lock */
386 Delivery::pan_outs () const
389 return _output->n_ports().n_audio();
392 return _configured_output.n_audio();
396 Delivery::reset_panner ()
399 if (!_no_panner_reset) {
402 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
405 _panshell->pannable()->set_panner (_panshell->panner());
411 panner_legal_c.disconnect ();
412 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
417 Delivery::panners_became_legal ()
420 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
423 _panshell->pannable()->set_panner (_panshell->panner());
427 panner_legal_c.disconnect ();
432 Delivery::defer_pan_reset ()
434 _no_panner_reset = true;
438 Delivery::allow_pan_reset ()
440 _no_panner_reset = false;
446 Delivery::disable_panners ()
448 panners_legal = false;
453 Delivery::reset_panners ()
455 panners_legal = true;
456 return *PannersLegal ();
460 Delivery::flush_buffers (framecnt_t nframes, framepos_t time)
462 /* io_lock, not taken: function must be called from Session::process() calltree */
468 PortSet& ports (_output->ports());
470 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
471 i->flush_buffers (nframes, time);
476 Delivery::transport_stopped (framepos_t now)
478 Processor::transport_stopped (now);
481 _panshell->pannable()->transport_stopped (now);
485 PortSet& ports (_output->ports());
487 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
488 i->transport_stopped ();
494 Delivery::realtime_locate ()
497 PortSet& ports (_output->ports());
499 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
500 i->realtime_locate ();
506 Delivery::target_gain ()
508 /* if we've been requested to deactivate, our target gain is zero */
510 if (!_pending_active) {
514 /* if we've been told not to output because its a monitoring situation and
515 we're not monitoring, then be quiet.
518 if (_no_outs_cuz_we_no_monitor) {
522 MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
526 mp = MuteMaster::Main;
529 mp = MuteMaster::Listen;
535 mp = MuteMaster::PreFader;
537 mp = MuteMaster::PostFader;
542 gain_t desired_gain = _mute_master->mute_gain_at (mp);
544 if (_role == Listen && _session.monitor_out() && !_session.listening()) {
546 /* nobody is soloed, and this delivery is a listen-send to the
547 control/monitor/listen bus, we should be silent since
548 it gets its signal from the master out.
559 Delivery::no_outs_cuz_we_no_monitor (bool yn)
561 _no_outs_cuz_we_no_monitor = yn;
565 Delivery::set_name (const std::string& name)
567 bool ret = IOProcessor::set_name (name);
570 ret = _panshell->set_name (name);
576 bool ignore_output_change = false;
579 Delivery::output_changed (IOChange change, void* /*src*/)
581 if (change.type & IOChange::ConfigurationChanged) {
583 _output_buffers->attach_buffers (_output->ports ());
587 boost::shared_ptr<Panner>
588 Delivery::panner () const
591 return _panshell->panner();
593 return boost::shared_ptr<Panner>();