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