make Gtkmm2ext::Popup::touch() thread-safe (again; it used to be in the 0.99 era)
[ardour.git] / libs / ardour / io.cc
1 /*
2     Copyright (C) 2000 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <fstream>
21 #include <algorithm>
22 #include <unistd.h>
23 #include <locale.h>
24 #include <errno.h>
25
26 #include <sigc++/bind.h>
27
28 #include <glibmm.h>
29 #include <glibmm/thread.h>
30
31 #include <pbd/xml++.h>
32 #include <pbd/replace_all.h>
33
34 #include <ardour/audioengine.h>
35 #include <ardour/io.h>
36 #include <ardour/route.h>
37 #include <ardour/port.h>
38 #include <ardour/connection.h>
39 #include <ardour/session.h>
40 #include <ardour/cycle_timer.h>
41 #include <ardour/panner.h>
42 #include <ardour/dB.h>
43
44 #include "i18n.h"
45
46 #include <cmath>
47
48 /*
49   A bug in OS X's cmath that causes isnan() and isinf() to be 
50   "undeclared". the following works around that
51 */
52
53 #if defined(__APPLE__) && defined(__MACH__)
54 extern "C" int isnan (double);
55 extern "C" int isinf (double);
56 #endif
57
58 #define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock())
59
60 using namespace std;
61 using namespace ARDOUR;
62 using namespace PBD;
63
64 nframes_t    IO::_automation_interval = 0;
65 const string IO::state_node_name = "IO";
66 bool         IO::connecting_legal = false;
67 bool         IO::ports_legal = false;
68 bool         IO::panners_legal = false;
69 sigc::signal<void>                IO::Meter;
70 sigc::signal<int>                 IO::ConnectingLegal;
71 sigc::signal<int>                 IO::PortsLegal;
72 sigc::signal<int>                 IO::PannersLegal;
73 sigc::signal<void,uint32_t>  IO::MoreOutputs;
74 sigc::signal<int>                 IO::PortsCreated;
75
76 Glib::StaticMutex       IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
77
78 /* this is a default mapper of [0 .. 1.0] control values to a gain coefficient.
79    others can be imagined. 
80 */
81
82 static gain_t direct_control_to_gain (double fract) { 
83         /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
84         /* this maxes at +6dB */
85         return pow (2.0,(sqrt(sqrt(sqrt(fract)))*198.0-192.0)/6.0);
86 }
87
88 static double direct_gain_to_control (gain_t gain) { 
89         /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
90         if (gain == 0) return 0.0;
91         
92         return pow((6.0*log(gain)/log(2.0)+192.0)/198.0, 8.0);
93 }
94
95 static bool sort_ports_by_name (Port* a, Port* b)
96 {
97         return a->name() < b->name();
98 }
99
100
101 /** @param default_type The type of port that will be created by ensure_io
102  * and friends if no type is explicitly requested (to avoid breakage).
103  */
104 IO::IO (Session& s, string name,
105         int input_min, int input_max, int output_min, int output_max,
106         DataType default_type)
107         : _session (s),
108           _name (name),
109           _default_type(default_type),
110           _gain_control (X_("gaincontrol"), *this),
111           _gain_automation_curve (0.0, 2.0, 1.0),
112           _input_minimum (input_min),
113           _input_maximum (input_max),
114           _output_minimum (output_min),
115           _output_maximum (output_max)
116 {
117         _panner = new Panner (name, _session);
118         _active = true;
119         _gain = 1.0;
120         _desired_gain = 1.0;
121         _input_connection = 0;
122         _output_connection = 0;
123         pending_state_node = 0;
124         _ninputs = 0;
125         _noutputs = 0;
126         no_panner_reset = false;
127         deferred_state = 0;
128
129         apply_gain_automation = false;
130         _ignore_gain_on_deliver = false;
131         
132         last_automation_snapshot = 0;
133
134         _gain_automation_state = Off;
135         _gain_automation_style = Absolute;
136
137         {
138                 // IO::Meter is emitted from another thread so the
139                 // Meter signal must be protected.
140                 Glib::Mutex::Lock guard (m_meter_signal_lock);
141                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
142         }
143
144         _session.add_controllable (&_gain_control);
145 }
146
147 IO::IO (Session& s, const XMLNode& node, DataType dt)
148         : _session (s),
149           _default_type (dt),
150           _gain_control (X_("gaincontrol"), *this),
151           _gain_automation_curve (0, 0, 0) // all reset in set_state()
152 {
153         _panner = 0;
154         _active = true;
155         deferred_state = 0;
156         no_panner_reset = false;
157         _desired_gain = 1.0;
158         _gain = 1.0;
159         _input_connection = 0;
160         _output_connection = 0;
161         _ninputs = 0;
162         _noutputs = 0;
163
164         apply_gain_automation = false;
165         _ignore_gain_on_deliver = false;
166
167         set_state (node);
168
169         {
170                 // IO::Meter is emitted from another thread so the
171                 // Meter signal must be protected.
172                 Glib::Mutex::Lock guard (m_meter_signal_lock);
173                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
174         }
175
176         _session.add_controllable (&_gain_control);
177 }
178
179 IO::~IO ()
180 {
181         Glib::Mutex::Lock guard (m_meter_signal_lock);
182         
183         Glib::Mutex::Lock lm (io_lock);
184         vector<Port *>::iterator i;
185
186         {
187                 BLOCK_PROCESS_CALLBACK ();
188                 
189                 for (i = _inputs.begin(); i != _inputs.end(); ++i) {
190                         _session.engine().unregister_port (*i);
191                 }
192                 
193                 for (i = _outputs.begin(); i != _outputs.end(); ++i) {
194                         _session.engine().unregister_port (*i);
195                 }
196         }
197
198         m_meter_connection.disconnect();
199 }
200
201 void
202 IO::silence (nframes_t nframes, nframes_t offset)
203 {
204         /* io_lock, not taken: function must be called from Session::process() calltree */
205
206         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
207                 (*i)->silence (nframes, offset);
208         }
209 }
210
211 void
212 IO::apply_declick (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity)
213 {
214         nframes_t declick = min ((nframes_t)128, nframes);
215         gain_t delta;
216         Sample *buffer;
217         double fractional_shift;
218         double fractional_pos;
219         gain_t polscale = invert_polarity ? -1.0f : 1.0f;
220
221         if (nframes == 0) return;
222         
223         fractional_shift = -1.0/declick;
224
225         if (target < initial) {
226                 /* fade out: remove more and more of delta from initial */
227                 delta = -(initial - target);
228         } else {
229                 /* fade in: add more and more of delta from initial */
230                 delta = target - initial;
231         }
232
233         for (uint32_t n = 0; n < nbufs; ++n) {
234
235                 buffer = bufs[n];
236                 fractional_pos = 1.0;
237
238                 for (nframes_t nx = 0; nx < declick; ++nx) {
239                         buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos))));
240                         fractional_pos += fractional_shift;
241                 }
242                 
243                 /* now ensure the rest of the buffer has the target value
244                    applied, if necessary.
245                 */
246
247                 if (declick != nframes) {
248                         float this_target;
249
250                         if (invert_polarity) {
251                                 this_target = -target;
252                         } else { 
253                                 this_target = target;
254                         }
255
256                         if (this_target == 0.0) {
257                                 memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
258                         } else if (this_target != 1.0) {
259                                 for (nframes_t nx = declick; nx < nframes; ++nx) {
260                                         buffer[nx] *= this_target;
261                                 }
262                         }
263                 }
264         }
265 }
266
267 void
268 IO::pan_automated (vector<Sample*>& bufs, uint32_t nbufs, nframes_t start, nframes_t end, nframes_t nframes, nframes_t offset)
269 {
270         Sample* dst;
271
272         /* io_lock, not taken: function must be called from Session::process() calltree */
273
274         if (_noutputs == 0) {
275                 return;
276         }
277
278         if (_noutputs == 1) {
279
280                 dst = output(0)->get_buffer (nframes) + offset;
281
282                 for (uint32_t n = 0; n < nbufs; ++n) {
283                         if (bufs[n] != dst) {
284                                 memcpy (dst, bufs[n], sizeof (Sample) * nframes);
285                         } 
286                 }
287
288                 output(0)->mark_silence (false);
289
290                 return;
291         }
292
293         uint32_t o;
294         vector<Port *>::iterator out;
295         vector<Sample *>::iterator in;
296         Panner::iterator pan;
297         Sample* obufs[_noutputs];
298
299         /* the terrible silence ... */
300
301         for (out = _outputs.begin(), o = 0; out != _outputs.end(); ++out, ++o) {
302                 obufs[o] = (*out)->get_buffer (nframes) + offset;
303                 memset (obufs[o], 0, sizeof (Sample) * nframes);
304                 (*out)->mark_silence (false);
305         }
306
307         uint32_t n;
308
309         for (pan = _panner->begin(), n = 0; n < nbufs; ++n, ++pan) {
310                 (*pan)->distribute_automated (bufs[n], obufs, start, end, nframes, _session.pan_automation_buffer());
311         }
312 }
313
314 void
315 IO::pan (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff)
316 {
317         Sample* dst;
318         Sample* src;
319
320         /* io_lock, not taken: function must be called from Session::process() calltree */
321
322         if (_noutputs == 0) {
323                 return;
324         }
325
326         /* the panner can be empty if there are no inputs to the 
327            route, but still outputs
328         */
329
330         if (_panner->bypassed() || _panner->empty()) {
331                 deliver_output_no_pan (bufs, nbufs, nframes, offset);
332                 return;
333         }
334
335         if (_noutputs == 1) {
336
337                 dst = output(0)->get_buffer (nframes) + offset;
338
339                 if (gain_coeff == 0.0f) {
340
341                         /* only one output, and gain was zero, so make it silent */
342
343                         memset (dst, 0, sizeof (Sample) * nframes); 
344                         
345                 } else if (gain_coeff == 1.0f){
346
347                         /* mix all buffers into the output */
348
349                         uint32_t n;
350                         
351                         memcpy (dst, bufs[0], sizeof (Sample) * nframes);
352                         
353                         for (n = 1; n < nbufs; ++n) {
354                                 Session::mix_buffers_no_gain(dst,bufs[n],nframes);
355                         }
356
357                         output(0)->mark_silence (false);
358
359                 } else {
360
361                         /* mix all buffers into the output, scaling them all by the gain */
362
363                         uint32_t n;
364
365                         src = bufs[0];
366                         
367                         for (nframes_t n = 0; n < nframes; ++n) {
368                                 dst[n] = src[n] * gain_coeff;
369                         }       
370
371                         for (n = 1; n < nbufs; ++n) {
372                                 Session::mix_buffers_with_gain(dst,bufs[n],nframes,gain_coeff);
373                         }
374                         
375                         output(0)->mark_silence (false);
376                 }
377
378                 return;
379         }
380
381         uint32_t o;
382         vector<Port *>::iterator out;
383         vector<Sample *>::iterator in;
384         Panner::iterator pan;
385         Sample* obufs[_noutputs];
386
387         /* the terrible silence ... */
388
389         /* XXX this is wasteful but i see no way to avoid it */
390         
391         for (out = _outputs.begin(), o = 0; out != _outputs.end(); ++out, ++o) {
392                 obufs[o] = (*out)->get_buffer (nframes) + offset;
393                 memset (obufs[o], 0, sizeof (Sample) * nframes);
394                 (*out)->mark_silence (false);
395         }
396
397         uint32_t n;
398
399         for (pan = _panner->begin(), n = 0; n < nbufs; ++n) {
400                 Panner::iterator tmp;
401
402                 tmp = pan;
403                 ++tmp;
404
405                 (*pan)->distribute (bufs[n], obufs, gain_coeff, nframes);
406
407                 if (tmp != _panner->end()) {
408                         pan = tmp;
409                 }
410         }
411 }
412
413 void
414 IO::deliver_output (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
415 {
416         /* io_lock, not taken: function must be called from Session::process() calltree */
417
418         if (_noutputs == 0) {
419                 return;
420         }
421         
422         if (_panner->bypassed() || _panner->empty()) {
423                 deliver_output_no_pan (bufs, nbufs, nframes, offset);
424                 return;
425         }
426
427
428         gain_t dg;
429         gain_t pangain = _gain;
430         
431         {
432                 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
433                 
434                 if (dm.locked()) {
435                         dg = _desired_gain;
436                 } else {
437                         dg = _gain;
438                 }
439         }
440
441         if (dg != _gain) {
442                 apply_declick (bufs, nbufs, nframes, _gain, dg, false);
443                 _gain = dg;
444                 pangain = 1.0f;
445         } 
446
447         /* simple, non-automation panning to outputs */
448
449         if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
450                 pan (bufs, nbufs, nframes, offset, pangain * speed_quietning);
451         } else {
452                 pan (bufs, nbufs, nframes, offset, pangain);
453         }
454 }
455
456 void
457 IO::deliver_output_no_pan (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
458 {
459         /* io_lock, not taken: function must be called from Session::process() calltree */
460
461         if (_noutputs == 0) {
462                 return;
463         }
464
465         gain_t dg;
466         gain_t old_gain = _gain;
467
468         if (apply_gain_automation || _ignore_gain_on_deliver) {
469
470                 /* gain has already been applied by automation code. do nothing here except
471                    speed quietning.
472                 */
473
474                 _gain = 1.0f;
475                 dg = _gain;
476                 
477         } else {
478
479                 Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
480                 
481                 if (dm.locked()) {
482                         dg = _desired_gain;
483                 } else {
484                         dg = _gain;
485                 }
486         }
487
488         Sample* src;
489         Sample* dst;
490         uint32_t i;
491         vector<Port*>::iterator o;
492         vector<Sample*> outs;
493         gain_t actual_gain;
494
495         /* reduce nbufs to the index of the last input buffer */
496
497         nbufs--;
498
499         if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
500                 actual_gain = _gain * speed_quietning;
501         } else {
502                 actual_gain = _gain;
503         }
504         
505         for (o = _outputs.begin(), i = 0; o != _outputs.end(); ++o, ++i) {
506
507                 dst = (*o)->get_buffer (nframes) + offset;
508                 src = bufs[min(nbufs,i)];
509
510                 if (dg != _gain) {
511                         /* unlikely condition */
512                         outs.push_back (dst);
513                 }
514
515                 if (dg != _gain || actual_gain == 1.0f) {
516                         memcpy (dst, src, sizeof (Sample) * nframes);
517                 } else if (actual_gain == 0.0f) {
518                         memset (dst, 0, sizeof (Sample) * nframes);
519                 } else {
520                         for (nframes_t x = 0; x < nframes; ++x) {
521                                 dst[x] = src[x] * actual_gain;
522                         }
523                 }
524                 
525                 (*o)->mark_silence (false);
526         }
527
528         if (dg != _gain) {
529                 apply_declick (outs, i, nframes, _gain, dg, false);
530                 _gain = dg;
531         }
532
533         if (apply_gain_automation || _ignore_gain_on_deliver) {
534                 _gain = old_gain;
535         }
536 }
537
538 void
539 IO::collect_input (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
540 {
541         /* io_lock, not taken: function must be called from Session::process() calltree */
542
543         vector<Port *>::iterator i;
544         uint32_t n;
545         Sample *last = 0;
546         
547         /* we require that bufs.size() >= 1 */
548
549         for (n = 0, i = _inputs.begin(); n < nbufs; ++i, ++n) {
550                 if (i == _inputs.end()) {
551                         break;
552                 }
553                 
554                 /* XXX always read the full extent of the port buffer that
555                    we need. One day, we may use jack_port_get_buffer_at_offset()
556                    or something similar. For now, this simple hack will
557                    have to do.
558
559                    Hack? Why yes .. we only need to read nframes-worth of
560                    data, but the data we want is at `offset' within the
561                    buffer.
562                 */
563
564                 last = (*i)->get_buffer (nframes+offset) + offset;
565                 // the dest buffer's offset has already been applied
566                 memcpy (bufs[n], last, sizeof (Sample) * nframes);
567         }
568
569         /* fill any excess outputs with the last input */
570         
571         if (last) {
572                 while (n < nbufs) {
573                         // the dest buffer's offset has already been applied
574                         memcpy (bufs[n], last, sizeof (Sample) * nframes);
575                         ++n;
576                 }
577         } else {
578                 while (n < nbufs) {
579                         memset (bufs[n], 0, sizeof (Sample) * nframes);
580                         ++n;
581                 }
582         }
583 }
584
585 void
586 IO::just_meter_input (nframes_t start_frame, nframes_t end_frame, 
587                       nframes_t nframes, nframes_t offset)
588 {
589         vector<Sample*>& bufs = _session.get_passthru_buffers ();
590         uint32_t nbufs = n_process_buffers ();
591
592         collect_input (bufs, nbufs, nframes, offset);
593
594         for (uint32_t n = 0; n < nbufs; ++n) {
595                 _peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
596         }
597 }
598
599 void
600 IO::drop_input_connection ()
601 {
602         _input_connection = 0;
603         input_connection_configuration_connection.disconnect();
604         input_connection_connection_connection.disconnect();
605         _session.set_dirty ();
606 }
607
608 void
609 IO::drop_output_connection ()
610 {
611         _output_connection = 0;
612         output_connection_configuration_connection.disconnect();
613         output_connection_connection_connection.disconnect();
614         _session.set_dirty ();
615 }
616
617 int
618 IO::disconnect_input (Port* our_port, string other_port, void* src)
619 {
620         if (other_port.length() == 0 || our_port == 0) {
621                 return 0;
622         }
623
624         { 
625                 BLOCK_PROCESS_CALLBACK ();
626                 
627                 {
628                         Glib::Mutex::Lock lm (io_lock);
629                         
630                         /* check that our_port is really one of ours */
631                         
632                         if (find (_inputs.begin(), _inputs.end(), our_port) == _inputs.end()) {
633                                 return -1;
634                         }
635                         
636                         /* disconnect it from the source */
637                         
638                         if (_session.engine().disconnect (other_port, our_port->name())) {
639                                 error << string_compose(_("IO: cannot disconnect input port %1 from %2"), our_port->name(), other_port) << endmsg;
640                                 return -1;
641                         }
642
643                         drop_input_connection();
644                 }
645         }
646
647         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
648         _session.set_dirty ();
649
650         return 0;
651 }
652
653 int
654 IO::connect_input (Port* our_port, string other_port, void* src)
655 {
656         if (other_port.length() == 0 || our_port == 0) {
657                 return 0;
658         }
659
660         {
661                 BLOCK_PROCESS_CALLBACK ();
662                 
663                 {
664                         Glib::Mutex::Lock lm (io_lock);
665                         
666                         /* check that our_port is really one of ours */
667                         
668                         if (find (_inputs.begin(), _inputs.end(), our_port) == _inputs.end()) {
669                                 return -1;
670                         }
671                         
672                         /* connect it to the source */
673
674                         if (_session.engine().connect (other_port, our_port->name())) {
675                                 return -1;
676                         }
677                         
678                         drop_input_connection ();
679                 }
680         }
681
682         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
683         _session.set_dirty ();
684         return 0;
685 }
686
687 int
688 IO::disconnect_output (Port* our_port, string other_port, void* src)
689 {
690         if (other_port.length() == 0 || our_port == 0) {
691                 return 0;
692         }
693
694         {
695                 BLOCK_PROCESS_CALLBACK ();
696                 
697                 {
698                         Glib::Mutex::Lock lm (io_lock);
699                         
700                         if (find (_outputs.begin(), _outputs.end(), our_port) == _outputs.end()) {
701                                 return -1;
702                         }
703                         
704                         /* disconnect it from the destination */
705                         
706                         if (_session.engine().disconnect (our_port->name(), other_port)) {
707                                 error << string_compose(_("IO: cannot disconnect output port %1 from %2"), our_port->name(), other_port) << endmsg;
708                                 return -1;
709                         }
710
711                         drop_output_connection ();
712                 }
713         }
714
715         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
716         _session.set_dirty ();
717         return 0;
718 }
719
720 int
721 IO::connect_output (Port* our_port, string other_port, void* src)
722 {
723         if (other_port.length() == 0 || our_port == 0) {
724                 return 0;
725         }
726
727         {
728                 BLOCK_PROCESS_CALLBACK ();
729
730                 
731                 {
732                         Glib::Mutex::Lock lm (io_lock);
733                         
734                         /* check that our_port is really one of ours */
735                         
736                         if (find (_outputs.begin(), _outputs.end(), our_port) == _outputs.end()) {
737                                 return -1;
738                         }
739                         
740                         /* connect it to the destination */
741                         
742                         if (_session.engine().connect (our_port->name(), other_port)) {
743                                 return -1;
744                         }
745
746                         drop_output_connection ();
747                 }
748         }
749
750         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
751         _session.set_dirty ();
752         return 0;
753 }
754
755 int
756 IO::set_input (Port* other_port, void* src)
757 {
758         /* this removes all but one ports, and connects that one port
759            to the specified source.
760         */
761
762         if (_input_minimum > 1 || _input_minimum == 0) {
763                 /* sorry, you can't do this */
764                 return -1;
765         }
766
767         if (other_port == 0) {
768                 if (_input_minimum < 0) {
769                         return ensure_inputs (0, false, true, src);
770                 } else {
771                         return -1;
772                 }
773         }
774
775         if (ensure_inputs (1, true, true, src)) {
776                 return -1;
777         }
778
779         return connect_input (_inputs.front(), other_port->name(), src);
780 }
781
782 int
783 IO::remove_output_port (Port* port, void* src)
784 {
785         IOChange change (NoChange);
786
787         {
788                 BLOCK_PROCESS_CALLBACK ();
789
790                 
791                 {
792                         Glib::Mutex::Lock lm (io_lock);
793                         
794                         if (_noutputs - 1 == (uint32_t) _output_minimum) {
795                                 /* sorry, you can't do this */
796                                 return -1;
797                         }
798                         
799                         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
800                                 if (*i == port) {
801                                         change = IOChange (change|ConfigurationChanged);
802                                         if (port->connected()) {
803                                                 change = IOChange (change|ConnectionsChanged);
804                                         } 
805
806                                         _session.engine().unregister_port (*i);
807                                         _outputs.erase (i);
808                                         _noutputs--;
809                                         drop_output_connection ();
810
811                                         break;
812                                 }
813                         }
814
815                         if (change != NoChange) {
816                                 setup_peak_meters ();
817                                 reset_panner ();
818                         }
819                 }
820         }
821         
822         if (change != NoChange) {
823                 output_changed (change, src); /* EMIT SIGNAL */
824                 _session.set_dirty ();
825                 return 0;
826         }
827
828         return -1;
829 }
830
831 /** Add an output port.
832  *
833  * @param destination Name of input port to connect new port to.
834  * @param src Source for emitted ConfigurationChanged signal.
835  * @param type Data type of port.  Default value (NIL) will use this IO's default type.
836  */
837 int
838 IO::add_output_port (string destination, void* src, DataType type)
839 {
840         Port* our_port;
841
842         if (type == DataType::NIL)
843                 type = _default_type;
844
845         {
846                 BLOCK_PROCESS_CALLBACK ();
847
848                 
849                 { 
850                         Glib::Mutex::Lock lm (io_lock);
851                         
852                         if (_output_maximum >= 0 && (int) _noutputs == _output_maximum) {
853                                 return -1;
854                         }
855                 
856                         /* Create a new output port */
857                         
858                         string portname = build_legal_port_name (false);
859                         
860                         if ((our_port = _session.engine().register_output_port (type, portname)) == 0) {
861                                 error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
862                                 return -1;
863                         }
864                         
865                         _outputs.push_back (our_port);
866                         sort (_outputs.begin(), _outputs.end(), sort_ports_by_name);
867                         ++_noutputs;
868                         drop_output_connection ();
869                         setup_peak_meters ();
870                         reset_panner ();
871                 }
872
873                 MoreOutputs (_noutputs); /* EMIT SIGNAL */
874         }
875
876         if (destination.length()) {
877                 if (_session.engine().connect (our_port->name(), destination)) {
878                         return -1;
879                 }
880         }
881         
882         // pan_changed (src); /* EMIT SIGNAL */
883         output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
884         _session.set_dirty ();
885         return 0;
886 }
887
888 int
889 IO::remove_input_port (Port* port, void* src)
890 {
891         IOChange change (NoChange);
892
893         {
894                 BLOCK_PROCESS_CALLBACK ();
895
896                 
897                 {
898                         Glib::Mutex::Lock lm (io_lock);
899
900                         if (((int)_ninputs - 1) < _input_minimum) {
901                                 /* sorry, you can't do this */
902                                 return -1;
903                         }
904                         for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
905
906                                 if (*i == port) {
907                                         change = IOChange (change|ConfigurationChanged);
908
909                                         if (port->connected()) {
910                                                 change = IOChange (change|ConnectionsChanged);
911                                         } 
912
913                                         _session.engine().unregister_port (*i);
914                                         _inputs.erase (i);
915                                         _ninputs--;
916                                         drop_input_connection ();
917
918                                         break;
919                                 }
920                         }
921                         
922                         if (change != NoChange) {
923                                 setup_peak_meters ();
924                                 reset_panner ();
925                         }
926                 }
927         }
928
929         if (change != NoChange) {
930                 input_changed (change, src);
931                 _session.set_dirty ();
932                 return 0;
933         } 
934
935         return -1;
936 }
937
938
939 /** Add an input port.
940  *
941  * @param type Data type of port.  The appropriate Jack port type, and @ref Port will be created.
942  * @param destination Name of input port to connect new port to.
943  * @param src Source for emitted ConfigurationChanged signal.
944  */
945 int
946 IO::add_input_port (string source, void* src, DataType type)
947 {
948         Port* our_port;
949         
950         if (type == DataType::NIL)
951                 type = _default_type;
952
953         {
954                 BLOCK_PROCESS_CALLBACK ();
955                 
956                 { 
957                         Glib::Mutex::Lock lm (io_lock);
958
959                         if (_input_maximum >= 0 && (int) _ninputs == _input_maximum) {
960                                 return -1;
961                         }
962
963                         /* Create a new input port */
964                         
965                         string portname = build_legal_port_name (true);
966
967                         if ((our_port = _session.engine().register_input_port (type, portname)) == 0) {
968                                 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
969                                 return -1;
970                         }
971                         
972                         _inputs.push_back (our_port);
973                         sort (_inputs.begin(), _inputs.end(), sort_ports_by_name);
974                         ++_ninputs;
975                         drop_input_connection ();
976                         setup_peak_meters ();
977                         reset_panner ();
978                 }
979
980                 MoreOutputs (_ninputs); /* EMIT SIGNAL */
981         }
982
983         if (source.length()) {
984
985                 if (_session.engine().connect (source, our_port->name())) {
986                         return -1;
987                 }
988         } 
989
990         // pan_changed (src); /* EMIT SIGNAL */
991         input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
992         _session.set_dirty ();
993
994         return 0;
995 }
996
997 int
998 IO::disconnect_inputs (void* src)
999 {
1000         { 
1001                 BLOCK_PROCESS_CALLBACK ();
1002                 
1003                 {
1004                         Glib::Mutex::Lock lm (io_lock);
1005                         
1006                         for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1007                                 _session.engine().disconnect (*i);
1008                         }
1009
1010                         drop_input_connection ();
1011                 }
1012         }
1013         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
1014         return 0;
1015 }
1016
1017 int
1018 IO::disconnect_outputs (void* src)
1019 {
1020         {
1021                 BLOCK_PROCESS_CALLBACK ();
1022                 
1023                 {
1024                         Glib::Mutex::Lock lm (io_lock);
1025                         
1026                         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1027                                 _session.engine().disconnect (*i);
1028                         }
1029
1030                         drop_output_connection ();
1031                 }
1032         }
1033
1034         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
1035         _session.set_dirty ();
1036         return 0;
1037 }
1038
1039 bool
1040 IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
1041 {
1042         Port* input_port;
1043         bool changed = false;
1044         bool reduced = false;
1045         
1046         /* remove unused ports */
1047
1048         while (_ninputs > n) {
1049                 _session.engine().unregister_port (_inputs.back());
1050                 _inputs.pop_back();
1051                 _ninputs--;
1052                 reduced = true;
1053                 changed = true;
1054         }
1055                 
1056         /* create any necessary new ports */
1057                 
1058         while (_ninputs < n) {
1059                 
1060                 /* Create a new input port (of the default type) */
1061                 
1062                 string portname = build_legal_port_name (true);
1063                 
1064                 try {
1065                         
1066                         if ((input_port = _session.engine().register_input_port (_default_type, portname)) == 0) {
1067                                 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
1068                                 return -1;
1069                         }
1070                 }
1071
1072                 catch (AudioEngine::PortRegistrationFailure& err) {
1073                         setup_peak_meters ();
1074                         reset_panner ();
1075                         /* pass it on */
1076                         throw;
1077                 }
1078                 
1079                 _inputs.push_back (input_port);
1080                 sort (_inputs.begin(), _inputs.end(), sort_ports_by_name);
1081                 ++_ninputs;
1082                 changed = true;
1083         }
1084         
1085         if (changed) {
1086                 drop_input_connection ();
1087                 setup_peak_meters ();
1088                 reset_panner ();
1089                 MoreOutputs (_ninputs); /* EMIT SIGNAL */
1090                 _session.set_dirty ();
1091         }
1092         
1093         if (clear) {
1094                 /* disconnect all existing ports so that we get a fresh start */
1095                         
1096                 for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1097                         _session.engine().disconnect (*i);
1098                 }
1099         }
1100
1101         return changed;
1102 }
1103
1104 int
1105 IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
1106 {
1107         bool in_changed = false;
1108         bool out_changed = false;
1109         bool in_reduced = false;
1110         bool out_reduced = false;
1111         bool need_pan_reset;
1112
1113         if (_input_maximum >= 0) {
1114                 nin = min (_input_maximum, (int) nin);
1115         }
1116
1117         if (_output_maximum >= 0) {
1118                 nout = min (_output_maximum, (int) nout);
1119         }
1120
1121         if (nin == _ninputs && nout == _noutputs && !clear) {
1122                 return 0;
1123         }
1124
1125         {
1126                 BLOCK_PROCESS_CALLBACK ();
1127                 Glib::Mutex::Lock lm (io_lock);
1128
1129                 Port* port;
1130                 
1131                 if (_noutputs == nout) {
1132                         need_pan_reset = false;
1133                 } else {
1134                         need_pan_reset = true;
1135                 }
1136                 
1137                 /* remove unused ports */
1138                 
1139                 while (_ninputs > nin) {
1140                         _session.engine().unregister_port (_inputs.back());
1141                         _inputs.pop_back();
1142                         _ninputs--;
1143                         in_reduced = true;
1144                         in_changed = true;
1145                 }
1146                 
1147                 while (_noutputs > nout) {
1148                         _session.engine().unregister_port (_outputs.back());
1149                         _outputs.pop_back();
1150                         _noutputs--;
1151                         out_reduced = true;
1152                         out_changed = true;
1153                 }
1154                 
1155                 /* create any necessary new ports (of the default type) */
1156                 
1157                 while (_ninputs < nin) {
1158                         
1159                         /* Create a new input port */
1160                         
1161                         string portname = build_legal_port_name (true);
1162
1163                         try {
1164                                 if ((port = _session.engine().register_input_port (_default_type, portname)) == 0) {
1165                                         error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
1166                                         return -1;
1167                                 }
1168                         }
1169
1170                         catch (AudioEngine::PortRegistrationFailure& err) {
1171                                 setup_peak_meters ();
1172                                 reset_panner ();
1173                                 /* pass it on */
1174                                 throw;
1175                         }
1176                 
1177                         _inputs.push_back (port);
1178                         ++_ninputs;
1179                         in_changed = true;
1180                 }
1181
1182                 /* create any necessary new ports */
1183                 
1184                 while (_noutputs < nout) {
1185                         
1186                         string portname = build_legal_port_name (false);
1187
1188                         try { 
1189                                 if ((port = _session.engine().register_output_port (_default_type, portname)) == 0) {
1190                                         error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
1191                                         return -1;
1192                                 }
1193                         }
1194                         
1195                         catch (AudioEngine::PortRegistrationFailure& err) {
1196                                 setup_peak_meters ();
1197                                 reset_panner ();
1198                                 /* pass it on */
1199                                 throw;
1200                         }
1201                 
1202                         _outputs.push_back (port);
1203                         ++_noutputs;
1204                         out_changed = true;
1205                 }
1206                 
1207                 if (clear) {
1208                         
1209                         /* disconnect all existing ports so that we get a fresh start */
1210                         
1211                         for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1212                                 _session.engine().disconnect (*i);
1213                         }
1214                         
1215                         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1216                                 _session.engine().disconnect (*i);
1217                         }
1218                 }
1219                 
1220                 if (in_changed || out_changed) {
1221                         setup_peak_meters ();
1222                         reset_panner ();
1223                 }
1224         }
1225
1226         if (out_changed) {
1227                 sort (_outputs.begin(), _outputs.end(), sort_ports_by_name);
1228                 drop_output_connection ();
1229                 output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1230         }
1231         
1232         if (in_changed) {
1233                 sort (_inputs.begin(), _inputs.end(), sort_ports_by_name);
1234                 drop_input_connection ();
1235                 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1236         }
1237
1238         if (in_changed || out_changed) {
1239                 MoreOutputs (max (_noutputs, _ninputs)); /* EMIT SIGNAL */
1240                 _session.set_dirty ();
1241         }
1242
1243         return 0;
1244 }
1245
1246 int
1247 IO::ensure_inputs (uint32_t n, bool clear, bool lockit, void* src)
1248 {
1249         bool changed = false;
1250
1251         if (_input_maximum >= 0) {
1252                 n = min (_input_maximum, (int) n);
1253                 
1254                 if (n == _ninputs && !clear) {
1255                         return 0;
1256                 }
1257         }
1258         
1259         if (lockit) {
1260                 BLOCK_PROCESS_CALLBACK ();
1261                 Glib::Mutex::Lock im (io_lock);
1262                 changed = ensure_inputs_locked (n, clear, src);
1263         } else {
1264                 changed = ensure_inputs_locked (n, clear, src);
1265         }
1266
1267         if (changed) {
1268                 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1269                 _session.set_dirty ();
1270         }
1271
1272         return 0;
1273 }
1274
1275 bool
1276 IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
1277 {
1278         Port* output_port;
1279         bool changed = false;
1280         bool reduced = false;
1281         bool need_pan_reset;
1282
1283         if (_noutputs == n) {
1284                 need_pan_reset = false;
1285         } else {
1286                 need_pan_reset = true;
1287         }
1288         
1289         /* remove unused ports */
1290         
1291         while (_noutputs > n) {
1292                 
1293                 _session.engine().unregister_port (_outputs.back());
1294                 _outputs.pop_back();
1295                 _noutputs--;
1296                 reduced = true;
1297                 changed = true;
1298         }
1299         
1300         /* create any necessary new ports */
1301         
1302         while (_noutputs < n) {
1303                 
1304                 /* Create a new output port */
1305                 
1306                 string portname = build_legal_port_name (false);
1307                 
1308                 if ((output_port = _session.engine().register_output_port (_default_type, portname)) == 0) {
1309                         error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
1310                         return -1;
1311                 }
1312                 
1313                 _outputs.push_back (output_port);
1314                 sort (_outputs.begin(), _outputs.end(), sort_ports_by_name);
1315                 ++_noutputs;
1316                 changed = true;
1317                 setup_peak_meters ();
1318
1319                 if (need_pan_reset) {
1320                         reset_panner ();
1321                 }
1322         }
1323         
1324         if (changed) {
1325                 drop_output_connection ();
1326                 MoreOutputs (_noutputs); /* EMIT SIGNAL */
1327                 _session.set_dirty ();
1328         }
1329         
1330         if (clear) {
1331                 /* disconnect all existing ports so that we get a fresh start */
1332                 
1333                 for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1334                         _session.engine().disconnect (*i);
1335                 }
1336         }
1337
1338         return changed;
1339 }
1340
1341 int
1342 IO::ensure_outputs (uint32_t n, bool clear, bool lockit, void* src)
1343 {
1344         bool changed = false;
1345
1346         if (_output_maximum >= 0) {
1347                 n = min (_output_maximum, (int) n);
1348                 if (n == _noutputs && !clear) {
1349                         return 0;
1350                 }
1351         }
1352
1353         /* XXX caller should hold io_lock, but generally doesn't */
1354
1355         if (lockit) {
1356                 BLOCK_PROCESS_CALLBACK ();
1357                 Glib::Mutex::Lock im (io_lock);
1358                 changed = ensure_outputs_locked (n, clear, src);
1359         } else {
1360                 changed = ensure_outputs_locked (n, clear, src);
1361         }
1362
1363         if (changed) {
1364                  output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1365         }
1366
1367         return 0;
1368 }
1369
1370 gain_t
1371 IO::effective_gain () const
1372 {
1373         if (gain_automation_playback()) {
1374                 return _effective_gain;
1375         } else {
1376                 return _desired_gain;
1377         }
1378 }
1379
1380 void
1381 IO::reset_panner ()
1382 {
1383         if (panners_legal) {
1384                 if (!no_panner_reset) {
1385                         _panner->reset (_noutputs, pans_required());
1386                 }
1387         } else {
1388                 panner_legal_c.disconnect ();
1389                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1390         }
1391 }
1392
1393 int
1394 IO::panners_became_legal ()
1395 {
1396         _panner->reset (_noutputs, pans_required());
1397         _panner->load (); // automation
1398         panner_legal_c.disconnect ();
1399         return 0;
1400 }
1401
1402 void
1403 IO::defer_pan_reset ()
1404 {
1405         no_panner_reset = true;
1406 }
1407
1408 void
1409 IO::allow_pan_reset ()
1410 {
1411         no_panner_reset = false;
1412         reset_panner ();
1413 }
1414
1415
1416 XMLNode&
1417 IO::get_state (void)
1418 {
1419         return state (true);
1420 }
1421
1422 XMLNode&
1423 IO::state (bool full_state)
1424 {
1425         XMLNode* node = new XMLNode (state_node_name);
1426         char buf[64];
1427         string str;
1428         bool need_ins = true;
1429         bool need_outs = true;
1430         LocaleGuard lg (X_("POSIX"));
1431         Glib::Mutex::Lock lm (io_lock);
1432
1433         node->add_property("name", _name);
1434         id().print (buf, sizeof (buf));
1435         node->add_property("id", buf);
1436         node->add_property("active", _active? "yes" : "no");
1437
1438         str = "";
1439
1440         if (_input_connection) {
1441                 node->add_property ("input-connection", _input_connection->name());
1442                 need_ins = false;
1443         }
1444
1445         if (_output_connection) {
1446                 node->add_property ("output-connection", _output_connection->name());
1447                 need_outs = false;
1448         }
1449
1450         if (need_ins) {
1451                 for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1452                         
1453                         const char **connections = (*i)->get_connections();
1454                         
1455                         if (connections && connections[0]) {
1456                                 str += '{';
1457                                 
1458                                 for (int n = 0; connections && connections[n]; ++n) {
1459                                         if (n) {
1460                                                 str += ',';
1461                                         }
1462                                         
1463                                         /* if its a connection to our own port,
1464                                            return only the port name, not the
1465                                            whole thing. this allows connections
1466                                            to be re-established even when our
1467                                            client name is different.
1468                                         */
1469                                         
1470                                         str += _session.engine().make_port_name_relative (connections[n]);
1471                                 }       
1472
1473                                 str += '}';
1474                                 
1475                                 free (connections);
1476                         }
1477                         else {
1478                                 str += "{}";
1479                         }
1480                 }
1481                 
1482                 node->add_property ("inputs", str);
1483         }
1484
1485         if (need_outs) {
1486                 str = "";
1487                 
1488                 for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1489                         
1490                         const char **connections = (*i)->get_connections();
1491                         
1492                         if (connections && connections[0]) {
1493                                 
1494                                 str += '{';
1495                                 
1496                                 for (int n = 0; connections[n]; ++n) {
1497                                         if (n) {
1498                                                 str += ',';
1499                                         }
1500
1501                                         str += _session.engine().make_port_name_relative (connections[n]);
1502                                 }
1503
1504                                 str += '}';
1505                                 
1506                                 free (connections);
1507                         }
1508                         else {
1509                                 str += "{}";
1510                         }
1511                 }
1512                 
1513                 node->add_property ("outputs", str);
1514         }
1515
1516         node->add_child_nocopy (_panner->state (full_state));
1517         node->add_child_nocopy (_gain_control.get_state ());
1518
1519         snprintf (buf, sizeof(buf), "%2.12f", gain());
1520         node->add_property ("gain", buf);
1521
1522         snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d",
1523                   _input_minimum,
1524                   _input_maximum,
1525                   _output_minimum,
1526                   _output_maximum);
1527
1528         node->add_property ("iolimits", buf);
1529
1530         /* automation */
1531
1532         if (full_state) {
1533
1534                 XMLNode* autonode = new XMLNode (X_("Automation"));
1535                 autonode->add_child_nocopy (get_automation_state());
1536                 node->add_child_nocopy (*autonode);
1537
1538                 snprintf (buf, sizeof (buf), "0x%x", (int) _gain_automation_curve.automation_state());
1539         } else {
1540                 /* never store anything except Off for automation state in a template */
1541                 snprintf (buf, sizeof (buf), "0x%x", ARDOUR::Off); 
1542         }
1543
1544         return *node;
1545 }
1546
1547 int
1548 IO::set_state (const XMLNode& node)
1549 {
1550         const XMLProperty* prop;
1551         XMLNodeConstIterator iter;
1552         LocaleGuard lg (X_("POSIX"));
1553
1554         /* force use of non-localized representation of decimal point,
1555            since we use it a lot in XML files and so forth.
1556         */
1557
1558         if (node.name() != state_node_name) {
1559                 error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg;
1560                 return -1;
1561         }
1562
1563         if ((prop = node.property ("name")) != 0) {
1564                 _name = prop->value();
1565                 /* used to set panner name with this, but no more */
1566         } 
1567
1568         if ((prop = node.property ("id")) != 0) {
1569                 _id = prop->value ();
1570         }
1571
1572         if ((prop = node.property ("iolimits")) != 0) {
1573                 sscanf (prop->value().c_str(), "%d,%d,%d,%d", 
1574                         &_input_minimum,
1575                         &_input_maximum,
1576                         &_output_minimum,
1577                         &_output_maximum);
1578         }
1579         
1580         if ((prop = node.property ("gain")) != 0) {
1581                 set_gain (atof (prop->value().c_str()), this);
1582                 _gain = _desired_gain;
1583         }
1584
1585         if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) {
1586                 /* old school automation handling */
1587         }
1588
1589         if ((prop = node.property (X_("active"))) != 0) {
1590                 set_active (prop->value() == "yes");
1591         }
1592
1593         for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
1594
1595                 if ((*iter)->name() == "Panner") {
1596                         if (_panner == 0) {
1597                                 _panner = new Panner (_name, _session);
1598                         }
1599                         _panner->set_state (**iter);
1600                 }
1601
1602                 if ((*iter)->name() == X_("Automation")) {
1603
1604                         set_automation_state (*(*iter)->children().front());
1605                 }
1606
1607                 if ((*iter)->name() == X_("controllable")) {
1608                         if ((prop = (*iter)->property("name")) != 0 && prop->value() == "gaincontrol") {
1609                                 _gain_control.set_state (**iter);
1610                         }
1611                 }
1612         }
1613
1614         if (ports_legal) {
1615
1616                 if (create_ports (node)) {
1617                         return -1;
1618                 }
1619
1620         } else {
1621
1622                 port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
1623         }
1624
1625         if (panners_legal) {
1626                 reset_panner ();
1627         } else {
1628                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1629         }
1630
1631         if (connecting_legal) {
1632
1633                 if (make_connections (node)) {
1634                         return -1;
1635                 }
1636
1637         } else {
1638                 
1639                 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
1640         }
1641
1642         if (!ports_legal || !connecting_legal) {
1643                 pending_state_node = new XMLNode (node);
1644         }
1645
1646         last_automation_snapshot = 0;
1647
1648         return 0;
1649 }
1650
1651 int
1652 IO::set_automation_state (const XMLNode& node)
1653 {
1654         return _gain_automation_curve.set_state (node);
1655 }
1656
1657 XMLNode&
1658 IO::get_automation_state ()
1659 {
1660         return (_gain_automation_curve.get_state ());
1661 }
1662
1663 int
1664 IO::load_automation (string path)
1665 {
1666         string fullpath;
1667         ifstream in;
1668         char line[128];
1669         uint32_t linecnt = 0;
1670         float version;
1671         LocaleGuard lg (X_("POSIX"));
1672
1673         fullpath = Glib::build_filename(_session.automation_dir(), path);
1674
1675         in.open (fullpath.c_str());
1676
1677         if (!in) {
1678                 fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
1679
1680                 in.open (fullpath.c_str());
1681
1682                 if (!in) {
1683                         error << string_compose(_("%1: cannot open automation event file \"%2\""), _name, fullpath) << endmsg;
1684                         return -1;
1685                 }
1686         }
1687
1688         clear_automation ();
1689
1690         while (in.getline (line, sizeof(line), '\n')) {
1691                 char type;
1692                 jack_nframes_t when;
1693                 double value;
1694
1695                 if (++linecnt == 1) {
1696                         if (memcmp (line, "version", 7) == 0) {
1697                                 if (sscanf (line, "version %f", &version) != 1) {
1698                                         error << string_compose(_("badly formed version number in automation event file \"%1\""), path) << endmsg;
1699                                         return -1;
1700                                 }
1701                         } else {
1702                                 error << string_compose(_("no version information in automation event file \"%1\""), path) << endmsg;
1703                                 return -1;
1704                         }
1705
1706                         continue;
1707                 }
1708
1709                 if (sscanf (line, "%c %" PRIu32 " %lf", &type, &when, &value) != 3) {
1710                         warning << string_compose(_("badly formatted automation event record at line %1 of %2 (ignored)"), linecnt, path) << endmsg;
1711                         continue;
1712                 }
1713
1714                 switch (type) {
1715                 case 'g':
1716                         _gain_automation_curve.fast_simple_add (when, value);
1717                         break;
1718
1719                 case 's':
1720                         break;
1721
1722                 case 'm':
1723                         break;
1724
1725                 case 'p':
1726                         /* older (pre-1.0) versions of ardour used this */
1727                         break;
1728
1729                 default:
1730                         warning << _("dubious automation event found (and ignored)") << endmsg;
1731                 }
1732         }
1733
1734         return 0;
1735 }
1736
1737 int
1738 IO::connecting_became_legal ()
1739 {
1740         int ret;
1741
1742         if (pending_state_node == 0) {
1743                 fatal << _("IO::connecting_became_legal() called without a pending state node") << endmsg;
1744                 /*NOTREACHED*/
1745                 return -1;
1746         }
1747
1748         connection_legal_c.disconnect ();
1749
1750         ret = make_connections (*pending_state_node);
1751
1752         if (ports_legal) {
1753                 delete pending_state_node;
1754                 pending_state_node = 0;
1755         }
1756
1757         return ret;
1758 }
1759 int
1760 IO::ports_became_legal ()
1761 {
1762         int ret;
1763
1764         if (pending_state_node == 0) {
1765                 fatal << _("IO::ports_became_legal() called without a pending state node") << endmsg;
1766                 /*NOTREACHED*/
1767                 return -1;
1768         }
1769
1770         port_legal_c.disconnect ();
1771
1772         ret = create_ports (*pending_state_node);
1773
1774         if (connecting_legal) {
1775                 delete pending_state_node;
1776                 pending_state_node = 0;
1777         }
1778
1779         return ret;
1780 }
1781
1782 Connection *
1783 IO::find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name) 
1784 {
1785         static const string digits = "0123456789";
1786
1787         Connection* c = _session.connection_by_name (desired_name);
1788
1789         if (!c) {
1790                 int connection_number, mask;
1791                 string possible_name;
1792                 bool stereo = false;
1793                 string::size_type last_non_digit_pos;
1794
1795                 error << string_compose(_("Unknown connection \"%1\" listed for %2 of %3"), desired_name, connection_type_name, _name)
1796                       << endmsg;
1797
1798                 // find numeric suffix of desired name
1799                 connection_number = 0;
1800                 
1801                 last_non_digit_pos = desired_name.find_last_not_of(digits);
1802
1803                 if (last_non_digit_pos != string::npos) {
1804                         stringstream s;
1805                         s << desired_name.substr(last_non_digit_pos);
1806                         s >> connection_number;
1807                 }
1808         
1809                 // see if it's a stereo connection e.g. "in 3+4"
1810
1811                 if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
1812                         int left_connection_number = 0;
1813                         string::size_type left_last_non_digit_pos;
1814
1815                         left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
1816
1817                         if (left_last_non_digit_pos != string::npos) {
1818                                 stringstream s;
1819                                 s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
1820                                 s >> left_connection_number;
1821
1822                                 if (left_connection_number > 0 && left_connection_number + 1 == connection_number) {
1823                                         connection_number--;
1824                                         stereo = true;
1825                                 }
1826                         }
1827                 }
1828
1829                 // make 0-based
1830                 if (connection_number)
1831                         connection_number--;
1832
1833                 // find highest set bit
1834                 mask = 1;
1835                 while ((mask <= connection_number) && (mask <<= 1));
1836                 
1837                 // "wrap" connection number into largest possible power of 2 
1838                 // that works...
1839
1840                 while (mask) {
1841
1842                         if (connection_number & mask) {
1843                                 connection_number &= ~mask;
1844                                 
1845                                 stringstream s;
1846                                 s << default_name << " " << connection_number + 1;
1847
1848                                 if (stereo) {
1849                                         s << "+" << connection_number + 2;
1850                                 }
1851                                 
1852                                 possible_name = s.str();
1853
1854                                 if ((c = _session.connection_by_name (possible_name)) != 0) {
1855                                         break;
1856                                 }
1857                         }
1858                         mask >>= 1;
1859                 }
1860                 if (c) {
1861                         info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), desired_name, possible_name)
1862                              << endmsg;
1863                 } else {
1864                         error << string_compose(_("No %1 connections available as a replacement"), connection_type_name)
1865                               << endmsg;
1866                 }
1867
1868         }
1869
1870         return c;
1871
1872 }
1873
1874 int
1875 IO::create_ports (const XMLNode& node)
1876 {
1877         const XMLProperty* prop;
1878         int num_inputs = 0;
1879         int num_outputs = 0;
1880
1881         if ((prop = node.property ("input-connection")) != 0) {
1882
1883                 Connection* c = find_possible_connection(prop->value(), _("in"), _("input"));
1884                 
1885                 if (c == 0) {
1886                         return -1;
1887                 } 
1888
1889                 num_inputs = c->nports();
1890
1891         } else if ((prop = node.property ("inputs")) != 0) {
1892
1893                 num_inputs = count (prop->value().begin(), prop->value().end(), '{');
1894         }
1895         
1896         if ((prop = node.property ("output-connection")) != 0) {
1897                 Connection* c = find_possible_connection(prop->value(), _("out"), _("output"));
1898
1899                 if (c == 0) {
1900                         return -1;
1901                 } 
1902
1903                 num_outputs = c->nports ();
1904                 
1905         } else if ((prop = node.property ("outputs")) != 0) {
1906                 num_outputs = count (prop->value().begin(), prop->value().end(), '{');
1907         }
1908
1909         no_panner_reset = true;
1910
1911         if (ensure_io (num_inputs, num_outputs, true, this)) {
1912                 error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
1913                 return -1;
1914         }
1915
1916         no_panner_reset = false;
1917
1918         set_deferred_state ();
1919
1920         PortsCreated();
1921         return 0;
1922 }
1923
1924
1925 int
1926 IO::make_connections (const XMLNode& node)
1927 {
1928         const XMLProperty* prop;
1929
1930         if ((prop = node.property ("input-connection")) != 0) {
1931                 Connection* c = find_possible_connection (prop->value(), _("in"), _("input"));
1932                 
1933                 if (c == 0) {
1934                         return -1;
1935                 } 
1936
1937                 use_input_connection (*c, this);
1938
1939         } else if ((prop = node.property ("inputs")) != 0) {
1940                 if (set_inputs (prop->value())) {
1941                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
1942                         return -1;
1943                 }
1944         }
1945         
1946         if ((prop = node.property ("output-connection")) != 0) {
1947                 Connection* c = find_possible_connection (prop->value(), _("out"), _("output"));
1948                 
1949                 if (c == 0) {
1950                         return -1;
1951                 } 
1952
1953                 use_output_connection (*c, this);
1954                 
1955         } else if ((prop = node.property ("outputs")) != 0) {
1956                 if (set_outputs (prop->value())) {
1957                         error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
1958                         return -1;
1959                 }
1960         }
1961         
1962         return 0;
1963 }
1964
1965 int
1966 IO::set_inputs (const string& str)
1967 {
1968         vector<string> ports;
1969         int i;
1970         int n;
1971         uint32_t nports;
1972         
1973         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1974                 return 0;
1975         }
1976
1977         if (ensure_inputs (nports, true, true, this)) {
1978                 return -1;
1979         }
1980
1981         string::size_type start, end, ostart;
1982
1983         ostart = 0;
1984         start = 0;
1985         end = 0;
1986         i = 0;
1987
1988         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1989                 start += 1;
1990
1991                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1992                         error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
1993                         return -1;
1994                 }
1995
1996                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1997                         error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
1998
1999                         return -1;
2000                         
2001                 } else if (n > 0) {
2002
2003                         for (int x = 0; x < n; ++x) {
2004                                 connect_input (input (i), ports[x], this);
2005                         }
2006                 }
2007
2008                 ostart = end+1;
2009                 i++;
2010         }
2011
2012         return 0;
2013 }
2014
2015 int
2016 IO::set_outputs (const string& str)
2017 {
2018         vector<string> ports;
2019         int i;
2020         int n;
2021         uint32_t nports;
2022         
2023         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
2024                 return 0;
2025         }
2026
2027         if (ensure_outputs (nports, true, true, this)) {
2028                 return -1;
2029         }
2030
2031         string::size_type start, end, ostart;
2032
2033         ostart = 0;
2034         start = 0;
2035         end = 0;
2036         i = 0;
2037
2038         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
2039                 start += 1;
2040
2041                 if ((end = str.find_first_of ('}', start)) == string::npos) {
2042                         error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg;
2043                         return -1;
2044                 }
2045
2046                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
2047                         error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg;
2048
2049                         return -1;
2050                         
2051                 } else if (n > 0) {
2052
2053                         for (int x = 0; x < n; ++x) {
2054                                 connect_output (output (i), ports[x], this);
2055                         }
2056                 }
2057
2058                 ostart = end+1;
2059                 i++;
2060         }
2061
2062         return 0;
2063 }
2064
2065 int
2066 IO::parse_io_string (const string& str, vector<string>& ports)
2067 {
2068         string::size_type pos, opos;
2069
2070         if (str.length() == 0) {
2071                 return 0;
2072         }
2073
2074         pos = 0;
2075         opos = 0;
2076
2077         ports.clear ();
2078
2079         while ((pos = str.find_first_of (',', opos)) != string::npos) {
2080                 ports.push_back (str.substr (opos, pos - opos));
2081                 opos = pos + 1;
2082         }
2083         
2084         if (opos < str.length()) {
2085                 ports.push_back (str.substr(opos));
2086         }
2087
2088         return ports.size();
2089 }
2090
2091 int
2092 IO::parse_gain_string (const string& str, vector<string>& ports)
2093 {
2094         string::size_type pos, opos;
2095
2096         pos = 0;
2097         opos = 0;
2098         ports.clear ();
2099
2100         while ((pos = str.find_first_of (',', opos)) != string::npos) {
2101                 ports.push_back (str.substr (opos, pos - opos));
2102                 opos = pos + 1;
2103         }
2104         
2105         if (opos < str.length()) {
2106                 ports.push_back (str.substr(opos));
2107         }
2108
2109         return ports.size();
2110 }
2111
2112 int
2113 IO::set_name (string requested_name, void* src)
2114 {
2115         if (requested_name == _name) {
2116                 return 0;
2117         }
2118
2119         string name;
2120         Route *rt;
2121         if ( (rt = dynamic_cast<Route *>(this))) {
2122                 name = Route::ensure_track_or_route_name(requested_name, _session);
2123         } else {
2124                 name = requested_name;
2125         }
2126
2127
2128         /* replace all colons in the name. i wish we didn't have to do this */
2129
2130         if (replace_all (name, ":", "-")) {
2131                 warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
2132         }
2133
2134         for (vector<Port *>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2135                 string current_name = (*i)->short_name();
2136                 current_name.replace (current_name.find (_name), _name.length(), name);
2137                 (*i)->set_name (current_name);
2138         }
2139
2140         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2141                 string current_name = (*i)->short_name();
2142                 current_name.replace (current_name.find (_name), _name.length(), name);
2143                 (*i)->set_name (current_name);
2144         }
2145
2146         _name = name;
2147          name_changed (src); /* EMIT SIGNAL */
2148
2149          return 0;
2150 }
2151
2152 void
2153 IO::set_input_minimum (int n)
2154 {
2155         _input_minimum = n;
2156 }
2157
2158 void
2159 IO::set_input_maximum (int n)
2160 {
2161         _input_maximum = n;
2162 }
2163
2164 void
2165 IO::set_output_minimum (int n)
2166 {
2167         _output_minimum = n;
2168 }
2169
2170 void
2171 IO::set_output_maximum (int n)
2172 {
2173         _output_maximum = n;
2174 }
2175
2176 void
2177 IO::set_port_latency (nframes_t nframes)
2178 {
2179         Glib::Mutex::Lock lm (io_lock);
2180
2181         for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2182                 (*i)->set_latency (nframes);
2183         }
2184 }
2185
2186 nframes_t
2187 IO::output_latency () const
2188 {
2189         nframes_t max_latency;
2190         nframes_t latency;
2191
2192         max_latency = 0;
2193
2194         /* io lock not taken - must be protected by other means */
2195
2196         for (vector<Port *>::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2197                 if ((latency = _session.engine().get_port_total_latency (*(*i))) > max_latency) {
2198                         max_latency = latency;
2199                 }
2200         }
2201
2202         return max_latency;
2203 }
2204
2205 nframes_t
2206 IO::input_latency () const
2207 {
2208         nframes_t max_latency;
2209         nframes_t latency;
2210
2211         max_latency = 0;
2212
2213         /* io lock not taken - must be protected by other means */
2214
2215         for (vector<Port *>::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2216                 if ((latency = _session.engine().get_port_total_latency (*(*i))) > max_latency) {
2217                         max_latency = latency;
2218                 }
2219         }
2220
2221         return max_latency;
2222 }
2223
2224 int
2225 IO::use_input_connection (Connection& c, void* src)
2226 {
2227         uint32_t limit;
2228
2229         {
2230                 BLOCK_PROCESS_CALLBACK ();
2231                 Glib::Mutex::Lock lm2 (io_lock);
2232                 
2233                 limit = c.nports();
2234                 
2235                 drop_input_connection ();
2236                 
2237                 if (ensure_inputs (limit, false, false, src)) {
2238                         return -1;
2239                 }
2240
2241                 /* first pass: check the current state to see what's correctly
2242                    connected, and drop anything that we don't want.
2243                 */
2244                 
2245                 for (uint32_t n = 0; n < limit; ++n) {
2246                         const Connection::PortList& pl = c.port_connections (n);
2247                         
2248                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2249                                 
2250                                 if (!_inputs[n]->connected_to ((*i))) {
2251                                         
2252                                         /* clear any existing connections */
2253                                         
2254                                         _session.engine().disconnect (_inputs[n]);
2255                                         
2256                                 } else if (_inputs[n]->connected() > 1) {
2257                                         
2258                                         /* OK, it is connected to the port we want,
2259                                            but its also connected to other ports.
2260                                            Change that situation.
2261                                         */
2262                                         
2263                                         /* XXX could be optimized to not drop
2264                                            the one we want.
2265                                         */
2266                                         
2267                                         _session.engine().disconnect (_inputs[n]);
2268                                         
2269                                 }
2270                         }
2271                 }
2272                 
2273                 /* second pass: connect all requested ports where necessary */
2274                 
2275                 for (uint32_t n = 0; n < limit; ++n) {
2276                         const Connection::PortList& pl = c.port_connections (n);
2277                         
2278                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2279                                 
2280                                 if (!_inputs[n]->connected_to ((*i))) {
2281                                         
2282                                         if (_session.engine().connect (*i, _inputs[n]->name())) {
2283                                                 return -1;
2284                                         }
2285                                 }
2286                                 
2287                         }
2288                 }
2289                 
2290                 _input_connection = &c;
2291                 
2292                 input_connection_configuration_connection = c.ConfigurationChanged.connect
2293                         (mem_fun (*this, &IO::input_connection_configuration_changed));
2294                 input_connection_connection_connection = c.ConnectionsChanged.connect
2295                         (mem_fun (*this, &IO::input_connection_connection_changed));
2296         }
2297
2298         input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
2299         return 0;
2300 }
2301
2302 int
2303 IO::use_output_connection (Connection& c, void* src)
2304 {
2305         uint32_t limit; 
2306
2307         {
2308                 BLOCK_PROCESS_CALLBACK ();
2309                 Glib::Mutex::Lock lm2 (io_lock);
2310
2311                 limit = c.nports();
2312                         
2313                 drop_output_connection ();
2314
2315                 if (ensure_outputs (limit, false, false, src)) {
2316                         return -1;
2317                 }
2318
2319                 /* first pass: check the current state to see what's correctly
2320                    connected, and drop anything that we don't want.
2321                 */
2322                         
2323                 for (uint32_t n = 0; n < limit; ++n) {
2324
2325                         const Connection::PortList& pl = c.port_connections (n);
2326                                 
2327                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2328                                         
2329                                 if (!_outputs[n]->connected_to ((*i))) {
2330
2331                                         /* clear any existing connections */
2332
2333                                         _session.engine().disconnect (_outputs[n]);
2334
2335                                 } else if (_outputs[n]->connected() > 1) {
2336
2337                                         /* OK, it is connected to the port we want,
2338                                            but its also connected to other ports.
2339                                            Change that situation.
2340                                         */
2341
2342                                         /* XXX could be optimized to not drop
2343                                            the one we want.
2344                                         */
2345                                                 
2346                                         _session.engine().disconnect (_outputs[n]);
2347                                 }
2348                         }
2349                 }
2350
2351                 /* second pass: connect all requested ports where necessary */
2352
2353                 for (uint32_t n = 0; n < limit; ++n) {
2354
2355                         const Connection::PortList& pl = c.port_connections (n);
2356                                 
2357                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2358                                         
2359                                 if (!_outputs[n]->connected_to ((*i))) {
2360                                                 
2361                                         if (_session.engine().connect (_outputs[n]->name(), *i)) {
2362                                                 return -1;
2363                                         }
2364                                 }
2365                         }
2366                 }
2367
2368                 _output_connection = &c;
2369
2370                 output_connection_configuration_connection = c.ConfigurationChanged.connect
2371                         (mem_fun (*this, &IO::output_connection_configuration_changed));
2372                 output_connection_connection_connection = c.ConnectionsChanged.connect
2373                         (mem_fun (*this, &IO::output_connection_connection_changed));
2374         }
2375
2376         output_changed (IOChange (ConnectionsChanged|ConfigurationChanged), src); /* EMIT SIGNAL */
2377
2378         return 0;
2379 }
2380
2381 int
2382 IO::disable_connecting ()
2383 {
2384         connecting_legal = false;
2385         return 0;
2386 }
2387
2388 int
2389 IO::enable_connecting ()
2390 {
2391         connecting_legal = true;
2392         return ConnectingLegal ();
2393 }
2394
2395 int
2396 IO::disable_ports ()
2397 {
2398         ports_legal = false;
2399         return 0;
2400 }
2401
2402 int
2403 IO::enable_ports ()
2404 {
2405         ports_legal = true;
2406         return PortsLegal ();
2407 }
2408
2409 int
2410 IO::disable_panners (void)
2411 {
2412         panners_legal = false;
2413         return 0;
2414 }
2415
2416 int
2417 IO::reset_panners ()
2418 {
2419         panners_legal = true;
2420         return PannersLegal ();
2421 }
2422
2423 void
2424 IO::input_connection_connection_changed (int ignored)
2425 {
2426         use_input_connection (*_input_connection, this);
2427 }
2428
2429 void
2430 IO::input_connection_configuration_changed ()
2431 {
2432         use_input_connection (*_input_connection, this);
2433 }
2434
2435 void
2436 IO::output_connection_connection_changed (int ignored)
2437 {
2438         use_output_connection (*_output_connection, this);
2439 }
2440
2441 void
2442 IO::output_connection_configuration_changed ()
2443 {
2444         use_output_connection (*_output_connection, this);
2445 }
2446
2447 void
2448 IO::GainControllable::set_value (float val)
2449 {
2450         io.set_gain (direct_control_to_gain (val), this);
2451 }
2452
2453 float
2454 IO::GainControllable::get_value (void) const
2455 {
2456         return direct_gain_to_control (io.effective_gain());
2457 }
2458
2459 void
2460 IO::reset_peak_meters ()
2461 {
2462         uint32_t limit = max (_ninputs, _noutputs);
2463
2464         for (uint32_t i = 0; i < limit; ++i) {
2465                 _peak_power[i] = 0;
2466         }
2467 }
2468
2469 void
2470 IO::reset_max_peak_meters ()
2471 {
2472         uint32_t limit = max (_ninputs, _noutputs);
2473
2474         for (uint32_t i = 0; i < limit; ++i) {
2475                 _max_peak_power[i] = -INFINITY;
2476         }
2477 }
2478
2479 void
2480 IO::setup_peak_meters ()
2481 {
2482         uint32_t limit = max (_ninputs, _noutputs);
2483
2484         while (_peak_power.size() < limit) {
2485                 _peak_power.push_back (0);
2486                 _visible_peak_power.push_back (-INFINITY);
2487                 _max_peak_power.push_back (-INFINITY);
2488         }
2489 }
2490
2491 /**
2492     Update the peak meters.
2493
2494     The meter signal lock is taken to prevent modification of the 
2495     Meter signal while updating the meters, taking the meter signal
2496     lock prior to taking the io_lock ensures that all IO will remain 
2497     valid while metering.
2498 */   
2499 void
2500 IO::update_meters()
2501 {
2502         Glib::Mutex::Lock guard (m_meter_signal_lock);
2503         Meter();
2504 }
2505
2506 void
2507 IO::meter ()
2508 {
2509         Glib::Mutex::Lock lm (io_lock); // READER: meter thread.
2510         uint32_t limit = max (_ninputs, _noutputs);
2511
2512         for (uint32_t n = 0; n < limit; ++n) {
2513
2514                 /* XXX we should use atomic exchange here */
2515
2516                 /* grab peak since last read */
2517
2518                 float new_peak = _peak_power[n];
2519                 _peak_power[n] = 0;
2520
2521                 /* compute new visible value using falloff */
2522
2523                 if (new_peak > 0.0f) {
2524                         new_peak = coefficient_to_dB (new_peak);
2525                 } else {
2526                         new_peak = -INFINITY;
2527                 }
2528
2529                 /* update max peak */
2530                 
2531                 _max_peak_power[n] = max (new_peak, _max_peak_power[n]);
2532                 
2533                 if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) {
2534                         _visible_peak_power[n] = new_peak;
2535                 } else {
2536                         // do falloff, the config value is in dB/sec, we get updated at 100/sec currently (should be a var somewhere)
2537                         new_peak = _visible_peak_power[n] - (Config->get_meter_falloff() * 0.01f);
2538                         _visible_peak_power[n] = max (new_peak, -INFINITY);
2539                 }
2540         }
2541 }
2542
2543 void
2544 IO::clear_automation ()
2545 {
2546         Glib::Mutex::Lock lm (automation_lock);
2547         _gain_automation_curve.clear ();
2548         _panner->clear_automation ();
2549 }
2550
2551 void
2552 IO::set_gain_automation_state (AutoState state)
2553 {
2554         bool changed = false;
2555
2556         {
2557                 Glib::Mutex::Lock lm (automation_lock);
2558
2559                 if (state != _gain_automation_curve.automation_state()) {
2560                         changed = true;
2561                         last_automation_snapshot = 0;
2562                         _gain_automation_curve.set_automation_state (state);
2563                         
2564                         if (state != Off) {
2565                                 set_gain (_gain_automation_curve.eval (_session.transport_frame()), this);
2566                         }
2567                 }
2568         }
2569
2570         if (changed) {
2571                 _session.set_dirty ();
2572                 gain_automation_state_changed (); /* EMIT SIGNAL */
2573         }
2574 }
2575
2576 void
2577 IO::set_gain_automation_style (AutoStyle style)
2578 {
2579         bool changed = false;
2580
2581         {
2582                 Glib::Mutex::Lock lm (automation_lock);
2583
2584                 if (style != _gain_automation_curve.automation_style()) {
2585                         changed = true;
2586                         _gain_automation_curve.set_automation_style (style);
2587                 }
2588         }
2589
2590         if (changed) {
2591                 gain_automation_style_changed (); /* EMIT SIGNAL */
2592         }
2593 }
2594 void
2595 IO::inc_gain (gain_t factor, void *src)
2596 {
2597         if (_desired_gain == 0.0f)
2598                 set_gain (0.000001f + (0.000001f * factor), src);
2599         else
2600                 set_gain (_desired_gain + (_desired_gain * factor), src);
2601 }
2602
2603 void
2604 IO::set_gain (gain_t val, void *src)
2605 {
2606         // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2607         if (val>1.99526231f) val=1.99526231f;
2608
2609         {
2610                 Glib::Mutex::Lock dm (declick_lock);
2611                 _desired_gain = val;
2612         }
2613
2614         if (_session.transport_stopped()) {
2615                 _effective_gain = val;
2616                 // _gain = val;
2617         }
2618
2619         gain_changed (src);
2620         _gain_control.Changed (); /* EMIT SIGNAL */
2621         
2622         if (_session.transport_stopped() && src != 0 && src != this && gain_automation_recording()) {
2623                 _gain_automation_curve.add (_session.transport_frame(), val);
2624         }
2625
2626         _session.set_dirty();
2627 }
2628
2629 void
2630 IO::start_gain_touch ()
2631 {
2632         _gain_automation_curve.start_touch ();
2633 }
2634
2635 void
2636 IO::end_gain_touch ()
2637 {
2638         _gain_automation_curve.stop_touch ();
2639 }
2640
2641 void
2642 IO::start_pan_touch (uint32_t which)
2643 {
2644         if (which < _panner->size()) {
2645                 (*_panner)[which]->automation().start_touch();
2646         }
2647 }
2648
2649 void
2650 IO::end_pan_touch (uint32_t which)
2651 {
2652         if (which < _panner->size()) {
2653                 (*_panner)[which]->automation().stop_touch();
2654         }
2655
2656 }
2657
2658 void
2659 IO::automation_snapshot (nframes_t now, bool force)
2660 {
2661         if (gain_automation_recording()) {
2662                 _gain_automation_curve.rt_add (now, gain());
2663         }
2664         
2665         _panner->snapshot (now);
2666         last_automation_snapshot = now;
2667 }
2668
2669 void
2670 IO::transport_stopped (nframes_t frame)
2671 {
2672         _gain_automation_curve.reposition_for_rt_add (frame);
2673
2674         if (_gain_automation_curve.automation_state() != Off) {
2675                 
2676                 /* the src=0 condition is a special signal to not propagate 
2677                    automation gain changes into the mix group when locating.
2678                 */
2679
2680                 set_gain (_gain_automation_curve.eval (frame), 0);
2681         }
2682
2683         _panner->transport_stopped (frame);
2684 }
2685
2686 string
2687 IO::build_legal_port_name (bool in)
2688 {
2689         const int name_size = jack_port_name_size();
2690         int limit;
2691         char* suffix;
2692         int maxports;
2693
2694         if (in) {
2695                 suffix = _("in");
2696                 maxports = _input_maximum;
2697         } else {
2698                 suffix = _("out");
2699                 maxports = _output_maximum;
2700         }
2701         
2702         if (maxports == 1) {
2703                 // allow space for the slash + the suffix
2704                 limit = name_size - _session.engine().client_name().length() - (strlen (suffix) + 1);
2705                 char buf[name_size+1];
2706                 snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix);
2707                 return string (buf);
2708         } 
2709         
2710         // allow up to 4 digits for the output port number, plus the slash, suffix and extra space
2711
2712         limit = name_size - _session.engine().client_name().length() - (strlen (suffix) + 5);
2713
2714         char buf1[name_size+1];
2715         char buf2[name_size+1];
2716         
2717         snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix);
2718         
2719         int port_number;
2720         
2721         if (in) {
2722                 port_number = find_input_port_hole (buf1);
2723         } else {
2724                 port_number = find_output_port_hole (buf1);
2725         }
2726         
2727         snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
2728         
2729         return string (buf2);
2730 }
2731
2732 int32_t
2733 IO::find_input_port_hole (const char* base)
2734 {
2735         /* CALLER MUST HOLD IO LOCK */
2736
2737         uint32_t n;
2738
2739         if (_inputs.empty()) {
2740                 return 1;
2741         }
2742
2743         /* we only allow up to 4 characters for the port number
2744          */
2745
2746         for (n = 1; n < 9999; ++n) {
2747                 char buf[jack_port_name_size()];
2748                 vector<Port*>::iterator i;
2749
2750                 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2751
2752                 for (i = _inputs.begin(); i != _inputs.end(); ++i) {
2753                         if ((*i)->short_name() == buf) {
2754                                 break;
2755                         }
2756                 }
2757
2758                 if (i == _inputs.end()) {
2759                         break;
2760                 }
2761         }
2762         return n;
2763 }
2764
2765 int32_t
2766 IO::find_output_port_hole (const char* base)
2767 {
2768         /* CALLER MUST HOLD IO LOCK */
2769
2770         uint32_t n;
2771
2772         if (_outputs.empty()) {
2773                 return 1;
2774         }
2775
2776         /* we only allow up to 4 characters for the port number
2777          */
2778
2779         for (n = 1; n < 9999; ++n) {
2780                 char buf[jack_port_name_size()];
2781                 vector<Port*>::iterator i;
2782
2783                 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2784
2785                 for (i = _outputs.begin(); i != _outputs.end(); ++i) {
2786                         if ((*i)->short_name() == buf) {
2787                                 break;
2788                         }
2789                 }
2790
2791                 if (i == _outputs.end()) {
2792                         break;
2793                 }
2794         }
2795         
2796         return n;
2797 }
2798
2799 void
2800 IO::set_active (bool yn)
2801 {
2802         _active = yn; 
2803          active_changed(); /* EMIT SIGNAL */
2804 }
2805