Fix a tiny memory-leak when calling vfork
[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/enum_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 "pbd/i18n.h"
38
39 namespace PBD {
40         DEFINE_ENUM_CONVERT(ARDOUR::Delivery::Role);
41 }
42
43 namespace ARDOUR { class Panner; }
44
45 using namespace std;
46 using namespace PBD;
47 using namespace ARDOUR;
48
49 PBD::Signal0<void>            Delivery::PannersLegal;
50 bool                          Delivery::panners_legal = false;
51
52 /* deliver to an existing IO object */
53
54 Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
55                     boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
56         : IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name)
57         , _role (r)
58         , _output_buffers (new BufferSet())
59         , _current_gain (GAIN_COEFF_UNITY)
60         , _no_outs_cuz_we_no_monitor (false)
61         , _mute_master (mm)
62         , _no_panner_reset (false)
63 {
64         if (pannable) {
65                 bool is_send = false;
66                 if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback)) is_send = true;
67                 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send));
68         }
69
70         _display_to_user = false;
71
72         if (_output) {
73                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
74         }
75 }
76
77 /* deliver to a new IO object */
78
79 Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
80         : IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name, "", DataType::AUDIO, (r == Send))
81         , _role (r)
82         , _output_buffers (new BufferSet())
83         , _current_gain (GAIN_COEFF_UNITY)
84         , _no_outs_cuz_we_no_monitor (false)
85         , _mute_master (mm)
86         , _no_panner_reset (false)
87 {
88         if (pannable) {
89                 bool is_send = false;
90                 if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback)) is_send = true;
91                 _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send));
92         }
93
94         _display_to_user = false;
95
96         if (_output) {
97                 _output->changed.connect_same_thread (*this, boost::bind (&Delivery::output_changed, this, _1, _2));
98         }
99 }
100
101
102 Delivery::~Delivery()
103 {
104         DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
105
106         /* this object should vanish from any signal callback lists
107            that it is on before we get any further. The full qualification
108            of the method name is not necessary, but is here to make it
109            clear that this call is about signals, not data flow connections.
110         */
111
112         ScopedConnectionList::drop_connections ();
113
114         delete _output_buffers;
115 }
116
117 std::string
118 Delivery::display_name () const
119 {
120         switch (_role) {
121         case Main:
122                 return _("main outs");
123                 break;
124         case Listen:
125                 return _("listen");
126                 break;
127         case Send:
128         case Insert:
129         default:
130                 return name();
131         }
132 }
133
134 bool
135 Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out)
136 {
137         if (_role == Main) {
138
139                 /* the out buffers will be set to point to the port output buffers
140                    of our output object.
141                 */
142
143                 if (_output) {
144                         if (_output->n_ports() != ChanCount::ZERO) {
145                                 /* increase number of output ports if the processor chain requires it */
146                                 out = ChanCount::max (_output->n_ports(), in);
147                                 return true;
148                         } else {
149                                 /* not configured yet - we will passthru */
150                                 out = in;
151                                 return true;
152                         }
153                 } else {
154                         fatal << "programming error: this should never be reached" << endmsg;
155                         abort(); /*NOTREACHED*/
156                 }
157
158
159         } else if (_role == Insert) {
160
161                 /* the output buffers will be filled with data from the *input* ports
162                    of this Insert.
163                 */
164
165                 if (_input) {
166                         if (_input->n_ports() != ChanCount::ZERO) {
167                                 out = _input->n_ports();
168                                 return true;
169                         } else {
170                                 /* not configured yet - we will passthru */
171                                 out = in;
172                                 return true;
173                         }
174                 } else {
175                         fatal << "programming error: this should never be reached" << endmsg;
176                         abort(); /*NOTREACHED*/
177                 }
178
179         } else {
180                 fatal << "programming error: this should never be reached" << endmsg;
181         }
182
183         return false;
184 }
185
186 /** Caller must hold process lock */
187 bool
188 Delivery::configure_io (ChanCount in, ChanCount out)
189 {
190 #ifndef NDEBUG
191         bool r = AudioEngine::instance()->process_lock().trylock();
192         assert (!r && "trylock inside Delivery::configure_io");
193 #endif
194
195         /* check configuration by comparison with our I/O port configuration, if appropriate.
196            see ::can_support_io_configuration() for comments
197         */
198
199         if (_role == Main) {
200
201                 if (_output) {
202                         if (_output->n_ports() != out) {
203                                 if (_output->n_ports() != ChanCount::ZERO) {
204                                         _output->ensure_io (out, false, this);
205                                 } else {
206                                         /* I/O not yet configured */
207                                 }
208                         }
209                 }
210
211         } else if (_role == Insert) {
212
213                 if (_input) {
214                         if (_input->n_ports() != in) {
215                                 if (_input->n_ports() != ChanCount::ZERO) {
216                                         fatal << _name << " programming error: configure_io called with " << in << " and " << out << " with " << _input->n_ports() << " input ports" << endmsg;
217                                         abort(); /*NOTREACHED*/
218                                 } else {
219                                         /* I/O not yet configured */
220                                 }
221                         }
222                 }
223
224         }
225
226         if (!Processor::configure_io (in, out)) {
227                 return false;
228         }
229
230         reset_panner ();
231
232         return true;
233 }
234
235 void
236 Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double /*speed*/, pframes_t nframes, bool result_required)
237 {
238         assert (_output);
239
240         PortSet& ports (_output->ports());
241         gain_t tgain;
242
243         if (ports.num_ports () == 0) {
244                 goto out;
245         }
246
247         if (!_active && !_pending_active) {
248                 _output->silence (nframes);
249                 goto out;
250         }
251
252         /* this setup is not just for our purposes, but for anything that comes after us in the
253          * processing pathway that wants to use this->output_buffers() for some reason.
254          */
255
256         // TODO delayline -- latency-compensation
257         output_buffers().get_backend_port_addresses (ports, nframes);
258
259         // this Delivery processor is not a derived type, and thus we assume
260         // we really can modify the buffers passed in (it is almost certainly
261         // the main output stage of a Route). Contrast with Send::run()
262         // which cannot do this.
263
264         tgain = target_gain ();
265
266         if (tgain != _current_gain) {
267                 /* target gain has changed */
268
269                 _current_gain = Amp::apply_gain (bufs, _session.nominal_sample_rate(), nframes, _current_gain, tgain);
270
271         } else if (tgain < GAIN_COEFF_SMALL) {
272
273                 /* we were quiet last time, and we're still supposed to be quiet.
274                          Silence the outputs, and make sure the buffers are quiet too,
275                          */
276
277                 _output->silence (nframes);
278                 if (result_required) {
279                         bufs.set_count (output_buffers().count ());
280                         Amp::apply_simple_gain (bufs, nframes, GAIN_COEFF_ZERO);
281                 }
282                 goto out;
283
284         } else if (tgain != GAIN_COEFF_UNITY) {
285
286                 /* target gain has not changed, but is not unity */
287                 Amp::apply_simple_gain (bufs, nframes, tgain);
288         }
289
290         // Speed quietning
291
292         if (fabs (_session.transport_speed()) > 1.5 && Config->get_quieten_at_speed ()) {
293                 Amp::apply_simple_gain (bufs, nframes, speed_quietning, false);
294         }
295
296         // Panning
297
298         if (_panshell && !_panshell->bypassed() && _panshell->panner()) {
299
300                 // Use the panner to distribute audio to output port buffers
301
302                 _panshell->run (bufs, output_buffers(), start_sample, end_sample, nframes);
303
304                 // non-audio data will not have been delivered by the panner
305
306                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
307                         if (*t != DataType::AUDIO && bufs.count().get(*t) > 0) {
308                                 _output->copy_to_outputs (bufs, *t, nframes, Port::port_offset());
309                         }
310                 }
311
312         } else {
313
314                 /* Do a 1:1 copy of data to output ports
315
316                    Audio is handled separately because we use 0 for the offset,
317                    since the port offset is only used for timestamped events
318                    (i.e. MIDI).
319                 */
320
321                 if (bufs.count().n_audio() > 0) {
322                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
323                 }
324
325                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
326                         if (*t != DataType::AUDIO && bufs.count().get(*t) > 0) {
327                                 _output->copy_to_outputs (bufs, *t, nframes, Port::port_offset());
328                         }
329                 }
330         }
331
332         if (result_required) {
333                 /* "bufs" are internal, meaning they should never reflect
334                    split-cycle offsets. So shift events back in time from where
335                    they were for the external buffers associated with Ports.
336                 */
337
338                 const BufferSet& outs (output_buffers());
339                 bufs.set_count (output_buffers().count ());
340
341                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
342
343                         uint32_t n = 0;
344                         for (BufferSet::iterator b = bufs.begin (*t); b != bufs.end (*t); ++b) {
345                                 if (outs.count ().get (*t) <= n) {
346                                         continue;
347                                 }
348                                 b->read_from (outs.get (*t, n++), nframes, (*t == DataType::AUDIO ? 0 : -Port::port_offset()));
349                         }
350                 }
351         }
352
353 out:
354         _active = _pending_active;
355 }
356
357 XMLNode&
358 Delivery::state ()
359 {
360         XMLNode& node (IOProcessor::state ());
361
362         if (_role & Main) {
363                 node.set_property("type", "main-outs");
364         } else if (_role & Listen) {
365                 node.set_property("type", "listen");
366         } else {
367                 node.set_property("type", "delivery");
368         }
369
370         node.set_property("role", _role);
371
372         if (_panshell) {
373                 node.add_child_nocopy (_panshell->get_state ());
374                 if (_panshell->pannable()) {
375                         node.add_child_nocopy (_panshell->pannable()->get_state ());
376                 }
377         }
378
379         return node;
380 }
381
382 int
383 Delivery::set_state (const XMLNode& node, int version)
384 {
385         if (IOProcessor::set_state (node, version)) {
386                 return -1;
387         }
388
389         if (node.get_property ("role", _role)) {
390                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
391         } else {
392                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
393         }
394
395         XMLNode* pan_node = node.child (X_("PannerShell"));
396
397         if (pan_node && _panshell) {
398                 _panshell->set_state (*pan_node, version);
399         }
400
401         reset_panner ();
402
403         XMLNode* pannnode = node.child (X_("Pannable"));
404         if (_panshell && _panshell->panner() && pannnode) {
405                 _panshell->pannable()->set_state (*pannnode, version);
406         }
407
408         return 0;
409 }
410
411 void
412 Delivery::unpan ()
413 {
414         /* caller must hold process lock */
415
416         _panshell.reset ();
417 }
418
419 uint32_t
420 Delivery::pan_outs () const
421 {
422         if (_output) {
423                 return _output->n_ports().n_audio();
424         }
425
426         return _configured_output.n_audio();
427 }
428
429 void
430 Delivery::reset_panner ()
431 {
432         if (panners_legal) {
433                 if (!_no_panner_reset) {
434
435                         if (_panshell && _role != Insert && _role != Listen) {
436                                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
437                         }
438                 }
439
440         } else {
441                 panner_legal_c.disconnect ();
442                 PannersLegal.connect_same_thread (panner_legal_c, boost::bind (&Delivery::panners_became_legal, this));
443         }
444 }
445
446 void
447 Delivery::panners_became_legal ()
448 {
449         if (_panshell && _role != Insert) {
450                 _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
451         }
452
453         panner_legal_c.disconnect ();
454 }
455
456 void
457 Delivery::defer_pan_reset ()
458 {
459         _no_panner_reset = true;
460 }
461
462 void
463 Delivery::allow_pan_reset ()
464 {
465         _no_panner_reset = false;
466         reset_panner ();
467 }
468
469
470 int
471 Delivery::disable_panners ()
472 {
473         panners_legal = false;
474         return 0;
475 }
476
477 void
478 Delivery::reset_panners ()
479 {
480         panners_legal = true;
481         PannersLegal ();
482 }
483
484 void
485 Delivery::flush_buffers (samplecnt_t nframes)
486 {
487         /* io_lock, not taken: function must be called from Session::process() calltree */
488
489         if (!_output) {
490                 return;
491         }
492
493         PortSet& ports (_output->ports());
494
495         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
496                 i->flush_buffers (nframes);
497         }
498 }
499
500 void
501 Delivery::non_realtime_transport_stop (samplepos_t now, bool flush)
502 {
503         Processor::non_realtime_transport_stop (now, flush);
504
505         if (_panshell) {
506                 _panshell->pannable()->non_realtime_transport_stop (now, flush);
507         }
508
509         if (_output) {
510                 PortSet& ports (_output->ports());
511
512                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
513                         i->transport_stopped ();
514                 }
515         }
516 }
517
518 void
519 Delivery::realtime_locate ()
520 {
521         if (_output) {
522                 PortSet& ports (_output->ports());
523
524                 for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
525                         i->realtime_locate ();
526                 }
527         }
528 }
529
530 gain_t
531 Delivery::target_gain ()
532 {
533         /* if we've been requested to deactivate, our target gain is zero */
534
535         if (!_pending_active) {
536                 return GAIN_COEFF_ZERO;
537         }
538
539         /* if we've been told not to output because its a monitoring situation and
540            we're not monitoring, then be quiet.
541         */
542
543         if (_no_outs_cuz_we_no_monitor) {
544                 return GAIN_COEFF_ZERO;
545         }
546
547         MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
548
549         switch (_role) {
550                 case Main:
551                         mp = MuteMaster::Main;
552                         break;
553                 case Listen:
554                         mp = MuteMaster::Listen;
555                         break;
556                 case Send:
557                 case Insert:
558                 case Aux:
559                 case Foldback:
560                         if (_pre_fader) {
561                                 mp = MuteMaster::PreFader;
562                         } else {
563                                 mp = MuteMaster::PostFader;
564                         }
565                         break;
566         }
567
568         gain_t desired_gain = _mute_master->mute_gain_at (mp);
569
570         if (_role == Listen && _session.monitor_out() && !_session.listening()) {
571
572                 /* nobody is soloed, and this delivery is a listen-send to the
573                  * control/monitor/listen bus, we should be silent since
574                  * it gets its signal from the master out.
575                  */
576
577                 desired_gain = GAIN_COEFF_ZERO;
578         }
579
580         return desired_gain;
581 }
582
583 void
584 Delivery::no_outs_cuz_we_no_monitor (bool yn)
585 {
586         _no_outs_cuz_we_no_monitor = yn;
587 }
588
589 bool
590 Delivery::set_name (const std::string& name)
591 {
592         bool ret = IOProcessor::set_name (name);
593
594         if (ret && _panshell) {
595                 ret = _panshell->set_name (name);
596         }
597
598         return ret;
599 }
600
601 bool ignore_output_change = false;
602
603 void
604 Delivery::output_changed (IOChange change, void* /*src*/)
605 {
606         if (change.type & IOChange::ConfigurationChanged) {
607                 reset_panner ();
608                 _output_buffers->attach_buffers (_output->ports ());
609         }
610 }
611
612 boost::shared_ptr<Panner>
613 Delivery::panner () const
614 {
615         if (_panshell) {
616                 return _panshell->panner();
617         } else {
618                 return boost::shared_ptr<Panner>();
619         }
620 }
621