fully implement and deploy explicit x-thread signal connection syntax (testing comes...
[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/delivery.h"
28 #include "ardour/audio_buffer.h"
29 #include "ardour/amp.h"
30 #include "ardour/buffer_set.h"
31 #include "ardour/configuration.h"
32 #include "ardour/io.h"
33 #include "ardour/meter.h"
34 #include "ardour/mute_master.h"
35 #include "ardour/panner.h"
36 #include "ardour/port.h"
37 #include "ardour/session.h"
38
39 #include "i18n.h"
40
41 using namespace std;
42 using namespace PBD;
43 using namespace ARDOUR;
44
45 PBD::Signal1<void,nframes_t> Delivery::CycleStart;
46 PBD::Signal0<int>           Delivery::PannersLegal;
47 bool                                     Delivery::panners_legal = false;
48
49 /* deliver to an existing IO object */
50
51 Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, 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         , _output_offset (0)
57         , _no_outs_cuz_we_no_monitor (false)
58         , _solo_level (0)
59         , _solo_isolated (false)
60         , _mute_master (mm)
61         , no_panner_reset (false)
62 {
63         _panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
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         CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
71 }
72
73 /* deliver to a new IO object */
74
75 Delivery::Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
76         : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name)
77         , _role (r)
78         , _output_buffers (new BufferSet())
79         , _current_gain (1.0)
80         , _output_offset (0)
81         , _no_outs_cuz_we_no_monitor (false)
82         , _solo_level (0)
83         , _solo_isolated (false)
84         , _mute_master (mm)
85         , no_panner_reset (false)
86 {
87         _panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
88         _display_to_user = false;
89
90         if (_output) {
91                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
92         }
93
94         CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
95 }
96
97 /* deliver to a new IO object, reconstruct from XML */
98
99 Delivery::Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node)
100         : IOProcessor (s, false, true, "reset")
101         , _role (Role (0))
102         , _output_buffers (new BufferSet())
103         , _current_gain (1.0)
104         , _output_offset (0)
105         , _no_outs_cuz_we_no_monitor (false)
106         , _solo_level (0)
107         , _solo_isolated (false)
108         , _mute_master (mm)
109         , no_panner_reset (false)
110 {
111         _panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
112         _display_to_user = false;
113
114         if (set_state (node, Stateful::loading_state_version)) {
115                 throw failed_constructor ();
116         }
117
118         if (_output) {
119                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
120         }
121
122         CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
123 }
124
125 /* deliver to an existing IO object, reconstruct from XML */
126
127 Delivery::Delivery (Session& s, boost::shared_ptr<IO> out, boost::shared_ptr<MuteMaster> mm, const XMLNode& node)
128         : IOProcessor (s, boost::shared_ptr<IO>(), out, "reset")
129         , _role (Role (0))
130         , _output_buffers (new BufferSet())
131         , _current_gain (1.0)
132         , _output_offset (0)
133         , _no_outs_cuz_we_no_monitor (false)
134         , _solo_level (0)
135         , _solo_isolated (false)
136         , _mute_master (mm)
137         , no_panner_reset (false)
138 {
139         _panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
140         _display_to_user = false;
141
142         if (set_state (node, Stateful::loading_state_version)) {
143                 throw failed_constructor ();
144         }
145
146         if (_output) {
147                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
148         }
149
150         CycleStart.connect_same_thread (*this, boost::bind (&Delivery::cycle_start, this, _1));
151 }
152
153 std::string
154 Delivery::display_name () const
155 {
156         switch (_role) {
157         case Main:
158                 return _("main outs");
159                 break;
160         case Listen:
161                 return _("listen");
162                 break;
163         case Send:
164         case Insert:
165         default:
166                 return name();
167         }
168 }
169
170 void
171 Delivery::cycle_start (nframes_t /*nframes*/)
172 {
173         _output_offset = 0;
174         _no_outs_cuz_we_no_monitor = false;
175 }
176
177 void
178 Delivery::increment_output_offset (nframes_t n)
179 {
180         _output_offset += n;
181 }
182
183 bool
184 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
185 {
186         if (_role == Main) {
187
188                 /* the out buffers will be set to point to the port output buffers
189                    of our output object.
190                 */
191
192                 if (_output) {
193                         if (_output->n_ports() != ChanCount::ZERO) {
194                                 out = _output->n_ports();
195                                 return true;
196                         } else {
197                                 /* not configured yet - we will passthru */
198                                 out = in;
199                                 return true;
200                         }
201                 } else {
202                         fatal << "programming error: this should never be reached" << endmsg;
203                         /*NOTREACHED*/
204                 }
205
206
207         } else if (_role == Insert) {
208
209                 /* the output buffers will be filled with data from the *input* ports
210                    of this Insert.
211                 */
212
213                 if (_input) {
214                         if (_input->n_ports() != ChanCount::ZERO) {
215                                 out = _input->n_ports();
216                                 return true;
217                         } else {
218                                 /* not configured yet - we will passthru */
219                                 out = in;
220                                 return true;
221                         }
222                 } else {
223                         fatal << "programming error: this should never be reached" << endmsg;
224                         /*NOTREACHED*/
225                 }
226
227         } else {
228                 fatal << "programming error: this should never be reached" << endmsg;
229         }
230
231         return false;
232 }
233
234 bool
235 Delivery::configure_io (ChanCount in, ChanCount out)
236 {
237         /* check configuration by comparison with our I/O port configuration, if appropriate.
238            see ::can_support_io_configuration() for comments
239         */
240
241         if (_role == Main) {
242
243                 if (_output) {
244                         if (_output->n_ports() != out) {
245                                 if (_output->n_ports() != ChanCount::ZERO) {
246                                         fatal << _name << " programming error: configure_io with nports = " << _output->n_ports() << " called with " << in << " and " << out << " with " << _output->n_ports() << " output ports" << endmsg;
247                                         /*NOTREACHED*/
248                                 } else {
249                                         /* I/O not yet configured */
250                                 }
251                         }
252                 }
253
254         } else if (_role == Insert) {
255
256                 if (_input) {
257                         if (_input->n_ports() != in) {
258                                 if (_input->n_ports() != ChanCount::ZERO) {
259                                         fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
260                                         /*NOTREACHED*/
261                                 } else {
262                                         /* I/O not yet configured */
263                                 }
264                         }
265                 }
266         }
267
268         if (!Processor::configure_io (in, out)) {
269                 return false;
270         }
271
272         reset_panner ();
273
274         return true;
275 }
276
277 void
278 Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool result_required)
279 {
280         assert (_output);
281
282         PortSet& ports (_output->ports());
283         gain_t tgain;
284
285         if (_output->n_ports ().get (_output->default_type()) == 0) {
286                 goto out;
287         }
288
289         if (!_active && !_pending_active) {
290                 _output->silence (nframes);
291                 goto out;
292         }
293
294         /* this setup is not just for our purposes, but for anything that comes after us in the
295            processing pathway that wants to use this->output_buffers() for some reason.
296         */
297
298         output_buffers().attach_buffers (ports, nframes, _output_offset);
299
300         // this Delivery processor is not a derived type, and thus we assume
301         // we really can modify the buffers passed in (it is almost certainly
302         // the main output stage of a Route). Contrast with Send::run()
303         // which cannot do this.
304
305         tgain = target_gain ();
306
307         if (tgain != _current_gain) {
308
309                 /* target gain has changed */
310
311                 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
312                 _current_gain = tgain;
313
314         } else if (tgain == 0.0) {
315
316                 /* we were quiet last time, and we're still supposed to be quiet.
317                    Silence the outputs, and make sure the buffers are quiet too,
318                 */
319
320                 _output->silence (nframes);
321                 if (result_required) {
322                         Amp::apply_simple_gain (bufs, nframes, 0.0);
323                 }
324                 goto out;
325
326         } else if (tgain != 1.0) {
327
328                 /* target gain has not changed, but is not unity */
329                 Amp::apply_simple_gain (bufs, nframes, tgain);
330         }
331
332         if (_panner && _panner->npanners() && !_panner->bypassed()) {
333
334                 // Use the panner to distribute audio to output port buffers
335
336                 _panner->run (bufs, output_buffers(), start_frame, end_frame, nframes);
337
338                 if (result_required) {
339                         bufs.read_from (output_buffers (), nframes);
340                 }
341
342         } else {
343                 // Do a 1:1 copy of data to output ports
344
345                 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
346                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, _output_offset);
347                 }
348
349                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
350                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset);
351                 }
352         }
353
354   out:
355         _active = _pending_active;
356 }
357
358 XMLNode&
359 Delivery::state (bool full_state)
360 {
361         XMLNode& node (IOProcessor::state (full_state));
362
363         if (_role & Main) {
364                 node.add_property("type", "main-outs");
365         } else if (_role & Listen) {
366                 node.add_property("type", "listen");
367         } else {
368                 node.add_property("type", "delivery");
369         }
370
371         node.add_property("role", enum_2_string(_role));
372         node.add_child_nocopy (_panner->state (full_state));
373
374         return node;
375 }
376
377 int
378 Delivery::set_state (const XMLNode& node, int version)
379 {
380         const XMLProperty* prop;
381
382         if (IOProcessor::set_state (node, version)) {
383                 return -1;
384         }
385
386         if ((prop = node.property ("role")) != 0) {
387                 _role = Role (string_2_enum (prop->value(), _role));
388                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
389         } else {
390                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
391         }
392
393         XMLNode* pan_node = node.child (X_("Panner"));
394
395         if (pan_node) {
396                 _panner->set_state (*pan_node, version);
397         }
398
399         reset_panner ();
400
401         return 0;
402 }
403
404 void
405 Delivery::reset_panner ()
406 {
407         if (panners_legal) {
408                 if (!no_panner_reset) {
409
410                         uint32_t ntargets;
411
412                         if (_output) {
413                                 ntargets = _output->n_ports().n_audio();
414                         } else {
415                                 ntargets = _configured_output.n_audio();
416                         }
417
418                         _panner->reset (ntargets, pans_required());
419                 }
420         } else {
421                 panner_legal_c.disconnect ();
422                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
423         }
424 }
425
426 int
427 Delivery::panners_became_legal ()
428 {
429         uint32_t ntargets;
430
431         if (_output) {
432                 ntargets = _output->n_ports().n_audio();
433         } else {
434                 ntargets = _configured_output.n_audio();
435         }
436
437         _panner->reset (ntargets, pans_required());
438         _panner->load (); // automation
439         panner_legal_c.disconnect ();
440         return 0;
441 }
442
443 void
444 Delivery::defer_pan_reset ()
445 {
446         no_panner_reset = true;
447 }
448
449 void
450 Delivery::allow_pan_reset ()
451 {
452         no_panner_reset = false;
453         reset_panner ();
454 }
455
456
457 int
458 Delivery::disable_panners (void)
459 {
460         panners_legal = false;
461         return 0;
462 }
463
464 int
465 Delivery::reset_panners ()
466 {
467         panners_legal = true;
468         return *PannersLegal ();
469 }
470
471
472 void
473 Delivery::start_pan_touch (uint32_t which)
474 {
475         if (which < _panner->npanners()) {
476                 _panner->pan_control(which)->start_touch();
477         }
478 }
479
480 void
481 Delivery::end_pan_touch (uint32_t which)
482 {
483         if (which < _panner->npanners()) {
484                 _panner->pan_control(which)->stop_touch();
485         }
486
487 }
488
489 void
490 Delivery::transport_stopped (sframes_t frame)
491 {
492         _panner->transport_stopped (frame);
493 }
494
495 void
496 Delivery::flush (nframes_t nframes, nframes64_t time)
497 {
498         /* io_lock, not taken: function must be called from Session::process() calltree */
499
500         PortSet& ports (_output->ports());
501
502         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
503                 (*i).flush_buffers (nframes, time, _output_offset);
504         }
505 }
506
507 void
508 Delivery::transport_stopped ()
509 {
510         /* turn off any notes that are on */
511
512         PortSet& ports (_output->ports());
513
514         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
515                 (*i).transport_stopped ();
516         }
517 }
518
519 gain_t
520 Delivery::target_gain ()
521 {
522         /* if we've been requested to deactivate, our target gain is zero */
523
524         if (!_pending_active) {
525                 return 0.0;
526         }
527
528         /* if we've been told not to output because its a monitoring situation and
529            we're not monitoring, then be quiet.
530         */
531
532         if (_no_outs_cuz_we_no_monitor) {
533                 return 0.0;
534         }
535
536         gain_t desired_gain;
537
538
539         if (_solo_level) {
540                 desired_gain = 1.0;
541         } else {
542
543                 MuteMaster::MutePoint mp;
544
545                 switch (_role) {
546                 case Main:
547                         mp = MuteMaster::Main;
548                         break;
549                 case Listen:
550                         mp = MuteMaster::Listen;
551                         break;
552                 case Send:
553                 case Insert:
554                 case Aux:
555                         /* XXX FIX ME this is wrong, we need per-delivery muting */
556                         mp = MuteMaster::PreFader;
557                         break;
558                 }
559                 
560                 if (!_solo_isolated && _session.soloing()) {
561                         desired_gain = min (Config->get_solo_mute_gain(), _mute_master->mute_gain_at (mp));
562
563                 } else {
564
565                         desired_gain = _mute_master->mute_gain_at (mp);
566                 }
567
568         }
569
570         return desired_gain;
571 }
572
573 void
574 Delivery::no_outs_cuz_we_no_monitor (bool yn)
575 {
576         _no_outs_cuz_we_no_monitor = yn;
577 }
578
579 bool
580 Delivery::set_name (const std::string& name)
581 {
582         bool ret = IOProcessor::set_name (name);
583
584         if (ret) {
585                 ret = _panner->set_name (name);
586         }
587
588         return ret;
589 }
590
591 void
592 Delivery::output_changed (IOChange change, void* /*src*/)
593 {
594         if (change & ARDOUR::ConfigurationChanged) {
595                 reset_panner ();
596         }
597 }
598