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