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