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