if a request to reset the speed to zero as the default arrives when stopped, reset...
[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) const
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         assert (!AudioEngine::instance()->process_lock().trylock());
183
184         /* check configuration by comparison with our I/O port configuration, if appropriate.
185            see ::can_support_io_configuration() for comments
186         */
187
188         if (_role == Main) {
189
190                 if (_output) {
191                         if (_output->n_ports() != out) {
192                                 if (_output->n_ports() != ChanCount::ZERO) {
193                                         _output->ensure_io (out, false, this);
194                                 } else {
195                                         /* I/O not yet configured */
196                                 }
197                         }
198                 }
199
200         } else if (_role == Insert) {
201
202                 if (_input) {
203                         if (_input->n_ports() != in) {
204                                 if (_input->n_ports() != ChanCount::ZERO) {
205                                         fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
206                                         /*NOTREACHED*/
207                                 } else {
208                                         /* I/O not yet configured */
209                                 }
210                         }
211                 }
212
213         }
214
215         if (!Processor::configure_io (in, out)) {
216                 return false;
217         }
218
219         reset_panner ();
220
221         return true;
222 }
223
224 void
225 Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
226 {
227         assert (_output);
228
229         PortSet& ports (_output->ports());
230         gain_t tgain;
231
232         if (_output->n_ports ().get (_output->default_type()) == 0) {
233                 goto out;
234         }
235
236         if (!_active && !_pending_active) {
237                 _output->silence (nframes);
238                 goto out;
239         }
240
241         /* this setup is not just for our purposes, but for anything that comes after us in the
242            processing pathway that wants to use this->output_buffers() for some reason.
243         */
244
245         output_buffers().get_jack_port_addresses (ports, nframes);
246
247         // this Delivery processor is not a derived type, and thus we assume
248         // we really can modify the buffers passed in (it is almost certainly
249         // the main output stage of a Route). Contrast with Send::run()
250         // which cannot do this.
251
252         tgain = target_gain ();
253
254         if (tgain != _current_gain) {
255                 /* target gain has changed */
256
257                 Amp::apply_gain (bufs, nframes, _current_gain, tgain);
258                 _current_gain = tgain;
259
260         } else if (tgain == 0.0) {
261
262                 /* we were quiet last time, and we're still supposed to be quiet.
263                    Silence the outputs, and make sure the buffers are quiet too,
264                 */
265
266                 _output->silence (nframes);
267                 if (result_required) {
268                         bufs.set_count (output_buffers().count ());
269                         Amp::apply_simple_gain (bufs, nframes, 0.0);
270                 }
271                 goto out;
272
273         } else if (tgain != 1.0) {
274
275                 /* target gain has not changed, but is not unity */
276                 Amp::apply_simple_gain (bufs, nframes, tgain);
277         }
278
279         if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
280
281                 // Use the panner to distribute audio to output port buffers
282
283                 _panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
284
285                 // MIDI data will not have been delivered by the panner
286
287                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
288                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
289                 }
290
291         } else {
292
293                 // Do a 1:1 copy of data to output ports
294
295                 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
296                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
297                 }
298
299                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
300                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
301                 }
302         }
303
304         if (result_required) {
305                 bufs.read_from (output_buffers (), nframes);
306         }
307
308   out:
309         _active = _pending_active;
310 }
311
312 XMLNode&
313 Delivery::state (bool full_state)
314 {
315         XMLNode& node (IOProcessor::state (full_state));
316
317         if (_role & Main) {
318                 node.add_property("type", "main-outs");
319         } else if (_role & Listen) {
320                 node.add_property("type", "listen");
321         } else {
322                 node.add_property("type", "delivery");
323         }
324
325         node.add_property("role", enum_2_string(_role));
326
327         if (_panshell) {
328                 node.add_child_nocopy (_panshell->get_state ());
329         }
330
331         return node;
332 }
333
334 int
335 Delivery::set_state (const XMLNode& node, int version)
336 {
337         const XMLProperty* prop;
338
339         if (IOProcessor::set_state (node, version)) {
340                 return -1;
341         }
342
343         if ((prop = node.property ("role")) != 0) {
344                 _role = Role (string_2_enum (prop->value(), _role));
345                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
346         } else {
347                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
348         }
349
350         XMLNode* pan_node = node.child (X_("PannerShell"));
351
352         if (pan_node && _panshell) {
353                 _panshell->set_state (*pan_node, version);
354         }
355
356         reset_panner ();
357
358         return 0;
359 }
360
361 void
362 Delivery::unpan ()
363 {
364         /* caller must hold process lock */
365
366         _panshell.reset ();
367 }
368
369 uint32_t
370 Delivery::pan_outs () const
371 {
372         if (_output) {
373                 return _output->n_ports().n_audio();
374         } 
375
376         return _configured_output.n_audio();
377 }
378
379 void
380 Delivery::reset_panner ()
381 {
382         if (panners_legal) {
383                 if (!_no_panner_reset) {
384
385                         if (_panshell) {
386                                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
387                                 
388                                 if (_role == Main) {
389                                         _panshell->pannable()->set_panner (_panshell->panner());
390                                 }
391                         }
392                 }
393
394         } else {
395                 panner_legal_c.disconnect ();
396                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
397         }
398 }
399
400 void
401 Delivery::panners_became_legal ()
402 {
403         if (_panshell) {
404                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
405                 
406                 if (_role == Main) {
407                         _panshell->pannable()->set_panner (_panshell->panner());
408                 }
409         }
410
411         panner_legal_c.disconnect ();
412 }
413
414 void
415 Delivery::defer_pan_reset ()
416 {
417         _no_panner_reset = true;
418 }
419
420 void
421 Delivery::allow_pan_reset ()
422 {
423         _no_panner_reset = false;
424         reset_panner ();
425 }
426
427
428 int
429 Delivery::disable_panners ()
430 {
431         panners_legal = false;
432         return 0;
433 }
434
435 void
436 Delivery::reset_panners ()
437 {
438         panners_legal = true;
439         PannersLegal ();
440 }
441
442 void
443 Delivery::flush_buffers (framecnt_t nframes)
444 {
445         /* io_lock, not taken: function must be called from Session::process() calltree */
446
447         if (!_output) {
448                 return;
449         }
450         
451         PortSet& ports (_output->ports());
452
453         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
454                 i->flush_buffers (nframes);
455         }
456 }
457
458 void
459 Delivery::transport_stopped (framepos_t now)
460 {
461         Processor::transport_stopped (now);
462
463         if (_panshell) {
464                 _panshell->pannable()->transport_stopped (now);
465         }
466
467         if (_output) {
468                 PortSet& ports (_output->ports());
469
470                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
471                         i->transport_stopped ();
472                 }
473         }
474 }
475
476 void
477 Delivery::realtime_locate ()
478 {
479         if (_output) {
480                 PortSet& ports (_output->ports());
481
482                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
483                         i->realtime_locate ();
484                 }
485         }
486 }
487
488 gain_t
489 Delivery::target_gain ()
490 {
491         /* if we've been requested to deactivate, our target gain is zero */
492
493         if (!_pending_active) {
494                 return 0.0;
495         }
496
497         /* if we've been told not to output because its a monitoring situation and
498            we're not monitoring, then be quiet.
499         */
500
501         if (_no_outs_cuz_we_no_monitor) {
502                 return 0.0;
503         }
504
505         MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
506
507         switch (_role) {
508         case Main:
509                 mp = MuteMaster::Main;
510                 break;
511         case Listen:
512                 mp = MuteMaster::Listen;
513                 break;
514         case Send:
515         case Insert:
516         case Aux:
517                 if (_pre_fader) {
518                         mp = MuteMaster::PreFader;
519                 } else {
520                         mp = MuteMaster::PostFader;
521                 }
522                 break;
523         }
524
525         gain_t desired_gain = _mute_master->mute_gain_at (mp);
526
527         if (_role == Listen && _session.monitor_out() && !_session.listening()) {
528
529                 /* nobody is soloed, and this delivery is a listen-send to the
530                    control/monitor/listen bus, we should be silent since
531                    it gets its signal from the master out.
532                 */
533
534                 desired_gain = 0.0;
535
536         }
537
538         return desired_gain;
539 }
540
541 void
542 Delivery::no_outs_cuz_we_no_monitor (bool yn)
543 {
544         _no_outs_cuz_we_no_monitor = yn;
545 }
546
547 bool
548 Delivery::set_name (const std::string& name)
549 {
550         bool ret = IOProcessor::set_name (name);
551
552         if (ret) {
553                 ret = _panshell->set_name (name);
554         }
555
556         return ret;
557 }
558
559 bool ignore_output_change = false;
560
561 void
562 Delivery::output_changed (IOChange change, void* /*src*/)
563 {
564         if (change.type & IOChange::ConfigurationChanged) {
565                 reset_panner ();
566                 _output_buffers->attach_buffers (_output->ports ());
567         }
568 }
569
570 boost::shared_ptr<Panner>
571 Delivery::panner () const
572 {
573         if (_panshell) {
574                 return _panshell->panner();
575         } else {
576                 return boost::shared_ptr<Panner>();
577         }
578 }
579