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