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