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<int> 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 ();
421 Delivery::defer_pan_reset ()
423 _no_panner_reset = true;
427 Delivery::allow_pan_reset ()
429 _no_panner_reset = false;
435 Delivery::disable_panners ()
437 panners_legal = false;
442 Delivery::reset_panners ()
444 panners_legal = true;
445 return *PannersLegal ();
449 Delivery::flush_buffers (framecnt_t nframes, framepos_t time)
451 /* io_lock, not taken: function must be called from Session::process() calltree */
457 PortSet& ports (_output->ports());
459 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
460 i->flush_buffers (nframes, time);
465 Delivery::transport_stopped (framepos_t now)
467 Processor::transport_stopped (now);
470 _panshell->pannable()->transport_stopped (now);
474 PortSet& ports (_output->ports());
476 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
477 i->transport_stopped ();
483 Delivery::realtime_locate ()
486 PortSet& ports (_output->ports());
488 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
489 i->realtime_locate ();
495 Delivery::target_gain ()
497 /* if we've been requested to deactivate, our target gain is zero */
499 if (!_pending_active) {
503 /* if we've been told not to output because its a monitoring situation and
504 we're not monitoring, then be quiet.
507 if (_no_outs_cuz_we_no_monitor) {
511 MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
515 mp = MuteMaster::Main;
518 mp = MuteMaster::Listen;
524 mp = MuteMaster::PreFader;
526 mp = MuteMaster::PostFader;
531 gain_t desired_gain = _mute_master->mute_gain_at (mp);
533 if (_role == Listen && _session.monitor_out() && !_session.listening()) {
535 /* nobody is soloed, and this delivery is a listen-send to the
536 control/monitor/listen bus, we should be silent since
537 it gets its signal from the master out.
548 Delivery::no_outs_cuz_we_no_monitor (bool yn)
550 _no_outs_cuz_we_no_monitor = yn;
554 Delivery::set_name (const std::string& name)
556 bool ret = IOProcessor::set_name (name);
559 ret = _panshell->set_name (name);
565 bool ignore_output_change = false;
568 Delivery::output_changed (IOChange change, void* /*src*/)
570 if (change.type & IOChange::ConfigurationChanged) {
572 _output_buffers->attach_buffers (_output->ports ());
576 boost::shared_ptr<Panner>
577 Delivery::panner () const
580 return _panshell->panner();
582 return boost::shared_ptr<Panner>();