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