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