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