merge (with conflict fixes) with master (even against rgareus' recommendation)
[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         output_buffers().get_backend_port_addresses (ports, nframes);
253
254         // this Delivery processor is not a derived type, and thus we assume
255         // we really can modify the buffers passed in (it is almost certainly
256         // the main output stage of a Route). Contrast with Send::run()
257         // which cannot do this.
258
259         tgain = target_gain ();
260
261         if (tgain != _current_gain) {
262                 /* target gain has changed */
263
264                 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
265                 _current_gain = tgain;
266
267         } else if (tgain == 0.0) {
268
269                 /* we were quiet last time, and we're still supposed to be quiet.
270                    Silence the outputs, and make sure the buffers are quiet too,
271                 */
272
273                 _output->silence (nframes);
274                 if (result_required) {
275                         bufs.set_count (output_buffers().count ());
276                         Amp::apply_simple_gain (bufs, nframes, 0.0);
277                 }
278                 goto out;
279
280         } else if (tgain != 1.0) {
281
282                 /* target gain has not changed, but is not unity */
283                 Amp::apply_simple_gain (bufs, nframes, tgain);
284         }
285
286         if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
287
288                 // Use the panner to distribute audio to output port buffers
289
290                 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
291
292                 // MIDI data will not have been delivered by the panner
293
294                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
295                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
296                 }
297
298         } else {
299
300                 // Do a 1:1 copy of data to output ports
301
302                 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
303                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
304                 }
305
306                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
307                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
308                 }
309         }
310
311         if (result_required) {
312                 bufs.read_from (output_buffers (), nframes);
313         }
314
315   out:
316         _active = _pending_active;
317 }
318
319 XMLNode&
320 Delivery::state (bool full_state)
321 {
322         XMLNode& node (IOProcessor::state (full_state));
323
324         if (_role & Main) {
325                 node.add_property("type", "main-outs");
326         } else if (_role & Listen) {
327                 node.add_property("type", "listen");
328         } else {
329                 node.add_property("type", "delivery");
330         }
331
332         node.add_property("role", enum_2_string(_role));
333
334         if (_panshell) {
335                 node.add_child_nocopy (_panshell->get_state ());
336                 if (_panshell->pannable()) {
337                         node.add_child_nocopy (_panshell->pannable()->get_state ());
338                 }
339         }
340
341         return node;
342 }
343
344 int
345 Delivery::set_state (const XMLNode& node, int version)
346 {
347         const XMLProperty* prop;
348
349         if (IOProcessor::set_state (node, version)) {
350                 return -1;
351         }
352
353         if ((prop = node.property ("role")) != 0) {
354                 _role = Role (string_2_enum (prop->value(), _role));
355                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
356         } else {
357                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
358         }
359
360         XMLNode* pan_node = node.child (X_("PannerShell"));
361
362         if (pan_node && _panshell) {
363                 _panshell->set_state (*pan_node, version);
364         }
365
366         reset_panner ();
367
368         XMLNode* pannnode = node.child (X_("Pannable"));
369         if (_panshell && _panshell->panner() && pannnode) {
370                 _panshell->pannable()->set_state (*pannnode, version);
371                 _panshell->pannable()->set_panner(_panshell->panner());
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) {
402                                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
403                                 
404                                 if (_role == Main || _role == Aux || _role == Send) {
405                                         _panshell->pannable()->set_panner (_panshell->panner());
406                                 }
407                         }
408                 }
409
410         } else {
411                 panner_legal_c.disconnect ();
412                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
413         }
414 }
415
416 void
417 Delivery::panners_became_legal ()
418 {
419         if (_panshell) {
420                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
421                 
422                 if (_role == Main) {
423                         _panshell->pannable()->set_panner (_panshell->panner());
424                 }
425         }
426
427         panner_legal_c.disconnect ();
428 }
429
430 void
431 Delivery::defer_pan_reset ()
432 {
433         _no_panner_reset = true;
434 }
435
436 void
437 Delivery::allow_pan_reset ()
438 {
439         _no_panner_reset = false;
440         reset_panner ();
441 }
442
443
444 int
445 Delivery::disable_panners ()
446 {
447         panners_legal = false;
448         return 0;
449 }
450
451 void
452 Delivery::reset_panners ()
453 {
454         panners_legal = true;
455         PannersLegal ();
456 }
457
458 void
459 Delivery::flush_buffers (framecnt_t nframes)
460 {
461         /* io_lock, not taken: function must be called from Session::process() calltree */
462
463         if (!_output) {
464                 return;
465         }
466         
467         PortSet& ports (_output->ports());
468
469         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
470                 i->flush_buffers (nframes);
471         }
472 }
473
474 void
475 Delivery::transport_stopped (framepos_t now)
476 {
477         Processor::transport_stopped (now);
478
479         if (_panshell) {
480                 _panshell->pannable()->transport_stopped (now);
481         }
482
483         if (_output) {
484                 PortSet& ports (_output->ports());
485
486                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
487                         i->transport_stopped ();
488                 }
489         }
490 }
491
492 void
493 Delivery::realtime_locate ()
494 {
495         if (_output) {
496                 PortSet& ports (_output->ports());
497
498                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
499                         i->realtime_locate ();
500                 }
501         }
502 }
503
504 gain_t
505 Delivery::target_gain ()
506 {
507         /* if we've been requested to deactivate, our target gain is zero */
508
509         if (!_pending_active) {
510                 return 0.0;
511         }
512
513         /* if we've been told not to output because its a monitoring situation and
514            we're not monitoring, then be quiet.
515         */
516
517         if (_no_outs_cuz_we_no_monitor) {
518                 return 0.0;
519         }
520
521         MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
522
523         switch (_role) {
524         case Main:
525                 mp = MuteMaster::Main;
526                 break;
527         case Listen:
528                 mp = MuteMaster::Listen;
529                 break;
530         case Send:
531         case Insert:
532         case Aux:
533                 if (_pre_fader) {
534                         mp = MuteMaster::PreFader;
535                 } else {
536                         mp = MuteMaster::PostFader;
537                 }
538                 break;
539         }
540
541         gain_t desired_gain = _mute_master->mute_gain_at (mp);
542
543         if (_role == Listen && _session.monitor_out() && !_session.listening()) {
544
545                 /* nobody is soloed, and this delivery is a listen-send to the
546                    control/monitor/listen bus, we should be silent since
547                    it gets its signal from the master out.
548                 */
549
550                 desired_gain = 0.0;
551
552         }
553
554         return desired_gain;
555 }
556
557 void
558 Delivery::no_outs_cuz_we_no_monitor (bool yn)
559 {
560         _no_outs_cuz_we_no_monitor = yn;
561 }
562
563 bool
564 Delivery::set_name (const std::string& name)
565 {
566         bool ret = IOProcessor::set_name (name);
567
568         if (ret) {
569                 ret = _panshell->set_name (name);
570         }
571
572         return ret;
573 }
574
575 bool ignore_output_change = false;
576
577 void
578 Delivery::output_changed (IOChange change, void* /*src*/)
579 {
580         if (change.type & IOChange::ConfigurationChanged) {
581                 reset_panner ();
582                 _output_buffers->attach_buffers (_output->ports ());
583         }
584 }
585
586 boost::shared_ptr<Panner>
587 Delivery::panner () const
588 {
589         if (_panshell) {
590                 return _panshell->panner();
591         } else {
592                 return boost::shared_ptr<Panner>();
593         }
594 }
595