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