26d2cf3acd8b027ebe01188e0646bb9a03f9ce85
[ardour.git] / libs / ardour / delivery.cc
1 /*
2     Copyright (C) 2009 Paul Davis
3
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)
7     any later version.
8
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
12     for more details.
13
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.
17 */
18
19 #include <cmath>
20 #include <algorithm>
21
22 #include "pbd/enumwriter.h"
23 #include "pbd/convert.h"
24
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"
36
37 #include "i18n.h"
38
39 namespace ARDOUR { class Panner; }
40
41 using namespace std;
42 using namespace PBD;
43 using namespace ARDOUR;
44
45 PBD::Signal0<void>            Delivery::PannersLegal;
46 bool                          Delivery::panners_legal = false;
47
48 /* deliver to an existing IO object */
49
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)
53         , _role (r)
54         , _output_buffers (new BufferSet())
55         , _current_gain (1.0)
56         , _no_outs_cuz_we_no_monitor (false)
57         , _mute_master (mm)
58         , _no_panner_reset (false)
59 {
60         if (pannable) {
61                 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
62         }
63
64         _display_to_user = false;
65
66         if (_output) {
67                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
68         }
69 }
70
71 /* deliver to a new IO object */
72
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))
75         , _role (r)
76         , _output_buffers (new BufferSet())
77         , _current_gain (1.0)
78         , _no_outs_cuz_we_no_monitor (false)
79         , _mute_master (mm)
80         , _no_panner_reset (false)
81 {
82         if (pannable) {
83                 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
84         }
85
86         _display_to_user = false;
87
88         if (_output) {
89                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
90         }
91 }
92
93
94 Delivery::~Delivery()
95 {
96         DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));   
97
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.
102         */
103
104         ScopedConnectionList::drop_connections ();
105
106         delete _output_buffers;
107 }
108
109 std::string
110 Delivery::display_name () const
111 {
112         switch (_role) {
113         case Main:
114                 return _("main outs");
115                 break;
116         case Listen:
117                 return _("listen");
118                 break;
119         case Send:
120         case Insert:
121         default:
122                 return name();
123         }
124 }
125
126 bool
127 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out)
128 {
129         if (_role == Main) {
130
131                 /* the out buffers will be set to point to the port output buffers
132                    of our output object.
133                 */
134
135                 if (_output) {
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);
139                                 return true;
140                         } else {
141                                 /* not configured yet - we will passthru */
142                                 out = in;
143                                 return true;
144                         }
145                 } else {
146                         fatal << "programming error: this should never be reached" << endmsg;
147                         /*NOTREACHED*/
148                 }
149
150
151         } else if (_role == Insert) {
152
153                 /* the output buffers will be filled with data from the *input* ports
154                    of this Insert.
155                 */
156
157                 if (_input) {
158                         if (_input->n_ports() != ChanCount::ZERO) {
159                                 out = _input->n_ports();
160                                 return true;
161                         } else {
162                                 /* not configured yet - we will passthru */
163                                 out = in;
164                                 return true;
165                         }
166                 } else {
167                         fatal << "programming error: this should never be reached" << endmsg;
168                         /*NOTREACHED*/
169                 }
170
171         } else {
172                 fatal << "programming error: this should never be reached" << endmsg;
173         }
174
175         return false;
176 }
177
178 /** Caller must hold process lock */
179 bool
180 Delivery::configure_io (ChanCount in, ChanCount out)
181 {
182 #ifndef NDEBUG
183         bool r = AudioEngine::instance()->process_lock().trylock();
184         assert (!r && "trylock inside Delivery::configure_io");
185 #endif
186
187         /* check configuration by comparison with our I/O port configuration, if appropriate.
188            see ::can_support_io_configuration() for comments
189         */
190
191         if (_role == Main) {
192
193                 if (_output) {
194                         if (_output->n_ports() != out) {
195                                 if (_output->n_ports() != ChanCount::ZERO) {
196                                         _output->ensure_io (out, false, this);
197                                 } else {
198                                         /* I/O not yet configured */
199                                 }
200                         }
201                 }
202
203         } else if (_role == Insert) {
204
205                 if (_input) {
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;
209                                         /*NOTREACHED*/
210                                 } else {
211                                         /* I/O not yet configured */
212                                 }
213                         }
214                 }
215
216         }
217
218         if (!Processor::configure_io (in, out)) {
219                 return false;
220         }
221
222         reset_panner ();
223
224         return true;
225 }
226
227 void
228 Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
229 {
230         assert (_output);
231
232         PortSet& ports (_output->ports());
233         gain_t tgain;
234
235         if (_output->n_ports ().get (_output->default_type()) == 0) {
236                 goto out;
237         }
238
239         if (!_active && !_pending_active) {
240                 _output->silence (nframes);
241                 goto out;
242         }
243
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.
246         */
247
248         output_buffers().get_backend_port_addresses (ports, nframes);
249
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.
254
255         tgain = target_gain ();
256
257         if (tgain != _current_gain) {
258                 /* target gain has changed */
259
260                 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
261                 _current_gain = tgain;
262
263         } else if (tgain == 0.0) {
264
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,
267                 */
268
269                 _output->silence (nframes);
270                 if (result_required) {
271                         bufs.set_count (output_buffers().count ());
272                         Amp::apply_simple_gain (bufs, nframes, 0.0);
273                 }
274                 goto out;
275
276         } else if (tgain != 1.0) {
277
278                 /* target gain has not changed, but is not unity */
279                 Amp::apply_simple_gain (bufs, nframes, tgain);
280         }
281
282         if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
283
284                 // Use the panner to distribute audio to output port buffers
285
286                 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
287
288                 // MIDI data will not have been delivered by the panner
289
290                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
291                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
292                 }
293
294         } else {
295
296                 // Do a 1:1 copy of data to output ports
297
298                 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
299                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
300                 }
301
302                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
303                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
304                 }
305         }
306
307         if (result_required) {
308                 bufs.read_from (output_buffers (), nframes);
309         }
310
311   out:
312         _active = _pending_active;
313 }
314
315 XMLNode&
316 Delivery::state (bool full_state)
317 {
318         XMLNode& node (IOProcessor::state (full_state));
319
320         if (_role & Main) {
321                 node.add_property("type", "main-outs");
322         } else if (_role & Listen) {
323                 node.add_property("type", "listen");
324         } else {
325                 node.add_property("type", "delivery");
326         }
327
328         node.add_property("role", enum_2_string(_role));
329
330         if (_panshell) {
331                 node.add_child_nocopy (_panshell->get_state ());
332                 if (_panshell->pannable()) {
333                         node.add_child_nocopy (_panshell->pannable()->get_state ());
334                 }
335         }
336
337         return node;
338 }
339
340 int
341 Delivery::set_state (const XMLNode& node, int version)
342 {
343         const XMLProperty* prop;
344
345         if (IOProcessor::set_state (node, version)) {
346                 return -1;
347         }
348
349         if ((prop = node.property ("role")) != 0) {
350                 _role = Role (string_2_enum (prop->value(), _role));
351                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
352         } else {
353                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
354         }
355
356         XMLNode* pan_node = node.child (X_("PannerShell"));
357
358         if (pan_node && _panshell) {
359                 _panshell->set_state (*pan_node, version);
360         }
361
362         reset_panner ();
363
364         XMLNode* pannnode = node.child (X_("Pannable"));
365         if (_panshell->panner() && pannnode) {
366                 _panshell->pannable()->set_state (*pannnode, version);
367         }
368
369         return 0;
370 }
371
372 void
373 Delivery::unpan ()
374 {
375         /* caller must hold process lock */
376
377         _panshell.reset ();
378 }
379
380 uint32_t
381 Delivery::pan_outs () const
382 {
383         if (_output) {
384                 return _output->n_ports().n_audio();
385         } 
386
387         return _configured_output.n_audio();
388 }
389
390 void
391 Delivery::reset_panner ()
392 {
393         if (panners_legal) {
394                 if (!_no_panner_reset) {
395
396                         if (_panshell) {
397                                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
398                                 
399                                 if (_role == Main || _role == Aux) {
400                                         _panshell->pannable()->set_panner (_panshell->panner());
401                                 }
402                         }
403                 }
404
405         } else {
406                 panner_legal_c.disconnect ();
407                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
408         }
409 }
410
411 void
412 Delivery::panners_became_legal ()
413 {
414         if (_panshell) {
415                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
416                 
417                 if (_role == Main) {
418                         _panshell->pannable()->set_panner (_panshell->panner());
419                 }
420         }
421
422         panner_legal_c.disconnect ();
423 }
424
425 void
426 Delivery::defer_pan_reset ()
427 {
428         _no_panner_reset = true;
429 }
430
431 void
432 Delivery::allow_pan_reset ()
433 {
434         _no_panner_reset = false;
435         reset_panner ();
436 }
437
438
439 int
440 Delivery::disable_panners ()
441 {
442         panners_legal = false;
443         return 0;
444 }
445
446 void
447 Delivery::reset_panners ()
448 {
449         panners_legal = true;
450         PannersLegal ();
451 }
452
453 void
454 Delivery::flush_buffers (framecnt_t nframes)
455 {
456         /* io_lock, not taken: function must be called from Session::process() calltree */
457
458         if (!_output) {
459                 return;
460         }
461         
462         PortSet& ports (_output->ports());
463
464         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
465                 i->flush_buffers (nframes);
466         }
467 }
468
469 void
470 Delivery::transport_stopped (framepos_t now)
471 {
472         Processor::transport_stopped (now);
473
474         if (_panshell) {
475                 _panshell->pannable()->transport_stopped (now);
476         }
477
478         if (_output) {
479                 PortSet& ports (_output->ports());
480
481                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
482                         i->transport_stopped ();
483                 }
484         }
485 }
486
487 void
488 Delivery::realtime_locate ()
489 {
490         if (_output) {
491                 PortSet& ports (_output->ports());
492
493                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
494                         i->realtime_locate ();
495                 }
496         }
497 }
498
499 gain_t
500 Delivery::target_gain ()
501 {
502         /* if we've been requested to deactivate, our target gain is zero */
503
504         if (!_pending_active) {
505                 return 0.0;
506         }
507
508         /* if we've been told not to output because its a monitoring situation and
509            we're not monitoring, then be quiet.
510         */
511
512         if (_no_outs_cuz_we_no_monitor) {
513                 return 0.0;
514         }
515
516         MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
517
518         switch (_role) {
519         case Main:
520                 mp = MuteMaster::Main;
521                 break;
522         case Listen:
523                 mp = MuteMaster::Listen;
524                 break;
525         case Send:
526         case Insert:
527         case Aux:
528                 if (_pre_fader) {
529                         mp = MuteMaster::PreFader;
530                 } else {
531                         mp = MuteMaster::PostFader;
532                 }
533                 break;
534         }
535
536         gain_t desired_gain = _mute_master->mute_gain_at (mp);
537
538         if (_role == Listen && _session.monitor_out() && !_session.listening()) {
539
540                 /* nobody is soloed, and this delivery is a listen-send to the
541                    control/monitor/listen bus, we should be silent since
542                    it gets its signal from the master out.
543                 */
544
545                 desired_gain = 0.0;
546
547         }
548
549         return desired_gain;
550 }
551
552 void
553 Delivery::no_outs_cuz_we_no_monitor (bool yn)
554 {
555         _no_outs_cuz_we_no_monitor = yn;
556 }
557
558 bool
559 Delivery::set_name (const std::string& name)
560 {
561         bool ret = IOProcessor::set_name (name);
562
563         if (ret) {
564                 ret = _panshell->set_name (name);
565         }
566
567         return ret;
568 }
569
570 bool ignore_output_change = false;
571
572 void
573 Delivery::output_changed (IOChange change, void* /*src*/)
574 {
575         if (change.type & IOChange::ConfigurationChanged) {
576                 reset_panner ();
577                 _output_buffers->attach_buffers (_output->ports ());
578         }
579 }
580
581 boost::shared_ptr<Panner>
582 Delivery::panner () const
583 {
584         if (_panshell) {
585                 return _panshell->panner();
586         } else {
587                 return boost::shared_ptr<Panner>();
588         }
589 }
590