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/amp.h"
26 #include "ardour/audioengine.h"
27 #include "ardour/buffer_set.h"
28 #include "ardour/debug.h"
29 #include "ardour/delivery.h"
30 #include "ardour/io.h"
31 #include "ardour/mute_master.h"
32 #include "ardour/pannable.h"
33 #include "ardour/panner_shell.h"
34 #include "ardour/port.h"
35 #include "ardour/session.h"
39 namespace ARDOUR { class Panner; }
43 using namespace ARDOUR;
45 PBD::Signal0<void> Delivery::PannersLegal;
46 bool Delivery::panners_legal = false;
48 /* deliver to an existing IO object */
50 Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
51 boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
52 : IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name)
54 , _output_buffers (new BufferSet())
56 , _no_outs_cuz_we_no_monitor (false)
58 , _no_panner_reset (false)
61 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
64 _display_to_user = false;
67 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
71 /* deliver to a new IO object */
73 Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
74 : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name, "", DataType::AUDIO, (r == Send))
76 , _output_buffers (new BufferSet())
78 , _no_outs_cuz_we_no_monitor (false)
80 , _no_panner_reset (false)
83 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
86 _display_to_user = false;
89 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
96 DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
98 /* this object should vanish from any signal callback lists
99 that it is on before we get any further. The full qualification
100 of the method name is not necessary, but is here to make it
101 clear that this call is about signals, not data flow connections.
104 ScopedConnectionList::drop_connections ();
106 delete _output_buffers;
110 Delivery::display_name () const
114 return _("main outs");
127 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out)
131 /* the out buffers will be set to point to the port output buffers
132 of our output object.
136 if (_output->n_ports() != ChanCount::ZERO) {
137 /* increase number of output ports if the processor chain requires it */
138 out = ChanCount::max (_output->n_ports(), in);
141 /* not configured yet - we will passthru */
146 fatal << "programming error: this should never be reached" << endmsg;
151 } else if (_role == Insert) {
153 /* the output buffers will be filled with data from the *input* ports
158 if (_input->n_ports() != ChanCount::ZERO) {
159 out = _input->n_ports();
162 /* not configured yet - we will passthru */
167 fatal << "programming error: this should never be reached" << endmsg;
172 fatal << "programming error: this should never be reached" << endmsg;
178 /** Caller must hold process lock */
180 Delivery::configure_io (ChanCount in, ChanCount out)
183 bool r = AudioEngine::instance()->process_lock().trylock();
184 assert (!r && "trylock inside Delivery::configure_io");
187 /* check configuration by comparison with our I/O port configuration, if appropriate.
188 see ::can_support_io_configuration() for comments
194 if (_output->n_ports() != out) {
195 if (_output->n_ports() != ChanCount::ZERO) {
196 _output->ensure_io (out, false, this);
198 /* I/O not yet configured */
203 } else if (_role == Insert) {
206 if (_input->n_ports() != in) {
207 if (_input->n_ports() != ChanCount::ZERO) {
208 fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
211 /* I/O not yet configured */
218 if (!Processor::configure_io (in, out)) {
228 Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
232 PortSet& ports (_output->ports());
235 if (_output->n_ports ().get (_output->default_type()) == 0) {
239 if (!_active && !_pending_active) {
240 _output->silence (nframes);
244 /* this setup is not just for our purposes, but for anything that comes after us in the
245 processing pathway that wants to use this->output_buffers() for some reason.
248 output_buffers().get_backend_port_addresses (ports, nframes);
250 // this Delivery processor is not a derived type, and thus we assume
251 // we really can modify the buffers passed in (it is almost certainly
252 // the main output stage of a Route). Contrast with Send::run()
253 // which cannot do this.
255 tgain = target_gain ();
257 if (tgain != _current_gain) {
258 /* target gain has changed */
260 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
261 _current_gain = tgain;
263 } else if (tgain == 0.0) {
265 /* we were quiet last time, and we're still supposed to be quiet.
266 Silence the outputs, and make sure the buffers are quiet too,
269 _output->silence (nframes);
270 if (result_required) {
271 bufs.set_count (output_buffers().count ());
272 Amp::apply_simple_gain (bufs, nframes, 0.0);
276 } else if (tgain != 1.0) {
278 /* target gain has not changed, but is not unity */
279 Amp::apply_simple_gain (bufs, nframes, tgain);
282 if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
284 // Use the panner to distribute audio to output port buffers
286 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
288 // MIDI data will not have been delivered by the panner
290 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
291 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
296 // Do a 1:1 copy of data to output ports
298 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
299 _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
302 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
303 _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
307 if (result_required) {
308 bufs.read_from (output_buffers (), nframes);
312 _active = _pending_active;
316 Delivery::state (bool full_state)
318 XMLNode& node (IOProcessor::state (full_state));
321 node.add_property("type", "main-outs");
322 } else if (_role & Listen) {
323 node.add_property("type", "listen");
325 node.add_property("type", "delivery");
328 node.add_property("role", enum_2_string(_role));
331 node.add_child_nocopy (_panshell->get_state ());
338 Delivery::set_state (const XMLNode& node, int version)
340 const XMLProperty* prop;
342 if (IOProcessor::set_state (node, version)) {
346 if ((prop = node.property ("role")) != 0) {
347 _role = Role (string_2_enum (prop->value(), _role));
348 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
350 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
353 XMLNode* pan_node = node.child (X_("PannerShell"));
355 if (pan_node && _panshell) {
356 _panshell->set_state (*pan_node, version);
367 /* caller must hold process lock */
373 Delivery::pan_outs () const
376 return _output->n_ports().n_audio();
379 return _configured_output.n_audio();
383 Delivery::reset_panner ()
386 if (!_no_panner_reset) {
389 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
392 _panshell->pannable()->set_panner (_panshell->panner());
398 panner_legal_c.disconnect ();
399 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
404 Delivery::panners_became_legal ()
407 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
410 _panshell->pannable()->set_panner (_panshell->panner());
414 panner_legal_c.disconnect ();
418 Delivery::defer_pan_reset ()
420 _no_panner_reset = true;
424 Delivery::allow_pan_reset ()
426 _no_panner_reset = false;
432 Delivery::disable_panners ()
434 panners_legal = false;
439 Delivery::reset_panners ()
441 panners_legal = true;
446 Delivery::flush_buffers (framecnt_t nframes)
448 /* io_lock, not taken: function must be called from Session::process() calltree */
454 PortSet& ports (_output->ports());
456 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
457 i->flush_buffers (nframes);
462 Delivery::transport_stopped (framepos_t now)
464 Processor::transport_stopped (now);
467 _panshell->pannable()->transport_stopped (now);
471 PortSet& ports (_output->ports());
473 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
474 i->transport_stopped ();
480 Delivery::realtime_locate ()
483 PortSet& ports (_output->ports());
485 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
486 i->realtime_locate ();
492 Delivery::target_gain ()
494 /* if we've been requested to deactivate, our target gain is zero */
496 if (!_pending_active) {
500 /* if we've been told not to output because its a monitoring situation and
501 we're not monitoring, then be quiet.
504 if (_no_outs_cuz_we_no_monitor) {
508 MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
512 mp = MuteMaster::Main;
515 mp = MuteMaster::Listen;
521 mp = MuteMaster::PreFader;
523 mp = MuteMaster::PostFader;
528 gain_t desired_gain = _mute_master->mute_gain_at (mp);
530 if (_role == Listen && _session.monitor_out() && !_session.listening()) {
532 /* nobody is soloed, and this delivery is a listen-send to the
533 control/monitor/listen bus, we should be silent since
534 it gets its signal from the master out.
545 Delivery::no_outs_cuz_we_no_monitor (bool yn)
547 _no_outs_cuz_we_no_monitor = yn;
551 Delivery::set_name (const std::string& name)
553 bool ret = IOProcessor::set_name (name);
556 ret = _panshell->set_name (name);
562 bool ignore_output_change = false;
565 Delivery::output_changed (IOChange change, void* /*src*/)
567 if (change.type & IOChange::ConfigurationChanged) {
569 _output_buffers->attach_buffers (_output->ports ());
573 boost::shared_ptr<Panner>
574 Delivery::panner () const
577 return _panshell->panner();
579 return boost::shared_ptr<Panner>();