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