dfbe4c960adcad6151038804b85919b1bdf6166a
[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_jack_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         }
333
334         return node;
335 }
336
337 int
338 Delivery::set_state (const XMLNode& node, int version)
339 {
340         const XMLProperty* prop;
341
342         if (IOProcessor::set_state (node, version)) {
343                 return -1;
344         }
345
346         if ((prop = node.property ("role")) != 0) {
347                 _role = Role (string_2_enum (prop->value(), _role));
348                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
349         } else {
350                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
351         }
352
353         XMLNode* pan_node = node.child (X_("PannerShell"));
354
355         if (pan_node && _panshell) {
356                 _panshell->set_state (*pan_node, version);
357         }
358
359         reset_panner ();
360
361         return 0;
362 }
363
364 void
365 Delivery::unpan ()
366 {
367         /* caller must hold process lock */
368
369         _panshell.reset ();
370 }
371
372 uint32_t
373 Delivery::pan_outs () const
374 {
375         if (_output) {
376                 return _output->n_ports().n_audio();
377         } 
378
379         return _configured_output.n_audio();
380 }
381
382 void
383 Delivery::reset_panner ()
384 {
385         if (panners_legal) {
386                 if (!_no_panner_reset) {
387
388                         if (_panshell) {
389                                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
390                                 
391                                 if (_role == Main) {
392                                         _panshell->pannable()->set_panner (_panshell->panner());
393                                 }
394                         }
395                 }
396
397         } else {
398                 panner_legal_c.disconnect ();
399                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
400         }
401 }
402
403 void
404 Delivery::panners_became_legal ()
405 {
406         if (_panshell) {
407                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
408                 
409                 if (_role == Main) {
410                         _panshell->pannable()->set_panner (_panshell->panner());
411                 }
412         }
413
414         panner_legal_c.disconnect ();
415 }
416
417 void
418 Delivery::defer_pan_reset ()
419 {
420         _no_panner_reset = true;
421 }
422
423 void
424 Delivery::allow_pan_reset ()
425 {
426         _no_panner_reset = false;
427         reset_panner ();
428 }
429
430
431 int
432 Delivery::disable_panners ()
433 {
434         panners_legal = false;
435         return 0;
436 }
437
438 void
439 Delivery::reset_panners ()
440 {
441         panners_legal = true;
442         PannersLegal ();
443 }
444
445 void
446 Delivery::flush_buffers (framecnt_t nframes)
447 {
448         /* io_lock, not taken: function must be called from Session::process() calltree */
449
450         if (!_output) {
451                 return;
452         }
453         
454         PortSet& ports (_output->ports());
455
456         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
457                 i->flush_buffers (nframes);
458         }
459 }
460
461 void
462 Delivery::transport_stopped (framepos_t now)
463 {
464         Processor::transport_stopped (now);
465
466         if (_panshell) {
467                 _panshell->pannable()->transport_stopped (now);
468         }
469
470         if (_output) {
471                 PortSet& ports (_output->ports());
472
473                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
474                         i->transport_stopped ();
475                 }
476         }
477 }
478
479 void
480 Delivery::realtime_locate ()
481 {
482         if (_output) {
483                 PortSet& ports (_output->ports());
484
485                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
486                         i->realtime_locate ();
487                 }
488         }
489 }
490
491 gain_t
492 Delivery::target_gain ()
493 {
494         /* if we've been requested to deactivate, our target gain is zero */
495
496         if (!_pending_active) {
497                 return 0.0;
498         }
499
500         /* if we've been told not to output because its a monitoring situation and
501            we're not monitoring, then be quiet.
502         */
503
504         if (_no_outs_cuz_we_no_monitor) {
505                 return 0.0;
506         }
507
508         MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
509
510         switch (_role) {
511         case Main:
512                 mp = MuteMaster::Main;
513                 break;
514         case Listen:
515                 mp = MuteMaster::Listen;
516                 break;
517         case Send:
518         case Insert:
519         case Aux:
520                 if (_pre_fader) {
521                         mp = MuteMaster::PreFader;
522                 } else {
523                         mp = MuteMaster::PostFader;
524                 }
525                 break;
526         }
527
528         gain_t desired_gain = _mute_master->mute_gain_at (mp);
529
530         if (_role == Listen && _session.monitor_out() && !_session.listening()) {
531
532                 /* nobody is soloed, and this delivery is a listen-send to the
533                    control/monitor/listen bus, we should be silent since
534                    it gets its signal from the master out.
535                 */
536
537                 desired_gain = 0.0;
538
539         }
540
541         return desired_gain;
542 }
543
544 void
545 Delivery::no_outs_cuz_we_no_monitor (bool yn)
546 {
547         _no_outs_cuz_we_no_monitor = yn;
548 }
549
550 bool
551 Delivery::set_name (const std::string& name)
552 {
553         bool ret = IOProcessor::set_name (name);
554
555         if (ret) {
556                 ret = _panshell->set_name (name);
557         }
558
559         return ret;
560 }
561
562 bool ignore_output_change = false;
563
564 void
565 Delivery::output_changed (IOChange change, void* /*src*/)
566 {
567         if (change.type & IOChange::ConfigurationChanged) {
568                 reset_panner ();
569                 _output_buffers->attach_buffers (_output->ports ());
570         }
571 }
572
573 boost::shared_ptr<Panner>
574 Delivery::panner () const
575 {
576         if (_panshell) {
577                 return _panshell->panner();
578         } else {
579                 return boost::shared_ptr<Panner>();
580         }
581 }
582