Merged with trunk R1141
[ardour.git] / libs / ardour / io.cc
1 /*
2     Copyright (C) 2000-2006 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 #include <fstream>
20 #include <algorithm>
21 #include <unistd.h>
22 #include <locale.h>
23 #include <errno.h>
24
25 #include <sigc++/bind.h>
26
27 #include <glibmm/thread.h>
28
29 #include <pbd/xml++.h>
30
31 #include <ardour/audioengine.h>
32 #include <ardour/io.h>
33 #include <ardour/port.h>
34 #include <ardour/audio_port.h>
35 #include <ardour/midi_port.h>
36 #include <ardour/connection.h>
37 #include <ardour/session.h>
38 #include <ardour/cycle_timer.h>
39 #include <ardour/panner.h>
40 #include <ardour/buffer_set.h>
41 #include <ardour/meter.h>
42 #include <ardour/amp.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
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62
63 nframes_t    IO::_automation_interval = 0;
64
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,ChanCount> IO::MoreChannels;
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
96 /** @param default_type The type of port that will be created by ensure_io
97  * and friends if no type is explicitly requested (to avoid breakage).
98  */
99 IO::IO (Session& s, string name,
100         int input_min, int input_max, int output_min, int output_max,
101         DataType default_type)
102         : _session (s),
103       _output_buffers(new BufferSet()),
104           _name (name),
105           _default_type(default_type),
106           _gain_control (X_("gaincontrol"), *this),
107           _gain_automation_curve (0.0, 2.0, 1.0),
108           _input_minimum (ChanCount::ZERO),
109           _input_maximum (ChanCount::INFINITE),
110           _output_minimum (ChanCount::ZERO),
111           _output_maximum (ChanCount::INFINITE)
112 {
113         _panner = new Panner (name, _session);
114         _meter = new PeakMeter (_session);
115
116         if (input_min > 0) {
117                 _input_minimum = ChanCount(_default_type, input_min);
118         }
119         if (input_max >= 0) {
120                 _input_maximum = ChanCount(_default_type, input_max);
121         }
122         if (output_min > 0) {
123                 _output_minimum = ChanCount(_default_type, output_min);
124         }
125         if (output_max >= 0) {
126                 _output_maximum = ChanCount(_default_type, output_max);
127         }
128
129         _gain = 1.0;
130         _desired_gain = 1.0;
131         _input_connection = 0;
132         _output_connection = 0;
133         pending_state_node = 0;
134         no_panner_reset = false;
135         _phase_invert = false;
136         deferred_state = 0;
137
138         apply_gain_automation = false;
139         
140         last_automation_snapshot = 0;
141
142         _gain_automation_state = Off;
143         _gain_automation_style = Absolute;
144
145         {
146                 // IO::Meter is emitted from another thread so the
147                 // Meter signal must be protected.
148                 Glib::Mutex::Lock guard (m_meter_signal_lock);
149                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
150         }
151         
152         // Connect to our own MoreChannels signal to connect output buffers
153         IO::MoreChannels.connect (mem_fun (*this, &IO::attach_buffers));
154
155         _session.add_controllable (&_gain_control);
156 }
157
158 IO::IO (Session& s, const XMLNode& node, DataType dt)
159         : _session (s),
160       _output_buffers(new BufferSet()),
161           _default_type (dt),
162           _gain_control (X_("gaincontrol"), *this),
163           _gain_automation_curve (0, 0, 0) // all reset in set_state()
164 {
165         // FIXME: hack
166         _meter = new PeakMeter (_session);
167
168         _panner = 0;
169         deferred_state = 0;
170         no_panner_reset = false;
171         _desired_gain = 1.0;
172         _gain = 1.0;
173         _input_connection = 0;
174         _output_connection = 0;
175
176         apply_gain_automation = false;
177
178         set_state (node);
179
180         {
181                 // IO::Meter is emitted from another thread so the
182                 // Meter signal must be protected.
183                 Glib::Mutex::Lock guard (m_meter_signal_lock);
184                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
185         }
186         
187         // Connect to our own MoreChannels signal to connect output buffers
188         IO::MoreChannels.connect (mem_fun (*this, &IO::attach_buffers));
189
190         _session.add_controllable (&_gain_control);
191 }
192
193 IO::~IO ()
194 {
195         Glib::Mutex::Lock guard (m_meter_signal_lock);
196         
197         Glib::Mutex::Lock lm (io_lock);
198
199         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
200                 _session.engine().unregister_port (*i);
201         }
202
203         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
204                 _session.engine().unregister_port (*i);
205         }
206
207         m_meter_connection.disconnect();
208
209         delete _meter;
210         delete _panner;
211         delete _output_buffers;
212 }
213
214 void
215 IO::silence (nframes_t nframes, nframes_t offset)
216 {
217         /* io_lock, not taken: function must be called from Session::process() calltree */
218
219         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
220                 i->get_buffer().silence (nframes, offset);
221         }
222 }
223
224 /** Deliver bufs to the IO's Jack outputs.
225  *
226  * This function should automatically do whatever it necessary to correctly deliver bufs
227  * to the outputs, eg applying gain or pan or whatever else needs to be done.
228  */
229 void
230 IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
231 {
232         // FIXME: type specific code doesn't actually need to be here, it will go away in time
233
234         /* ********** AUDIO ********** */
235
236         // Apply gain if gain automation isn't playing
237         if ( ! apply_gain_automation) {
238                 
239                 gain_t dg = _gain; // desired gain
240
241                 {
242                         Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
243
244                         if (dm.locked()) {
245                                 dg = _desired_gain;
246                         }
247
248                 }
249
250                 Amp::run(bufs, nframes, _gain, dg, _phase_invert);
251         }
252         
253         // Use the panner to distribute audio to output port buffers
254         if (_panner && !_panner->empty() && !_panner->bypassed()) {
255                 _panner->distribute(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
256         } else {
257                 const DataType type = DataType::AUDIO;
258
259                 // Copy any audio 1:1 to outputs
260                 assert(bufs.count().get(DataType::AUDIO) == output_buffers().count().get(DataType::AUDIO));
261                 BufferSet::iterator o = output_buffers().begin(type);
262                 for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) {
263                         o->read_from(*i, nframes, offset);
264                 }
265         }
266
267
268         /* ********** MIDI ********** */
269
270         // No MIDI, we're done here
271         if (bufs.count().get(DataType::MIDI) == 0) {
272                 return;
273         }
274
275         const DataType type = DataType::MIDI;
276
277         // Copy any MIDI 1:1 to outputs
278         assert(bufs.count().get(DataType::MIDI) == output_buffers().count().get(DataType::MIDI));
279         BufferSet::iterator o = output_buffers().begin(type);
280         for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) {
281                 o->read_from(*i, nframes, offset);
282         }
283 }
284
285 void
286 IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
287 {
288         assert(outs.available() >= n_inputs());
289
290         outs.set_count(n_inputs());
291         
292         if (outs.count() == ChanCount::ZERO)
293                 return;
294
295         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
296                 
297                 BufferSet::iterator o = outs.begin(*t);
298                 for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
299                         o->read_from(i->get_buffer(), nframes, offset);
300                 }
301
302         }
303 }
304
305 void
306 IO::just_meter_input (nframes_t start_frame, nframes_t end_frame, 
307                       nframes_t nframes, nframes_t offset)
308 {
309         BufferSet& bufs = _session.get_scratch_buffers (n_inputs());
310
311         collect_input (bufs, nframes, offset);
312
313         _meter->run(bufs, nframes);
314 }
315
316 void
317 IO::drop_input_connection ()
318 {
319         _input_connection = 0;
320         input_connection_configuration_connection.disconnect();
321         input_connection_connection_connection.disconnect();
322         _session.set_dirty ();
323 }
324
325 void
326 IO::drop_output_connection ()
327 {
328         _output_connection = 0;
329         output_connection_configuration_connection.disconnect();
330         output_connection_connection_connection.disconnect();
331         _session.set_dirty ();
332 }
333
334 int
335 IO::disconnect_input (Port* our_port, string other_port, void* src)
336 {
337         if (other_port.length() == 0 || our_port == 0) {
338                 return 0;
339         }
340
341         { 
342                 Glib::Mutex::Lock em (_session.engine().process_lock());
343                 
344                 {
345                         Glib::Mutex::Lock lm (io_lock);
346                         
347                         /* check that our_port is really one of ours */
348                         
349                         if ( ! _inputs.contains(our_port)) {
350                                 return -1;
351                         }
352                         
353                         /* disconnect it from the source */
354                         
355                         if (_session.engine().disconnect (other_port, our_port->name())) {
356                                 error << string_compose(_("IO: cannot disconnect input port %1 from %2"), our_port->name(), other_port) << endmsg;
357                                 return -1;
358                         }
359
360                         drop_input_connection();
361                 }
362         }
363
364         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
365         _session.set_dirty ();
366
367         return 0;
368 }
369
370 int
371 IO::connect_input (Port* our_port, string other_port, void* src)
372 {
373         if (other_port.length() == 0 || our_port == 0) {
374                 return 0;
375         }
376
377         {
378                 Glib::Mutex::Lock em(_session.engine().process_lock());
379                 
380                 {
381                         Glib::Mutex::Lock lm (io_lock);
382                         
383                         /* check that our_port is really one of ours */
384                         
385                         if ( ! _inputs.contains(our_port) ) {
386                                 return -1;
387                         }
388                         
389                         /* connect it to the source */
390
391                         if (_session.engine().connect (other_port, our_port->name())) {
392                                 return -1;
393                         }
394                         
395                         drop_input_connection ();
396                 }
397         }
398
399         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
400         _session.set_dirty ();
401         return 0;
402 }
403
404 int
405 IO::disconnect_output (Port* our_port, string other_port, void* src)
406 {
407         if (other_port.length() == 0 || our_port == 0) {
408                 return 0;
409         }
410
411         {
412                 Glib::Mutex::Lock em(_session.engine().process_lock());
413                 
414                 {
415                         Glib::Mutex::Lock lm (io_lock);
416                         
417                         /* check that our_port is really one of ours */
418                         
419                         if ( ! _outputs.contains(our_port) ) {
420                                 return -1;
421                         }
422                         
423                         /* disconnect it from the destination */
424                         
425                         if (_session.engine().disconnect (our_port->name(), other_port)) {
426                                 error << string_compose(_("IO: cannot disconnect output port %1 from %2"), our_port->name(), other_port) << endmsg;
427                                 return -1;
428                         }
429
430                         drop_output_connection ();
431                 }
432         }
433
434         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
435         _session.set_dirty ();
436         return 0;
437 }
438
439 int
440 IO::connect_output (Port* our_port, string other_port, void* src)
441 {
442         if (other_port.length() == 0 || our_port == 0) {
443                 return 0;
444         }
445
446         {
447                 Glib::Mutex::Lock em(_session.engine().process_lock());
448                 
449                 {
450                         Glib::Mutex::Lock lm (io_lock);
451                         
452                         /* check that our_port is really one of ours */
453                         
454                         if ( ! _outputs.contains(our_port) ) {
455                                 return -1;
456                         }
457                         
458                         /* connect it to the destination */
459                         
460                         if (_session.engine().connect (our_port->name(), other_port)) {
461                                 return -1;
462                         }
463
464                         drop_output_connection ();
465                 }
466         }
467
468         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
469         _session.set_dirty ();
470         return 0;
471 }
472
473 int
474 IO::set_input (Port* other_port, void* src)
475 {
476         /* this removes all but one ports, and connects that one port
477            to the specified source.
478         */
479
480         if (_input_minimum.get_total() > 1) {
481                 /* sorry, you can't do this */
482                 return -1;
483         }
484
485         if (other_port == 0) {
486                 if (_input_minimum == ChanCount::ZERO) {
487                         return ensure_inputs (ChanCount::ZERO, false, true, src);
488                 } else {
489                         return -1;
490                 }
491         }
492
493         if (ensure_inputs (ChanCount(other_port->type(), 1), true, true, src)) {
494                 return -1;
495         }
496
497         return connect_input (_inputs.port(0), other_port->name(), src);
498 }
499
500 int
501 IO::remove_output_port (Port* port, void* src)
502 {
503         IOChange change (NoChange);
504
505         {
506                 Glib::Mutex::Lock em(_session.engine().process_lock());
507                 
508                 {
509                         Glib::Mutex::Lock lm (io_lock);
510
511                         if (n_outputs() <= _output_minimum) {
512                                 /* sorry, you can't do this */
513                                 return -1;
514                         }
515
516                         if (_outputs.remove(port)) {
517                                 change = IOChange (change|ConfigurationChanged);
518
519                                 if (port->connected()) {
520                                         change = IOChange (change|ConnectionsChanged);
521                                 } 
522
523                                 _session.engine().unregister_port (*port);
524                                 drop_output_connection ();
525                                 
526                                 setup_peak_meters ();
527                                 reset_panner ();
528                         }
529                 }
530         }
531
532         if (change != NoChange) {
533                 output_changed (change, src);
534                 _session.set_dirty ();
535                 return 0;
536         } 
537         
538         return -1;
539 }
540
541 /** Add an output port.
542  *
543  * @param destination Name of input port to connect new port to.
544  * @param src Source for emitted ConfigurationChanged signal.
545  * @param type Data type of port.  Default value (NIL) will use this IO's default type.
546  */
547 int
548 IO::add_output_port (string destination, void* src, DataType type)
549 {
550         Port* our_port;
551         char name[64];
552
553         if (type == DataType::NIL)
554                 type = _default_type;
555
556         {
557                 Glib::Mutex::Lock em(_session.engine().process_lock());
558                 
559                 { 
560                         Glib::Mutex::Lock lm (io_lock);
561                         
562                         if (n_outputs() >= _output_maximum) {
563                                 return -1;
564                         }
565                 
566                         /* Create a new output port */
567                         
568                         // FIXME: naming scheme for differently typed ports?
569                         if (_output_maximum.get(type) == 1) {
570                                 snprintf (name, sizeof (name), _("%s/out"), _name.c_str());
571                         } else {
572                                 snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
573                         }
574                         
575                         if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
576                                 error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
577                                 return -1;
578                         }
579                         
580                         _outputs.add (our_port);
581                         drop_output_connection ();
582                         setup_peak_meters ();
583                         reset_panner ();
584                 }
585
586                 MoreChannels (n_outputs()); /* EMIT SIGNAL */
587         }
588
589         if (destination.length()) {
590                 if (_session.engine().connect (our_port->name(), destination)) {
591                         return -1;
592                 }
593         }
594         
595         // pan_changed (src); /* EMIT SIGNAL */
596         output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
597         _session.set_dirty ();
598         
599         return 0;
600 }
601
602 int
603 IO::remove_input_port (Port* port, void* src)
604 {
605         IOChange change (NoChange);
606
607         {
608                 Glib::Mutex::Lock em(_session.engine().process_lock());
609                 
610                 {
611                         Glib::Mutex::Lock lm (io_lock);
612
613                         if (n_inputs() <= _input_minimum) {
614                                 /* sorry, you can't do this */
615                                 return -1;
616                         }
617
618                         if (_inputs.remove(port)) {
619                                 change = IOChange (change|ConfigurationChanged);
620
621                                 if (port->connected()) {
622                                         change = IOChange (change|ConnectionsChanged);
623                                 } 
624
625                                 _session.engine().unregister_port (*port);
626                                 drop_input_connection ();
627                                 
628                                 setup_peak_meters ();
629                                 reset_panner ();
630                         }
631                 }
632         }
633
634         if (change != NoChange) {
635                 input_changed (change, src);
636                 _session.set_dirty ();
637                 return 0;
638         } 
639         
640         return -1;
641 }
642
643
644 /** Add an input port.
645  *
646  * @param type Data type of port.  The appropriate Jack port type, and @ref Port will be created.
647  * @param destination Name of input port to connect new port to.
648  * @param src Source for emitted ConfigurationChanged signal.
649  */
650 int
651 IO::add_input_port (string source, void* src, DataType type)
652 {
653         Port* our_port;
654         char name[64];
655         
656         if (type == DataType::NIL)
657                 type = _default_type;
658
659         {
660                 Glib::Mutex::Lock em (_session.engine().process_lock());
661                 
662                 { 
663                         Glib::Mutex::Lock lm (io_lock);
664                         
665                         if (n_inputs() >= _input_maximum) {
666                                 return -1;
667                         }
668
669                         /* Create a new input port */
670                         
671                         // FIXME: naming scheme for differently typed ports?
672                         if (_input_maximum.get(type) == 1) {
673                                 snprintf (name, sizeof (name), _("%s/in"), _name.c_str());
674                         } else {
675                                 snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
676                         }
677                         
678                         if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
679                                 error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
680                                 return -1;
681                         }
682
683                         _inputs.add (our_port);
684                         drop_input_connection ();
685                         setup_peak_meters ();
686                         reset_panner ();
687                 }
688
689                 MoreChannels (n_inputs()); /* EMIT SIGNAL */
690         }
691
692         if (source.length()) {
693
694                 if (_session.engine().connect (source, our_port->name())) {
695                         return -1;
696                 }
697         } 
698
699         // pan_changed (src); /* EMIT SIGNAL */
700         input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
701         _session.set_dirty ();
702         
703         return 0;
704 }
705
706 int
707 IO::disconnect_inputs (void* src)
708 {
709         { 
710                 Glib::Mutex::Lock em (_session.engine().process_lock());
711                 
712                 {
713                         Glib::Mutex::Lock lm (io_lock);
714                         
715                         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
716                                 _session.engine().disconnect (*i);
717                         }
718
719                         drop_input_connection ();
720                 }
721         }
722         
723         input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
724         
725         return 0;
726 }
727
728 int
729 IO::disconnect_outputs (void* src)
730 {
731         {
732                 Glib::Mutex::Lock em (_session.engine().process_lock());
733                 
734                 {
735                         Glib::Mutex::Lock lm (io_lock);
736                         
737                         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
738                                 _session.engine().disconnect (*i);
739                         }
740
741                         drop_output_connection ();
742                 }
743         }
744
745         output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */
746         _session.set_dirty ();
747         
748         return 0;
749 }
750
751 bool
752 IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
753 {
754         Port* input_port = 0;
755         bool  changed    = false;
756
757
758         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
759                 
760                 const size_t n = count.get(*t);
761         
762                 /* remove unused ports */
763                 for (size_t i = n_inputs().get(*t); i > n; --i) {
764                         input_port = _inputs.port(*t, i-1);
765
766                         assert(input_port);
767                         _inputs.remove(input_port);
768                         _session.engine().unregister_port (*input_port);
769
770                         changed = true;
771                 }
772
773                 /* create any necessary new ports */
774                 while (n_inputs().get(*t) < n) {
775
776                         char buf[64];
777
778                         if (_input_maximum.get(*t) == 1) {
779                                 snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
780                         } else {
781                                 snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole());
782                         }
783
784                         try {
785
786                                 if ((input_port = _session.engine().register_input_port (*t, buf)) == 0) {
787                                         error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
788                                         return -1;
789                                 }
790                         }
791
792                         catch (AudioEngine::PortRegistrationFailure& err) {
793                                 setup_peak_meters ();
794                                 reset_panner ();
795                                 /* pass it on */
796                                 throw err;
797                         }
798
799                         _inputs.add (input_port);
800                         changed = true;
801                 }
802         }
803         
804         if (changed) {
805                 drop_input_connection ();
806                 setup_peak_meters ();
807                 reset_panner ();
808                 MoreChannels (n_inputs()); /* EMIT SIGNAL */
809                 _session.set_dirty ();
810         }
811         
812         if (clear) {
813                 /* disconnect all existing ports so that we get a fresh start */
814                 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
815                         _session.engine().disconnect (*i);
816                 }
817         }
818
819         return changed;
820 }
821
822 /** Attach output_buffers to port buffers.
823  * 
824  * Connected to IO's own MoreChannels signal.
825  */
826 void
827 IO::attach_buffers(ChanCount ignored)
828 {
829         _output_buffers->attach_buffers(_outputs);
830 }
831
832 int
833 IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
834 {
835         bool in_changed     = false;
836         bool out_changed    = false;
837         bool need_pan_reset = false;
838
839         in = min (_input_maximum, in);
840
841         out = min (_output_maximum, out);
842
843         if (in == n_inputs() && out == n_outputs() && !clear) {
844                 return 0;
845         }
846
847         {
848                 Glib::Mutex::Lock em (_session.engine().process_lock());
849                 Glib::Mutex::Lock lm (io_lock);
850
851                 Port* port;
852                 
853                 if (n_outputs() != out) {
854                         need_pan_reset = true;
855                 }
856                 
857                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
858
859                         const size_t nin = in.get(*t);
860                         const size_t nout = out.get(*t);
861
862                         Port* output_port = 0;
863                         Port* input_port = 0;
864
865                         /* remove unused output ports */
866                         for (size_t i = n_outputs().get(*t); i > nout; --i) {
867                                 output_port = _outputs.port(*t, i-1);
868
869                                 assert(output_port);
870                                 _outputs.remove(output_port);
871                                 _session.engine().unregister_port (*output_port);
872
873                                 out_changed = true;
874                         }
875
876                         /* remove unused input ports */
877                         for (size_t i = n_inputs().get(*t); i > nin; --i) {
878                                 input_port = _inputs.port(*t, i-1);
879
880                                 assert(input_port);
881                                 _inputs.remove(input_port);
882                                 _session.engine().unregister_port (*input_port);
883
884                                 in_changed = true;
885                         }
886
887                         /* create any necessary new input ports */
888
889                         while (n_inputs().get(*t) < nin) {
890
891                                 char buf[64];
892
893                                 /* Create a new input port */
894
895                                 if (_input_maximum.get(*t) == 1) {
896                                         snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
897                                 } else {
898                                         snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole());
899                                 }
900
901                                 try {
902                                         if ((port = _session.engine().register_input_port (*t, buf)) == 0) {
903                                                 error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
904                                                 return -1;
905                                         }
906                                 }
907
908                                 catch (AudioEngine::PortRegistrationFailure& err) {
909                                         setup_peak_meters ();
910                                         reset_panner ();
911                                         /* pass it on */
912                                         throw err;
913                                 }
914
915                                 _inputs.add (port);
916                                 in_changed = true;
917                         }
918
919                         /* create any necessary new output ports */
920
921                         while (n_outputs().get(*t) < nout) {
922
923                                 char buf[64];
924
925                                 /* Create a new output port */
926
927                                 if (_output_maximum.get(*t) == 1) {
928                                         snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
929                                 } else {
930                                         snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
931                                 }
932
933                                 try { 
934                                         if ((port = _session.engine().register_output_port (*t, buf)) == 0) {
935                                                 error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
936                                                 return -1;
937                                         }
938                                 }
939
940                                 catch (AudioEngine::PortRegistrationFailure& err) {
941                                         setup_peak_meters ();
942                                         reset_panner ();
943                                         /* pass it on */
944                                         throw err;
945                                 }
946
947                                 _outputs.add (port);
948                                 out_changed = true;
949                         }
950                 }
951                 
952                 if (clear) {
953                         
954                         /* disconnect all existing ports so that we get a fresh start */
955                         
956                         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
957                                 _session.engine().disconnect (*i);
958                         }
959                         
960                         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
961                                 _session.engine().disconnect (*i);
962                         }
963                 }
964                 
965                 if (in_changed || out_changed) {
966                         setup_peak_meters ();
967                         reset_panner ();
968                 }
969         }
970
971         if (out_changed) {
972                 drop_output_connection ();
973                 output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
974         }
975         
976         if (in_changed) {
977                 drop_input_connection ();
978                 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
979         }
980
981         if (in_changed || out_changed) {
982                 MoreChannels (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */
983                 _session.set_dirty ();
984         }
985
986         return 0;
987 }
988
989 int
990 IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
991 {
992         bool changed = false;
993
994         count = min (_input_maximum, count);
995
996         if (count == n_inputs() && !clear) {
997                 return 0;
998         }
999
1000         if (lockit) {
1001                 Glib::Mutex::Lock em (_session.engine().process_lock());
1002                 Glib::Mutex::Lock im (io_lock);
1003                 changed = ensure_inputs_locked (count, clear, src);
1004         } else {
1005                 changed = ensure_inputs_locked (count, clear, src);
1006         }
1007
1008         if (changed) {
1009                 input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1010                 _session.set_dirty ();
1011         }
1012         return 0;
1013 }
1014
1015 bool
1016 IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
1017 {
1018         Port* output_port    = 0;
1019         bool  changed        = false;
1020         bool  need_pan_reset = false;
1021
1022         if (n_outputs() != count) {
1023                 need_pan_reset = true;
1024         }
1025         
1026         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1027
1028                 const size_t n = count.get(*t);
1029
1030                 /* remove unused ports */
1031                 for (size_t i = n_outputs().get(*t); i > n; --i) {
1032                         output_port = _outputs.port(*t, i-1);
1033
1034                         assert(output_port);
1035                         _outputs.remove(output_port);
1036                         _session.engine().unregister_port (*output_port);
1037
1038                         changed = true;
1039                 }
1040
1041                 /* create any necessary new ports */
1042                 while (n_outputs().get(*t) < n) {
1043
1044                         char buf[64];
1045
1046                         if (_output_maximum.get(*t) == 1) {
1047                                 snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
1048                         } else {
1049                                 snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
1050                         }
1051
1052                         if ((output_port = _session.engine().register_output_port (*t, buf)) == 0) {
1053                                 error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
1054                                 return -1;
1055                         }
1056
1057                         _outputs.add (output_port);
1058                         changed = true;
1059                         setup_peak_meters ();
1060
1061                         if (need_pan_reset) {
1062                                 reset_panner ();
1063                         }
1064                 }
1065         }
1066         
1067         if (changed) {
1068                 drop_output_connection ();
1069                 MoreChannels (n_outputs()); /* EMIT SIGNAL */
1070                 _session.set_dirty ();
1071         }
1072         
1073         if (clear) {
1074                 /* disconnect all existing ports so that we get a fresh start */
1075                 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1076                         _session.engine().disconnect (*i);
1077                 }
1078         }
1079
1080         return changed;
1081 }
1082
1083 int
1084 IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
1085 {
1086         bool changed = false;
1087
1088         if (_output_maximum < ChanCount::INFINITE) {
1089                 count = min (_output_maximum, count);
1090                 if (count == n_outputs() && !clear) {
1091                         return 0;
1092                 }
1093         }
1094
1095         /* XXX caller should hold io_lock, but generally doesn't */
1096
1097         if (lockit) {
1098                 Glib::Mutex::Lock em (_session.engine().process_lock());
1099                 Glib::Mutex::Lock im (io_lock);
1100                 changed = ensure_outputs_locked (count, clear, src);
1101         } else {
1102                 changed = ensure_outputs_locked (count, clear, src);
1103         }
1104
1105         if (changed) {
1106                  output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
1107         }
1108
1109         return 0;
1110 }
1111
1112 gain_t
1113 IO::effective_gain () const
1114 {
1115         if (gain_automation_playback()) {
1116                 return _effective_gain;
1117         } else {
1118                 return _desired_gain;
1119         }
1120 }
1121
1122 void
1123 IO::reset_panner ()
1124 {
1125         if (panners_legal) {
1126                 if (!no_panner_reset) {
1127                         _panner->reset (n_outputs().get(DataType::AUDIO), pans_required());
1128                 }
1129         } else {
1130                 panner_legal_c.disconnect ();
1131                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1132         }
1133 }
1134
1135 int
1136 IO::panners_became_legal ()
1137 {
1138         _panner->reset (n_outputs().get(DataType::AUDIO), pans_required());
1139         _panner->load (); // automation
1140         panner_legal_c.disconnect ();
1141         return 0;
1142 }
1143
1144 void
1145 IO::defer_pan_reset ()
1146 {
1147         no_panner_reset = true;
1148 }
1149
1150 void
1151 IO::allow_pan_reset ()
1152 {
1153         no_panner_reset = false;
1154         reset_panner ();
1155 }
1156
1157
1158 XMLNode&
1159 IO::get_state (void)
1160 {
1161         return state (true);
1162 }
1163
1164 XMLNode&
1165 IO::state (bool full_state)
1166 {
1167         XMLNode* node = new XMLNode (state_node_name);
1168         char buf[64];
1169         string str;
1170         bool need_ins = true;
1171         bool need_outs = true;
1172         LocaleGuard lg (X_("POSIX"));
1173         Glib::Mutex::Lock lm (io_lock);
1174
1175         node->add_property("name", _name);
1176         id().print (buf, sizeof (buf));
1177         node->add_property("id", buf);
1178
1179         str = "";
1180
1181         if (_input_connection) {
1182                 node->add_property ("input-connection", _input_connection->name());
1183                 need_ins = false;
1184         }
1185
1186         if (_output_connection) {
1187                 node->add_property ("output-connection", _output_connection->name());
1188                 need_outs = false;
1189         }
1190
1191         if (need_ins) {
1192                 for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1193                         
1194                         const char **connections = i->get_connections();
1195                         
1196                         if (connections && connections[0]) {
1197                                 str += '{';
1198                                 
1199                                 for (int n = 0; connections && connections[n]; ++n) {
1200                                         if (n) {
1201                                                 str += ',';
1202                                         }
1203                                         
1204                                         /* if its a connection to our own port,
1205                                            return only the port name, not the
1206                                            whole thing. this allows connections
1207                                            to be re-established even when our
1208                                            client name is different.
1209                                         */
1210                                         
1211                                         str += _session.engine().make_port_name_relative (connections[n]);
1212                                 }       
1213
1214                                 str += '}';
1215                                 
1216                                 free (connections);
1217                         }
1218                         else {
1219                                 str += "{}";
1220                         }
1221                 }
1222                 
1223                 node->add_property ("inputs", str);
1224         }
1225
1226         if (need_outs) {
1227                 str = "";
1228                 
1229                 for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1230                         
1231                         const char **connections = i->get_connections();
1232                         
1233                         if (connections && connections[0]) {
1234                                 
1235                                 str += '{';
1236                                 
1237                                 for (int n = 0; connections[n]; ++n) {
1238                                         if (n) {
1239                                                 str += ',';
1240                                         }
1241
1242                                         str += _session.engine().make_port_name_relative (connections[n]);
1243                                 }
1244
1245                                 str += '}';
1246                                 
1247                                 free (connections);
1248                         }
1249                         else {
1250                                 str += "{}";
1251                         }
1252                 }
1253                 
1254                 node->add_property ("outputs", str);
1255         }
1256
1257         node->add_child_nocopy (_panner->state (full_state));
1258         node->add_child_nocopy (_gain_control.get_state ());
1259
1260         snprintf (buf, sizeof(buf), "%2.12f", gain());
1261         node->add_property ("gain", buf);
1262
1263         // FIXME: this is NOT sufficient!
1264         const int in_min  = (_input_minimum == ChanCount::ZERO) ? -1 : _input_minimum.get(_default_type);
1265         const int in_max  = (_input_maximum == ChanCount::INFINITE) ? -1 : _input_maximum.get(_default_type);
1266         const int out_min = (_output_minimum == ChanCount::ZERO) ? -1 : _output_minimum.get(_default_type);
1267         const int out_max = (_output_maximum == ChanCount::INFINITE) ? -1 : _output_maximum.get(_default_type);
1268
1269         snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d", in_min, in_max, out_min, out_max);
1270
1271         node->add_property ("iolimits", buf);
1272
1273         /* automation */
1274
1275         if (full_state) {
1276
1277                 XMLNode* autonode = new XMLNode (X_("Automation"));
1278                 autonode->add_child_nocopy (get_automation_state());
1279                 node->add_child_nocopy (*autonode);
1280
1281                 snprintf (buf, sizeof (buf), "0x%x", (int) _gain_automation_curve.automation_state());
1282         } else {
1283                 /* never store anything except Off for automation state in a template */
1284                 snprintf (buf, sizeof (buf), "0x%x", ARDOUR::Off); 
1285         }
1286
1287         return *node;
1288 }
1289
1290 int
1291 IO::set_state (const XMLNode& node)
1292 {
1293         const XMLProperty* prop;
1294         XMLNodeConstIterator iter;
1295         LocaleGuard lg (X_("POSIX"));
1296
1297         /* force use of non-localized representation of decimal point,
1298            since we use it a lot in XML files and so forth.
1299         */
1300
1301         if (node.name() != state_node_name) {
1302                 error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg;
1303                 return -1;
1304         }
1305
1306         if ((prop = node.property ("name")) != 0) {
1307                 _name = prop->value();
1308                 /* used to set panner name with this, but no more */
1309         } 
1310
1311         if ((prop = node.property ("id")) != 0) {
1312                 _id = prop->value ();
1313         }
1314
1315         size_t in_min =  -1;
1316         size_t in_max  = -1;
1317         size_t out_min = -1;
1318         size_t out_max = -1;
1319
1320         if ((prop = node.property ("iolimits")) != 0) {
1321                 sscanf (prop->value().c_str(), "%zd,%zd,%zd,%zd",
1322                         &in_min, &in_max, &out_min, &out_max);
1323                 _input_minimum = ChanCount(_default_type, in_min);
1324                 _input_maximum = ChanCount(_default_type, in_max);
1325                 _output_minimum = ChanCount(_default_type, out_min);
1326                 _output_maximum = ChanCount(_default_type, out_max);
1327         }
1328         
1329         if ((prop = node.property ("gain")) != 0) {
1330                 set_gain (atof (prop->value().c_str()), this);
1331                 _gain = _desired_gain;
1332         }
1333
1334         if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) {
1335                 /* old school automation handling */
1336         }
1337
1338         for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
1339
1340                 if ((*iter)->name() == "Panner") {
1341                         if (_panner == 0) {
1342                                 _panner = new Panner (_name, _session);
1343                         }
1344                         _panner->set_state (**iter);
1345                 }
1346
1347                 if ((*iter)->name() == X_("Automation")) {
1348
1349                         set_automation_state (*(*iter)->children().front());
1350                 }
1351
1352                 if ((*iter)->name() == X_("gaincontrol")) {
1353                         _gain_control.set_state (**iter);
1354                 }
1355         }
1356
1357         if (ports_legal) {
1358
1359                 if (create_ports (node)) {
1360                         return -1;
1361                 }
1362
1363         } else {
1364
1365                 port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
1366         }
1367
1368         if (panners_legal) {
1369                 reset_panner ();
1370         } else {
1371                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1372         }
1373
1374         if (connecting_legal) {
1375
1376                 if (make_connections (node)) {
1377                         return -1;
1378                 }
1379
1380         } else {
1381                 
1382                 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
1383         }
1384
1385         if (!ports_legal || !connecting_legal) {
1386                 pending_state_node = new XMLNode (node);
1387         }
1388
1389         last_automation_snapshot = 0;
1390
1391         return 0;
1392 }
1393
1394 int
1395 IO::set_automation_state (const XMLNode& node)
1396 {
1397         return _gain_automation_curve.set_state (node);
1398 }
1399
1400 XMLNode&
1401 IO::get_automation_state ()
1402 {
1403         return (_gain_automation_curve.get_state ());
1404 }
1405
1406 int
1407 IO::load_automation (string path)
1408 {
1409         string fullpath;
1410         ifstream in;
1411         char line[128];
1412         uint32_t linecnt = 0;
1413         float version;
1414         LocaleGuard lg (X_("POSIX"));
1415
1416         fullpath = _session.automation_dir();
1417         fullpath += path;
1418
1419         in.open (fullpath.c_str());
1420
1421         if (!in) {
1422                 fullpath = _session.automation_dir();
1423                 fullpath += _session.snap_name();
1424                 fullpath += '-';
1425                 fullpath += path;
1426
1427                 in.open (fullpath.c_str());
1428
1429                 if (!in) {
1430                         error << string_compose(_("%1: cannot open automation event file \"%2\""), _name, fullpath) << endmsg;
1431                         return -1;
1432                 }
1433         }
1434
1435         clear_automation ();
1436
1437         while (in.getline (line, sizeof(line), '\n')) {
1438                 char type;
1439                 jack_nframes_t when;
1440                 double value;
1441
1442                 if (++linecnt == 1) {
1443                         if (memcmp (line, "version", 7) == 0) {
1444                                 if (sscanf (line, "version %f", &version) != 1) {
1445                                         error << string_compose(_("badly formed version number in automation event file \"%1\""), path) << endmsg;
1446                                         return -1;
1447                                 }
1448                         } else {
1449                                 error << string_compose(_("no version information in automation event file \"%1\""), path) << endmsg;
1450                                 return -1;
1451                         }
1452
1453                         continue;
1454                 }
1455
1456                 if (sscanf (line, "%c %" PRIu32 " %lf", &type, &when, &value) != 3) {
1457                         warning << string_compose(_("badly formatted automation event record at line %1 of %2 (ignored)"), linecnt, path) << endmsg;
1458                         continue;
1459                 }
1460
1461                 switch (type) {
1462                 case 'g':
1463                         _gain_automation_curve.fast_simple_add (when, value);
1464                         break;
1465
1466                 case 's':
1467                         break;
1468
1469                 case 'm':
1470                         break;
1471
1472                 case 'p':
1473                         /* older (pre-1.0) versions of ardour used this */
1474                         break;
1475
1476                 default:
1477                         warning << _("dubious automation event found (and ignored)") << endmsg;
1478                 }
1479         }
1480
1481         return 0;
1482 }
1483
1484 int
1485 IO::connecting_became_legal ()
1486 {
1487         int ret;
1488
1489         if (pending_state_node == 0) {
1490                 fatal << _("IO::connecting_became_legal() called without a pending state node") << endmsg;
1491                 /*NOTREACHED*/
1492                 return -1;
1493         }
1494
1495         connection_legal_c.disconnect ();
1496
1497         ret = make_connections (*pending_state_node);
1498
1499         if (ports_legal) {
1500                 delete pending_state_node;
1501                 pending_state_node = 0;
1502         }
1503
1504         return ret;
1505 }
1506 int
1507 IO::ports_became_legal ()
1508 {
1509         int ret;
1510
1511         if (pending_state_node == 0) {
1512                 fatal << _("IO::ports_became_legal() called without a pending state node") << endmsg;
1513                 /*NOTREACHED*/
1514                 return -1;
1515         }
1516
1517         port_legal_c.disconnect ();
1518
1519         ret = create_ports (*pending_state_node);
1520
1521         if (connecting_legal) {
1522                 delete pending_state_node;
1523                 pending_state_node = 0;
1524         }
1525
1526         return ret;
1527 }
1528
1529 int
1530 IO::create_ports (const XMLNode& node)
1531 {
1532         const XMLProperty* prop;
1533         int num_inputs = 0;
1534         int num_outputs = 0;
1535
1536         if ((prop = node.property ("input-connection")) != 0) {
1537
1538                 Connection* c = _session.connection_by_name (prop->value());
1539                 
1540                 if (c == 0) {
1541                         error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
1542
1543                         if ((c = _session.connection_by_name (_("in 1"))) == 0) {
1544                                 error << _("No input connections available as a replacement")
1545                                       << endmsg;
1546                                 return -1;
1547                         }  else {
1548                                 info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
1549                                      << endmsg;
1550                         }
1551                 } 
1552
1553                 num_inputs = c->nports();
1554
1555         } else if ((prop = node.property ("inputs")) != 0) {
1556
1557                 num_inputs = count (prop->value().begin(), prop->value().end(), '{');
1558         }
1559         
1560         if ((prop = node.property ("output-connection")) != 0) {
1561                 Connection* c = _session.connection_by_name (prop->value());
1562
1563                 if (c == 0) {
1564                         error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
1565
1566                         if ((c = _session.connection_by_name (_("out 1"))) == 0) {
1567                                 error << _("No output connections available as a replacement")
1568                                       << endmsg;
1569                                 return -1;
1570                         }  else {
1571                                 info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
1572                                      << endmsg;
1573                         }
1574                 } 
1575
1576                 num_outputs = c->nports ();
1577                 
1578         } else if ((prop = node.property ("outputs")) != 0) {
1579                 num_outputs = count (prop->value().begin(), prop->value().end(), '{');
1580         }
1581
1582         no_panner_reset = true;
1583
1584         // FIXME: audio-only
1585         if (ensure_io (ChanCount(DataType::AUDIO, num_inputs), ChanCount(DataType::AUDIO, num_outputs), true, this)) {
1586                 error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
1587                 return -1;
1588         }
1589
1590         no_panner_reset = false;
1591
1592         set_deferred_state ();
1593
1594         PortsCreated();
1595         return 0;
1596 }
1597
1598
1599 int
1600 IO::make_connections (const XMLNode& node)
1601 {
1602         const XMLProperty* prop;
1603
1604         if ((prop = node.property ("input-connection")) != 0) {
1605                 Connection* c = _session.connection_by_name (prop->value());
1606                 
1607                 if (c == 0) {
1608                         error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
1609
1610                         if ((c = _session.connection_by_name (_("in 1"))) == 0) {
1611                                 error << _("No input connections available as a replacement")
1612                                       << endmsg;
1613                                 return -1;
1614                         } else {
1615                                 info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
1616                                      << endmsg;
1617                         }
1618                 } 
1619
1620                 use_input_connection (*c, this);
1621
1622         } else if ((prop = node.property ("inputs")) != 0) {
1623                 if (set_inputs (prop->value())) {
1624                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
1625                         return -1;
1626                 }
1627         }
1628         
1629         if ((prop = node.property ("output-connection")) != 0) {
1630                 Connection* c = _session.connection_by_name (prop->value());
1631                 
1632                 if (c == 0) {
1633                         error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
1634
1635                         if ((c = _session.connection_by_name (_("out 1"))) == 0) {
1636                                 error << _("No output connections available as a replacement")
1637                                       << endmsg;
1638                                 return -1;
1639                         }  else {
1640                                 info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
1641                                      << endmsg;
1642                         }
1643                 } 
1644
1645                 use_output_connection (*c, this);
1646                 
1647         } else if ((prop = node.property ("outputs")) != 0) {
1648                 if (set_outputs (prop->value())) {
1649                         error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
1650                         return -1;
1651                 }
1652         }
1653         
1654         return 0;
1655 }
1656
1657 int
1658 IO::set_inputs (const string& str)
1659 {
1660         vector<string> ports;
1661         int i;
1662         int n;
1663         uint32_t nports;
1664         
1665         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1666                 return 0;
1667         }
1668
1669         // FIXME: audio-only
1670         if (ensure_inputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1671                 return -1;
1672         }
1673
1674         string::size_type start, end, ostart;
1675
1676         ostart = 0;
1677         start = 0;
1678         end = 0;
1679         i = 0;
1680
1681         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1682                 start += 1;
1683
1684                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1685                         error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
1686                         return -1;
1687                 }
1688
1689                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1690                         error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
1691
1692                         return -1;
1693                         
1694                 } else if (n > 0) {
1695
1696                         for (int x = 0; x < n; ++x) {
1697                                 connect_input (input (i), ports[x], this);
1698                         }
1699                 }
1700
1701                 ostart = end+1;
1702                 i++;
1703         }
1704
1705         return 0;
1706 }
1707
1708 int
1709 IO::set_outputs (const string& str)
1710 {
1711         vector<string> ports;
1712         int i;
1713         int n;
1714         uint32_t nports;
1715         
1716         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1717                 return 0;
1718         }
1719
1720         // FIXME: audio-only
1721         if (ensure_outputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1722                 return -1;
1723         }
1724
1725         string::size_type start, end, ostart;
1726
1727         ostart = 0;
1728         start = 0;
1729         end = 0;
1730         i = 0;
1731
1732         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1733                 start += 1;
1734
1735                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1736                         error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg;
1737                         return -1;
1738                 }
1739
1740                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1741                         error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg;
1742
1743                         return -1;
1744                         
1745                 } else if (n > 0) {
1746
1747                         for (int x = 0; x < n; ++x) {
1748                                 connect_output (output (i), ports[x], this);
1749                         }
1750                 }
1751
1752                 ostart = end+1;
1753                 i++;
1754         }
1755
1756         return 0;
1757 }
1758
1759 int
1760 IO::parse_io_string (const string& str, vector<string>& ports)
1761 {
1762         string::size_type pos, opos;
1763
1764         if (str.length() == 0) {
1765                 return 0;
1766         }
1767
1768         pos = 0;
1769         opos = 0;
1770
1771         ports.clear ();
1772
1773         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1774                 ports.push_back (str.substr (opos, pos - opos));
1775                 opos = pos + 1;
1776         }
1777         
1778         if (opos < str.length()) {
1779                 ports.push_back (str.substr(opos));
1780         }
1781
1782         return ports.size();
1783 }
1784
1785 int
1786 IO::parse_gain_string (const string& str, vector<string>& ports)
1787 {
1788         string::size_type pos, opos;
1789
1790         pos = 0;
1791         opos = 0;
1792         ports.clear ();
1793
1794         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1795                 ports.push_back (str.substr (opos, pos - opos));
1796                 opos = pos + 1;
1797         }
1798         
1799         if (opos < str.length()) {
1800                 ports.push_back (str.substr(opos));
1801         }
1802
1803         return ports.size();
1804 }
1805
1806 int
1807 IO::set_name (string name, void* src)
1808 {
1809         if (name == _name) {
1810                 return 0;
1811         }
1812
1813         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1814                 string current_name = i->short_name();
1815                 current_name.replace (current_name.find (_name), _name.length(), name);
1816                 i->set_name (current_name);
1817         }
1818
1819         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1820                 string current_name = i->short_name();
1821                 current_name.replace (current_name.find (_name), _name.length(), name);
1822                 i->set_name (current_name);
1823         }
1824
1825         _name = name;
1826          name_changed (src); /* EMIT SIGNAL */
1827
1828          return 0;
1829 }
1830
1831 void
1832 IO::set_input_minimum (ChanCount n)
1833 {
1834         _input_minimum = n;
1835 }
1836
1837 void
1838 IO::set_input_maximum (ChanCount n)
1839 {
1840         _input_maximum = n;
1841 }
1842
1843 void
1844 IO::set_output_minimum (ChanCount n)
1845 {
1846         _output_minimum = n;
1847 }
1848
1849 void
1850 IO::set_output_maximum (ChanCount n)
1851 {
1852         _output_maximum = n;
1853 }
1854
1855 void
1856 IO::set_port_latency (nframes_t nframes)
1857 {
1858         Glib::Mutex::Lock lm (io_lock);
1859
1860         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1861                 i->set_latency (nframes);
1862         }
1863 }
1864
1865 nframes_t
1866 IO::output_latency () const
1867 {
1868         nframes_t max_latency;
1869         nframes_t latency;
1870
1871         max_latency = 0;
1872
1873         /* io lock not taken - must be protected by other means */
1874
1875         for (PortSet::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1876                 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
1877                         max_latency = latency;
1878                 }
1879         }
1880
1881         return max_latency;
1882 }
1883
1884 nframes_t
1885 IO::input_latency () const
1886 {
1887         nframes_t max_latency;
1888         nframes_t latency;
1889
1890         max_latency = 0;
1891
1892         /* io lock not taken - must be protected by other means */
1893
1894         for (PortSet::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1895                 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
1896                         max_latency = latency;
1897                 }
1898         }
1899
1900         return max_latency;
1901 }
1902
1903 int
1904 IO::use_input_connection (Connection& c, void* src)
1905 {
1906         uint32_t limit;
1907
1908         {
1909                 Glib::Mutex::Lock lm (_session.engine().process_lock());
1910                 Glib::Mutex::Lock lm2 (io_lock);
1911                 
1912                 limit = c.nports();
1913                 
1914                 drop_input_connection ();
1915                 
1916                 // FIXME connections only work for audio-only
1917                 if (ensure_inputs (ChanCount(DataType::AUDIO, limit), false, false, src)) {
1918                         return -1;
1919                 }
1920
1921                 /* first pass: check the current state to see what's correctly
1922                    connected, and drop anything that we don't want.
1923                 */
1924                 
1925                 for (uint32_t n = 0; n < limit; ++n) {
1926                         const Connection::PortList& pl = c.port_connections (n);
1927                         
1928                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
1929                                 
1930                                 if (!_inputs.port(n)->connected_to ((*i))) {
1931                                         
1932                                         /* clear any existing connections */
1933                                         
1934                                         _session.engine().disconnect (*_inputs.port(n));
1935                                         
1936                                 } else if (_inputs.port(n)->connected() > 1) {
1937                                         
1938                                         /* OK, it is connected to the port we want,
1939                                            but its also connected to other ports.
1940                                            Change that situation.
1941                                         */
1942                                         
1943                                         /* XXX could be optimized to not drop
1944                                            the one we want.
1945                                         */
1946                                         
1947                                         _session.engine().disconnect (*_inputs.port(n));
1948                                         
1949                                 }
1950                         }
1951                 }
1952                 
1953                 /* second pass: connect all requested ports where necessary */
1954                 
1955                 for (uint32_t n = 0; n < limit; ++n) {
1956                         const Connection::PortList& pl = c.port_connections (n);
1957                         
1958                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
1959                                 
1960                                 if (!_inputs.port(n)->connected_to ((*i))) {
1961                                         
1962                                         if (_session.engine().connect (*i, _inputs.port(n)->name())) {
1963                                                 return -1;
1964                                         }
1965                                 }
1966                                 
1967                         }
1968                 }
1969                 
1970                 _input_connection = &c;
1971                 
1972                 input_connection_configuration_connection = c.ConfigurationChanged.connect
1973                         (mem_fun (*this, &IO::input_connection_configuration_changed));
1974                 input_connection_connection_connection = c.ConnectionsChanged.connect
1975                         (mem_fun (*this, &IO::input_connection_connection_changed));
1976         }
1977
1978         input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
1979         return 0;
1980 }
1981
1982 int
1983 IO::use_output_connection (Connection& c, void* src)
1984 {
1985         uint32_t limit; 
1986
1987         {
1988                 Glib::Mutex::Lock lm (_session.engine().process_lock());
1989                 Glib::Mutex::Lock lm2 (io_lock);
1990
1991                 limit = c.nports();
1992                         
1993                 drop_output_connection ();
1994
1995                 // FIXME: audio-only
1996                 if (ensure_outputs (ChanCount(DataType::AUDIO, limit), false, false, src)) {
1997                         return -1;
1998                 }
1999
2000                 /* first pass: check the current state to see what's correctly
2001                    connected, and drop anything that we don't want.
2002                 */
2003                         
2004                 for (uint32_t n = 0; n < limit; ++n) {
2005
2006                         const Connection::PortList& pl = c.port_connections (n);
2007                                 
2008                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2009                                         
2010                                 if (!_outputs.port(n)->connected_to ((*i))) {
2011
2012                                         /* clear any existing connections */
2013
2014                                         _session.engine().disconnect (*_outputs.port(n));
2015
2016                                 } else if (_outputs.port(n)->connected() > 1) {
2017
2018                                         /* OK, it is connected to the port we want,
2019                                            but its also connected to other ports.
2020                                            Change that situation.
2021                                         */
2022
2023                                         /* XXX could be optimized to not drop
2024                                            the one we want.
2025                                         */
2026                                                 
2027                                         _session.engine().disconnect (*_outputs.port(n));
2028                                 }
2029                         }
2030                 }
2031
2032                 /* second pass: connect all requested ports where necessary */
2033
2034                 for (uint32_t n = 0; n < limit; ++n) {
2035
2036                         const Connection::PortList& pl = c.port_connections (n);
2037                                 
2038                         for (Connection::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2039                                         
2040                                 if (!_outputs.port(n)->connected_to ((*i))) {
2041                                                 
2042                                         if (_session.engine().connect (_outputs.port(n)->name(), *i)) {
2043                                                 return -1;
2044                                         }
2045                                 }
2046                         }
2047                 }
2048
2049                 _output_connection = &c;
2050
2051                 output_connection_configuration_connection = c.ConfigurationChanged.connect
2052                         (mem_fun (*this, &IO::output_connection_configuration_changed));
2053                 output_connection_connection_connection = c.ConnectionsChanged.connect
2054                         (mem_fun (*this, &IO::output_connection_connection_changed));
2055         }
2056
2057         output_changed (IOChange (ConnectionsChanged|ConfigurationChanged), src); /* EMIT SIGNAL */
2058
2059         return 0;
2060 }
2061
2062 int
2063 IO::disable_connecting ()
2064 {
2065         connecting_legal = false;
2066         return 0;
2067 }
2068
2069 int
2070 IO::enable_connecting ()
2071 {
2072         connecting_legal = true;
2073         return ConnectingLegal ();
2074 }
2075
2076 int
2077 IO::disable_ports ()
2078 {
2079         ports_legal = false;
2080         return 0;
2081 }
2082
2083 int
2084 IO::enable_ports ()
2085 {
2086         ports_legal = true;
2087         return PortsLegal ();
2088 }
2089
2090 int
2091 IO::disable_panners (void)
2092 {
2093         panners_legal = false;
2094         return 0;
2095 }
2096
2097 int
2098 IO::reset_panners ()
2099 {
2100         panners_legal = true;
2101         return PannersLegal ();
2102 }
2103
2104 void
2105 IO::input_connection_connection_changed (int ignored)
2106 {
2107         use_input_connection (*_input_connection, this);
2108 }
2109
2110 void
2111 IO::input_connection_configuration_changed ()
2112 {
2113         use_input_connection (*_input_connection, this);
2114 }
2115
2116 void
2117 IO::output_connection_connection_changed (int ignored)
2118 {
2119         use_output_connection (*_output_connection, this);
2120 }
2121
2122 void
2123 IO::output_connection_configuration_changed ()
2124 {
2125         use_output_connection (*_output_connection, this);
2126 }
2127
2128 void
2129 IO::GainControllable::set_value (float val)
2130 {
2131         io.set_gain (direct_control_to_gain (val), this);
2132 }
2133
2134 float
2135 IO::GainControllable::get_value (void) const
2136 {
2137         return direct_gain_to_control (io.effective_gain());
2138 }
2139
2140 void
2141 IO::setup_peak_meters()
2142 {
2143         _meter->setup(std::max(_inputs.count(), _outputs.count()));
2144 }
2145
2146 /**
2147     Update the peak meters.
2148
2149     The meter signal lock is taken to prevent modification of the 
2150     Meter signal while updating the meters, taking the meter signal
2151     lock prior to taking the io_lock ensures that all IO will remain 
2152     valid while metering.
2153 */   
2154 void
2155 IO::update_meters()
2156 {
2157     Glib::Mutex::Lock guard (m_meter_signal_lock);
2158     
2159     Meter(); /* EMIT SIGNAL */
2160 }
2161
2162 void
2163 IO::meter ()
2164 {
2165         // FIXME: Ugly.  Meter should manage the lock, if it's necessary
2166         
2167         Glib::Mutex::Lock lm (io_lock); // READER: meter thread.
2168         _meter->meter();
2169 }
2170
2171 void
2172 IO::clear_automation ()
2173 {
2174         Glib::Mutex::Lock lm (automation_lock);
2175         _gain_automation_curve.clear ();
2176         _panner->clear_automation ();
2177 }
2178
2179 void
2180 IO::set_gain_automation_state (AutoState state)
2181 {
2182         bool changed = false;
2183
2184         {
2185                 Glib::Mutex::Lock lm (automation_lock);
2186
2187                 if (state != _gain_automation_curve.automation_state()) {
2188                         changed = true;
2189                         last_automation_snapshot = 0;
2190                         _gain_automation_curve.set_automation_state (state);
2191                         
2192                         if (state != Off) {
2193                                 set_gain (_gain_automation_curve.eval (_session.transport_frame()), this);
2194                         }
2195                 }
2196         }
2197
2198         if (changed) {
2199                 _session.set_dirty ();
2200                 gain_automation_state_changed (); /* EMIT SIGNAL */
2201         }
2202 }
2203
2204 void
2205 IO::set_gain_automation_style (AutoStyle style)
2206 {
2207         bool changed = false;
2208
2209         {
2210                 Glib::Mutex::Lock lm (automation_lock);
2211
2212                 if (style != _gain_automation_curve.automation_style()) {
2213                         changed = true;
2214                         _gain_automation_curve.set_automation_style (style);
2215                 }
2216         }
2217
2218         if (changed) {
2219                 gain_automation_style_changed (); /* EMIT SIGNAL */
2220         }
2221 }
2222 void
2223 IO::inc_gain (gain_t factor, void *src)
2224 {
2225         if (_desired_gain == 0.0f)
2226                 set_gain (0.000001f + (0.000001f * factor), src);
2227         else
2228                 set_gain (_desired_gain + (_desired_gain * factor), src);
2229 }
2230
2231 void
2232 IO::set_gain (gain_t val, void *src)
2233 {
2234         // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2235         if (val>1.99526231f) val=1.99526231f;
2236
2237         {
2238                 Glib::Mutex::Lock dm (declick_lock);
2239                 _desired_gain = val;
2240         }
2241
2242         if (_session.transport_stopped()) {
2243                 _effective_gain = val;
2244                 _gain = val;
2245         }
2246
2247         gain_changed (src);
2248         _gain_control.Changed (); /* EMIT SIGNAL */
2249         
2250         if (_session.transport_stopped() && src != 0 && src != this && gain_automation_recording()) {
2251                 _gain_automation_curve.add (_session.transport_frame(), val);
2252                 
2253         }
2254
2255         _session.set_dirty();
2256 }
2257
2258 void
2259 IO::start_gain_touch ()
2260 {
2261         _gain_automation_curve.start_touch ();
2262 }
2263
2264 void
2265 IO::end_gain_touch ()
2266 {
2267         _gain_automation_curve.stop_touch ();
2268 }
2269
2270 void
2271 IO::start_pan_touch (uint32_t which)
2272 {
2273         if (which < _panner->size()) {
2274                 (*_panner)[which]->automation().start_touch();
2275         }
2276 }
2277
2278 void
2279 IO::end_pan_touch (uint32_t which)
2280 {
2281         if (which < _panner->size()) {
2282                 (*_panner)[which]->automation().stop_touch();
2283         }
2284
2285 }
2286
2287 void
2288 IO::automation_snapshot (nframes_t now)
2289 {
2290         if (last_automation_snapshot > now || (now - last_automation_snapshot) > _automation_interval) {
2291
2292                 if (gain_automation_recording()) {
2293                         _gain_automation_curve.rt_add (now, gain());
2294                 }
2295                 
2296                 _panner->snapshot (now);
2297
2298                 last_automation_snapshot = now;
2299         }
2300 }
2301
2302 void
2303 IO::transport_stopped (nframes_t frame)
2304 {
2305         _gain_automation_curve.reposition_for_rt_add (frame);
2306
2307         if (_gain_automation_curve.automation_state() != Off) {
2308                 
2309                 /* the src=0 condition is a special signal to not propagate 
2310                    automation gain changes into the mix group when locating.
2311                 */
2312
2313                 set_gain (_gain_automation_curve.eval (frame), 0);
2314         }
2315
2316         _panner->transport_stopped (frame);
2317 }
2318
2319 int32_t
2320 IO::find_input_port_hole ()
2321 {
2322         /* CALLER MUST HOLD IO LOCK */
2323
2324         uint32_t n;
2325
2326         if (_inputs.empty()) {
2327                 return 1;
2328         }
2329
2330         for (n = 1; n < UINT_MAX; ++n) {
2331                 char buf[jack_port_name_size()];
2332                 PortSet::iterator i = _inputs.begin();
2333
2334                 snprintf (buf, jack_port_name_size(), _("%s/in %u"), _name.c_str(), n);
2335
2336                 for ( ; i != _inputs.end(); ++i) {
2337                         if (i->short_name() == buf) {
2338                                 break;
2339                         }
2340                 }
2341
2342                 if (i == _inputs.end()) {
2343                         break;
2344                 }
2345         }
2346         return n;
2347 }
2348
2349 int32_t
2350 IO::find_output_port_hole ()
2351 {
2352         /* CALLER MUST HOLD IO LOCK */
2353
2354         uint32_t n;
2355
2356         if (_outputs.empty()) {
2357                 return 1;
2358         }
2359
2360         for (n = 1; n < UINT_MAX; ++n) {
2361                 char buf[jack_port_name_size()];
2362                 PortSet::iterator i = _outputs.begin();
2363
2364                 snprintf (buf, jack_port_name_size(), _("%s/out %u"), _name.c_str(), n);
2365
2366                 for ( ; i != _outputs.end(); ++i) {
2367                         if (i->short_name() == buf) {
2368                                 break;
2369                         }
2370                 }
2371
2372                 if (i == _outputs.end()) {
2373                         break;
2374                 }
2375         }
2376         
2377         return n;
2378 }
2379
2380 AudioPort*
2381 IO::audio_input(uint32_t n) const
2382 {
2383         return dynamic_cast<AudioPort*>(input(n));
2384 }
2385
2386 AudioPort*
2387 IO::audio_output(uint32_t n) const
2388 {
2389         return dynamic_cast<AudioPort*>(output(n));
2390 }
2391
2392 MidiPort*
2393 IO::midi_input(uint32_t n) const
2394 {
2395         return dynamic_cast<MidiPort*>(input(n));
2396 }
2397
2398 MidiPort*
2399 IO::midi_output(uint32_t n) const
2400 {
2401         return dynamic_cast<MidiPort*>(output(n));
2402 }
2403
2404 void
2405 IO::set_phase_invert (bool yn, void *src)
2406 {
2407         if (_phase_invert != yn) {
2408                 _phase_invert = yn;
2409         }
2410         //  phase_invert_changed (src); /* EMIT SIGNAL */
2411 }
2412