make strip-as-GUI-for-send work for metering too ; frame around session summary widge...
[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 sigc::signal<void,nframes_t> Delivery::CycleStart;
46 sigc::signal<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 (mem_fun (*this, &Delivery::output_changed));
68         }
69
70         CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
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 (mem_fun (*this, &Delivery::output_changed));
92         }
93
94         CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
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 (mem_fun (*this, &Delivery::output_changed));
120         }
121
122         CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
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 (mem_fun (*this, &Delivery::output_changed));
148         }
149
150         CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
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)
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                 Amp::apply_simple_gain (bufs, nframes, 0.0);
322                 goto out;
323
324         } else if (tgain != 1.0) {
325
326                 /* target gain has not changed, but is not unity */
327                 Amp::apply_simple_gain (bufs, nframes, tgain);
328         }
329
330         if (_panner && _panner->npanners() && !_panner->bypassed()) {
331
332                 // Use the panner to distribute audio to output port buffers
333
334                 _panner->run (bufs, output_buffers(), start_frame, end_frame, nframes);
335
336         } else {
337                 // Do a 1:1 copy of data to output ports
338
339                 if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
340                         _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, _output_offset);
341                 }
342
343                 if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
344                         _output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset);
345                 }
346         }
347
348   out:
349         _active = _pending_active;
350 }
351
352 XMLNode&
353 Delivery::state (bool full_state)
354 {
355         XMLNode& node (IOProcessor::state (full_state));
356
357         if (_role & Main) {
358                 node.add_property("type", "main-outs");
359         } else if (_role & Listen) {
360                 node.add_property("type", "listen");
361         } else {
362                 node.add_property("type", "delivery");
363         }
364
365         node.add_property("role", enum_2_string(_role));
366         node.add_child_nocopy (_panner->state (full_state));
367
368         return node;
369 }
370
371 int
372 Delivery::set_state (const XMLNode& node, int version)
373 {
374         const XMLProperty* prop;
375
376         if (IOProcessor::set_state (node, version)) {
377                 return -1;
378         }
379
380         if ((prop = node.property ("role")) != 0) {
381                 _role = Role (string_2_enum (prop->value(), _role));
382                 // std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
383         } else {
384                 // std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
385         }
386
387         XMLNode* pan_node = node.child (X_("Panner"));
388
389         if (pan_node) {
390                 _panner->set_state (*pan_node, version);
391         }
392
393         reset_panner ();
394
395         return 0;
396 }
397
398 void
399 Delivery::reset_panner ()
400 {
401         if (panners_legal) {
402                 if (!no_panner_reset) {
403
404                         uint32_t ntargets;
405
406                         if (_output) {
407                                 ntargets = _output->n_ports().n_audio();
408                         } else {
409                                 ntargets = _configured_output.n_audio();
410                         }
411
412                         _panner->reset (ntargets, pans_required());
413                 }
414         } else {
415                 panner_legal_c.disconnect ();
416                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &Delivery::panners_became_legal));
417         }
418 }
419
420 int
421 Delivery::panners_became_legal ()
422 {
423         uint32_t ntargets;
424
425         if (_output) {
426                 ntargets = _output->n_ports().n_audio();
427         } else {
428                 ntargets = _configured_output.n_audio();
429         }
430
431         _panner->reset (ntargets, pans_required());
432         _panner->load (); // automation
433         panner_legal_c.disconnect ();
434         return 0;
435 }
436
437 void
438 Delivery::defer_pan_reset ()
439 {
440         no_panner_reset = true;
441 }
442
443 void
444 Delivery::allow_pan_reset ()
445 {
446         no_panner_reset = false;
447         reset_panner ();
448 }
449
450
451 int
452 Delivery::disable_panners (void)
453 {
454         panners_legal = false;
455         return 0;
456 }
457
458 int
459 Delivery::reset_panners ()
460 {
461         panners_legal = true;
462         return PannersLegal ();
463 }
464
465
466 void
467 Delivery::start_pan_touch (uint32_t which)
468 {
469         if (which < _panner->npanners()) {
470                 _panner->pan_control(which)->start_touch();
471         }
472 }
473
474 void
475 Delivery::end_pan_touch (uint32_t which)
476 {
477         if (which < _panner->npanners()) {
478                 _panner->pan_control(which)->stop_touch();
479         }
480
481 }
482
483 void
484 Delivery::transport_stopped (sframes_t frame)
485 {
486         _panner->transport_stopped (frame);
487 }
488
489 void
490 Delivery::flush (nframes_t nframes, nframes64_t time)
491 {
492         /* io_lock, not taken: function must be called from Session::process() calltree */
493
494         PortSet& ports (_output->ports());
495
496         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
497                 (*i).flush_buffers (nframes, time, _output_offset);
498         }
499 }
500
501 void
502 Delivery::transport_stopped ()
503 {
504         /* turn off any notes that are on */
505
506         PortSet& ports (_output->ports());
507
508         for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
509                 (*i).transport_stopped ();
510         }
511 }
512
513 gain_t
514 Delivery::target_gain ()
515 {
516         /* if we've been requested to deactivate, our target gain is zero */
517
518         if (!_pending_active) {
519                 return 0.0;
520         }
521
522         /* if we've been told not to output because its a monitoring situation and
523            we're not monitoring, then be quiet.
524         */
525
526         if (_no_outs_cuz_we_no_monitor) {
527                 return 0.0;
528         }
529
530         gain_t desired_gain;
531
532         if (_solo_level) {
533                 desired_gain = 1.0;
534         } else {
535
536                 MuteMaster::MutePoint mp;
537
538                 switch (_role) {
539                 case Main:
540                         mp = MuteMaster::Main;
541                         break;
542                 case Listen:
543                         mp = MuteMaster::Listen;
544                         break;
545                 case Send:
546                 case Insert:
547                 case Aux:
548                         /* XXX FIX ME this is wrong, we need per-delivery muting */
549                         mp = MuteMaster::PreFader;
550                         break;
551                 }
552
553                 if (_solo_isolated) {
554
555                         /* ... but we are isolated from all that nonsense */
556
557                         desired_gain = _mute_master->mute_gain_at (mp);
558
559                 } else if (_session.soloing()) {
560
561                         desired_gain = min (Config->get_solo_mute_gain(), _mute_master->mute_gain_at (mp));
562
563                 } else {
564                         desired_gain = _mute_master->mute_gain_at (mp);
565                 }
566         }
567
568         return desired_gain;
569 }
570
571 void
572 Delivery::no_outs_cuz_we_no_monitor (bool yn)
573 {
574         _no_outs_cuz_we_no_monitor = yn;
575 }
576
577 bool
578 Delivery::set_name (const std::string& name)
579 {
580         bool ret = IOProcessor::set_name (name);
581
582         if (ret) {
583                 ret = _panner->set_name (name);
584         }
585
586         return ret;
587 }
588
589 void
590 Delivery::output_changed (IOChange change, void* /*src*/)
591 {
592         if (change & ARDOUR::ConfigurationChanged) {
593                 reset_panner ();
594         }
595 }
596