Apply panners/automation patch from torbenh (Panner is-a Processor).
[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(Evoral::Parameter(GainAutomation)));
142
143         _gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
144
145         add_control(_gain_control);
146
147         apply_gain_automation = false;
148         
149         {
150                 // IO::Meter is emitted from another thread so the
151                 // Meter signal must be protected.
152                 Glib::Mutex::Lock guard (m_meter_signal_lock);
153                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
154         }
155         
156         // Connect to our own PortCountChanged signal to connect output buffers
157         IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
158
159         _session.add_controllable (_gain_control);
160
161         create_bundles_for_inputs_and_outputs ();
162 }
163
164 IO::IO (Session& s, const XMLNode& node, DataType dt)
165         : SessionObject(s, "unnamed io"),
166           AutomatableControls (s),
167           _output_buffers (new BufferSet()),
168           _active(true),
169           _default_type (dt)
170 {
171         _meter = new PeakMeter (_session);
172         _public_ports = true; // XXX get this from node
173         _panner = 0;
174         deferred_state = 0;
175         no_panner_reset = false;
176         _desired_gain = 1.0;
177         _gain = 1.0;
178
179         apply_gain_automation = false;
180         
181         boost::shared_ptr<AutomationList> gl(
182                         new AutomationList(Evoral::Parameter(GainAutomation)));
183
184         _gain_control = boost::shared_ptr<GainControl>(
185                         new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl));
186
187         add_control(_gain_control);
188
189         set_state (node);
190
191         {
192                 // IO::Meter is emitted from another thread so the
193                 // Meter signal must be protected.
194                 Glib::Mutex::Lock guard (m_meter_signal_lock);
195                 m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
196         }
197         
198         // Connect to our own PortCountChanged signal to connect output buffers
199         IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
200
201         _session.add_controllable (_gain_control);
202
203         create_bundles_for_inputs_and_outputs ();
204 }
205
206 IO::~IO ()
207 {
208         Glib::Mutex::Lock guard (m_meter_signal_lock);
209         Glib::Mutex::Lock lm (io_lock);
210
211         BLOCK_PROCESS_CALLBACK ();
212
213         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
214                 _session.engine().unregister_port (*i);
215         }
216
217         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
218                 _session.engine().unregister_port (*i);
219         }
220
221         m_meter_connection.disconnect();
222
223         delete _meter;
224         delete _panner;
225         delete _output_buffers;
226 }
227
228 void
229 IO::silence (nframes_t nframes, nframes_t offset)
230 {
231         /* io_lock, not taken: function must be called from Session::process() calltree */
232
233         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
234                 i->get_buffer().silence (nframes, offset);
235         }
236 }
237
238 /** Deliver bufs to the IO's output ports
239  *
240  * This function should automatically do whatever it necessary to correctly deliver bufs
241  * to the outputs, eg applying gain or pan or whatever else needs to be done.
242  */
243 void
244 IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
245 {
246         // FIXME: type specific code doesn't actually need to be here, it will go away in time
247
248         /* ********** AUDIO ********** */
249
250         // Apply gain if gain automation isn't playing
251         if ( ! apply_gain_automation) {
252                 
253                 gain_t dg = _gain; // desired gain
254
255                 {
256                         Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK);
257
258                         if (dm.locked()) {
259                                 dg = _desired_gain;
260                         }
261
262                 }
263
264                 if (dg != _gain || dg != 1.0)
265                         Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert);
266         }
267
268         // Use the panner to distribute audio to output port buffers
269         if( _panner && _panner->npanners() && !_panner->bypassed()) {
270                 _panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
271         } else {
272                 const DataType type = DataType::AUDIO;
273                 
274                 // Copy any audio 1:1 to outputs
275                 
276                 BufferSet::iterator o = output_buffers().begin(type);
277                 BufferSet::iterator i = bufs.begin(type);
278                 BufferSet::iterator prev = i;
279                 
280                 while (i != bufs.end(type) && o != output_buffers().end (type)) {
281                         o->read_from(*i, nframes, offset);
282                         prev = i;
283                         ++i;
284                         ++o;
285                 }
286
287                 /* extra outputs get a copy of the last buffer */
288
289                 while (o != output_buffers().end(type)) {
290                         o->read_from(*prev, nframes, offset);
291                         ++o;
292                 }
293         }
294
295         /* ********** MIDI ********** */
296
297         // No MIDI, we're done here
298         if (bufs.count().n_midi() == 0) {
299                 return;
300         }
301
302         const DataType type = DataType::MIDI;
303
304         // Copy any MIDI 1:1 to outputs
305         assert(bufs.count().n_midi() == output_buffers().count().n_midi());
306         BufferSet::iterator o = output_buffers().begin(type);
307         for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) {
308                 o->read_from(*i, nframes, offset);
309         }
310 }
311
312 void
313 IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
314 {
315         assert(outs.available() >= n_inputs());
316         
317         if (n_inputs() == ChanCount::ZERO)
318                 return;
319
320         outs.set_count(n_inputs());
321         
322         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
323                 
324                 BufferSet::iterator o = outs.begin(*t);
325                 for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
326                         (*i).cycle_start (nframes, offset);
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                 // Old school Panner.
1405                 if ((*iter)->name() == "Panner") {
1406                         if (_panner == 0) {
1407                                 _panner = new Panner (_name, _session);
1408                         }
1409                         _panner->set_state (**iter);
1410                 }
1411
1412                 if ((*iter)->name() == "Processor") {
1413                         if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
1414                                 if (_panner == 0) {
1415                                         _panner = new Panner (_name, _session);
1416                                 }
1417                                 _panner->set_state (**iter);
1418                         }
1419                 }
1420
1421                 if ((*iter)->name() == X_("Automation")) {
1422
1423                         set_automation_state (*(*iter), Evoral::Parameter(GainAutomation));
1424                 }
1425
1426                 if ((*iter)->name() == X_("controllable")) {
1427                         if ((prop = (*iter)->property("name")) != 0 && prop->value() == "gaincontrol") {
1428                                 _gain_control->set_state (**iter);
1429                         }
1430                 }
1431         }
1432
1433         if (ports_legal) {
1434
1435                 if (create_ports (node)) {
1436                         return -1;
1437                 }
1438
1439         } else {
1440
1441                 port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
1442         }
1443
1444         if( !_panner )
1445             _panner = new Panner( _name, _session );
1446         if (panners_legal) {
1447                 reset_panner ();
1448         } else {
1449                 panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal));
1450         }
1451
1452         if (connecting_legal) {
1453
1454                 if (make_connections (node)) {
1455                         return -1;
1456                 }
1457
1458         } else {
1459                 
1460                 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
1461         }
1462
1463         if (!ports_legal || !connecting_legal) {
1464                 pending_state_node = new XMLNode (node);
1465         }
1466
1467         return 0;
1468 }
1469
1470 int
1471 IO::load_automation (string path)
1472 {
1473         string fullpath;
1474         ifstream in;
1475         char line[128];
1476         uint32_t linecnt = 0;
1477         float version;
1478         LocaleGuard lg (X_("POSIX"));
1479
1480         fullpath = Glib::build_filename(_session.automation_dir(), path);
1481
1482         in.open (fullpath.c_str());
1483
1484         if (!in) {
1485                 fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
1486
1487                 in.open (fullpath.c_str());
1488
1489                 if (!in) {
1490                         error << string_compose(_("%1: cannot open automation event file \"%2\""), _name, fullpath) << endmsg;
1491                         return -1;
1492                 }
1493         }
1494
1495         clear_automation ();
1496
1497         while (in.getline (line, sizeof(line), '\n')) {
1498                 char type;
1499                 nframes_t when;
1500                 double value;
1501
1502                 if (++linecnt == 1) {
1503                         if (memcmp (line, "version", 7) == 0) {
1504                                 if (sscanf (line, "version %f", &version) != 1) {
1505                                         error << string_compose(_("badly formed version number in automation event file \"%1\""), path) << endmsg;
1506                                         return -1;
1507                                 }
1508                         } else {
1509                                 error << string_compose(_("no version information in automation event file \"%1\""), path) << endmsg;
1510                                 return -1;
1511                         }
1512
1513                         continue;
1514                 }
1515
1516                 if (sscanf (line, "%c %" PRIu32 " %lf", &type, &when, &value) != 3) {
1517                         warning << string_compose(_("badly formatted automation event record at line %1 of %2 (ignored)"), linecnt, path) << endmsg;
1518                         continue;
1519                 }
1520
1521                 switch (type) {
1522                 case 'g':
1523                         _gain_control->list()->fast_simple_add (when, value);
1524                         break;
1525
1526                 case 's':
1527                         break;
1528
1529                 case 'm':
1530                         break;
1531
1532                 case 'p':
1533                         /* older (pre-1.0) versions of ardour used this */
1534                         break;
1535
1536                 default:
1537                         warning << _("dubious automation event found (and ignored)") << endmsg;
1538                 }
1539         }
1540
1541         return 0;
1542 }
1543
1544 int
1545 IO::connecting_became_legal ()
1546 {
1547         int ret;
1548
1549         if (pending_state_node == 0) {
1550                 fatal << _("IO::connecting_became_legal() called without a pending state node") << endmsg;
1551                 /*NOTREACHED*/
1552                 return -1;
1553         }
1554
1555         connection_legal_c.disconnect ();
1556
1557         ret = make_connections (*pending_state_node);
1558
1559         if (ports_legal) {
1560                 delete pending_state_node;
1561                 pending_state_node = 0;
1562         }
1563
1564         return ret;
1565 }
1566 int
1567 IO::ports_became_legal ()
1568 {
1569         int ret;
1570
1571         if (pending_state_node == 0) {
1572                 fatal << _("IO::ports_became_legal() called without a pending state node") << endmsg;
1573                 /*NOTREACHED*/
1574                 return -1;
1575         }
1576
1577         port_legal_c.disconnect ();
1578
1579         ret = create_ports (*pending_state_node);
1580
1581         if (connecting_legal) {
1582                 delete pending_state_node;
1583                 pending_state_node = 0;
1584         }
1585
1586         return ret;
1587 }
1588
1589 boost::shared_ptr<Bundle>
1590 IO::find_possible_bundle (const string &desired_name, const string &default_name, const string &bundle_type_name) 
1591 {
1592         static const string digits = "0123456789";
1593
1594         boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
1595
1596         if (!c) {
1597                 int bundle_number, mask;
1598                 string possible_name;
1599                 bool stereo = false;
1600                 string::size_type last_non_digit_pos;
1601
1602                 error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
1603                       << endmsg;
1604
1605                 // find numeric suffix of desired name
1606                 bundle_number = 0;
1607                 
1608                 last_non_digit_pos = desired_name.find_last_not_of(digits);
1609
1610                 if (last_non_digit_pos != string::npos) {
1611                         stringstream s;
1612                         s << desired_name.substr(last_non_digit_pos);
1613                         s >> bundle_number;
1614                 }
1615         
1616                 // see if it's a stereo connection e.g. "in 3+4"
1617
1618                 if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
1619                         int left_bundle_number = 0;
1620                         string::size_type left_last_non_digit_pos;
1621
1622                         left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
1623
1624                         if (left_last_non_digit_pos != string::npos) {
1625                                 stringstream s;
1626                                 s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
1627                                 s >> left_bundle_number;
1628
1629                                 if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
1630                                         bundle_number--;
1631                                         stereo = true;
1632                                 }
1633                         }
1634                 }
1635
1636                 // make 0-based
1637                 if (bundle_number)
1638                         bundle_number--;
1639
1640                 // find highest set bit
1641                 mask = 1;
1642                 while ((mask <= bundle_number) && (mask <<= 1));
1643                 
1644                 // "wrap" bundle number into largest possible power of 2 
1645                 // that works...
1646
1647                 while (mask) {
1648
1649                         if (bundle_number & mask) {
1650                                 bundle_number &= ~mask;
1651                                 
1652                                 stringstream s;
1653                                 s << default_name << " " << bundle_number + 1;
1654
1655                                 if (stereo) {
1656                                         s << "+" << bundle_number + 2;
1657                                 }
1658                                 
1659                                 possible_name = s.str();
1660
1661                                 if ((c = _session.bundle_by_name (possible_name)) != 0) {
1662                                         break;
1663                                 }
1664                         }
1665                         mask >>= 1;
1666                 }
1667                 if (c) {
1668                         info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
1669                              << endmsg;
1670                 } else {
1671                         error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
1672                               << endmsg;
1673                 }
1674
1675         }
1676
1677         return c;
1678
1679 }
1680
1681 int
1682 IO::create_ports (const XMLNode& node)
1683 {
1684         XMLProperty const * prop;
1685         ChanCount num_inputs;
1686         ChanCount num_outputs;
1687
1688         if ((prop = node.property ("input-connection")) != 0) {
1689
1690                 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
1691                 
1692                 if (!c) {
1693                         return -1;
1694                 } 
1695
1696                 num_inputs = c->nchannels();
1697
1698         } else if ((prop = node.property ("inputs")) != 0) {
1699
1700                 num_inputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
1701         }
1702         
1703         if ((prop = node.property ("output-connection")) != 0) {
1704
1705                 boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
1706
1707                 if (!c) {
1708                         return -1;
1709                 } 
1710
1711                 num_outputs = c->nchannels ();
1712                 
1713         } else if ((prop = node.property ("outputs")) != 0) {
1714
1715                 num_outputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
1716         }
1717
1718         no_panner_reset = true;
1719
1720         if (ensure_io (num_inputs, num_outputs, true, this)) {
1721                 error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
1722                 return -1;
1723         }
1724
1725         no_panner_reset = false;
1726
1727         set_deferred_state ();
1728
1729         PortsCreated();
1730         return 0;
1731 }
1732
1733
1734 int
1735 IO::make_connections (const XMLNode& node)
1736 {
1737
1738         const XMLProperty* prop;
1739
1740         if ((prop = node.property ("input-connection")) != 0) {
1741                 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
1742                 
1743                 if (!c) {
1744                         return -1;
1745                 } 
1746
1747                 connect_input_ports_to_bundle (c, this);
1748
1749         } else if ((prop = node.property ("inputs")) != 0) {
1750                 if (set_inputs (prop->value())) {
1751                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
1752                         return -1;
1753                 }
1754         }
1755
1756         if ((prop = node.property ("output-connection")) != 0) {
1757                 boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
1758                 
1759                 if (!c) {
1760                         return -1;
1761                 } 
1762                 
1763                 connect_output_ports_to_bundle (c, this);
1764                 
1765         } else if ((prop = node.property ("outputs")) != 0) {
1766                 if (set_outputs (prop->value())) {
1767                         error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
1768                         return -1;
1769                 }
1770         }
1771
1772         for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) {
1773
1774                 if ((*i)->name() == "InputBundle") {
1775                         XMLProperty const * prop = (*i)->property ("name");
1776                         if (prop) {
1777                                 boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("in"), _("input"));
1778                                 if (b) {
1779                                         connect_input_ports_to_bundle (b, this);
1780                                 }
1781                         }
1782                         
1783                 } else if ((*i)->name() == "OutputBundle") {
1784                         XMLProperty const * prop = (*i)->property ("name");
1785                         if (prop) {
1786                                 boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("out"), _("output"));
1787                                 if (b) {
1788                                         connect_output_ports_to_bundle (b, this);
1789                                 } 
1790                         }
1791                 }
1792         }
1793         
1794         return 0;
1795 }
1796
1797 int
1798 IO::set_inputs (const string& str)
1799 {
1800         vector<string> ports;
1801         int i;
1802         int n;
1803         uint32_t nports;
1804         
1805         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1806                 return 0;
1807         }
1808
1809         // FIXME: audio-only
1810         if (ensure_inputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1811                 return -1;
1812         }
1813
1814         string::size_type start, end, ostart;
1815
1816         ostart = 0;
1817         start = 0;
1818         end = 0;
1819         i = 0;
1820
1821         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1822                 start += 1;
1823
1824                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1825                         error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
1826                         return -1;
1827                 }
1828
1829                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1830                         error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
1831
1832                         return -1;
1833                         
1834                 } else if (n > 0) {
1835
1836                         for (int x = 0; x < n; ++x) {
1837                                 connect_input (input (i), ports[x], this);
1838                         }
1839                 }
1840
1841                 ostart = end+1;
1842                 i++;
1843         }
1844
1845         return 0;
1846 }
1847
1848 int
1849 IO::set_outputs (const string& str)
1850 {
1851         vector<string> ports;
1852         int i;
1853         int n;
1854         uint32_t nports;
1855         
1856         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
1857                 return 0;
1858         }
1859
1860         // FIXME: audio-only
1861         if (ensure_outputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1862                 return -1;
1863         }
1864
1865         string::size_type start, end, ostart;
1866
1867         ostart = 0;
1868         start = 0;
1869         end = 0;
1870         i = 0;
1871
1872         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1873                 start += 1;
1874
1875                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1876                         error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg;
1877                         return -1;
1878                 }
1879
1880                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1881                         error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg;
1882
1883                         return -1;
1884                         
1885                 } else if (n > 0) {
1886
1887                         for (int x = 0; x < n; ++x) {
1888                                 connect_output (output (i), ports[x], this);
1889                         }
1890                 }
1891
1892                 ostart = end+1;
1893                 i++;
1894         }
1895
1896         return 0;
1897 }
1898
1899 int
1900 IO::parse_io_string (const string& str, vector<string>& ports)
1901 {
1902         string::size_type pos, opos;
1903
1904         if (str.length() == 0) {
1905                 return 0;
1906         }
1907
1908         pos = 0;
1909         opos = 0;
1910
1911         ports.clear ();
1912
1913         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1914                 ports.push_back (str.substr (opos, pos - opos));
1915                 opos = pos + 1;
1916         }
1917         
1918         if (opos < str.length()) {
1919                 ports.push_back (str.substr(opos));
1920         }
1921
1922         return ports.size();
1923 }
1924
1925 int
1926 IO::parse_gain_string (const string& str, vector<string>& ports)
1927 {
1928         string::size_type pos, opos;
1929
1930         pos = 0;
1931         opos = 0;
1932         ports.clear ();
1933
1934         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1935                 ports.push_back (str.substr (opos, pos - opos));
1936                 opos = pos + 1;
1937         }
1938         
1939         if (opos < str.length()) {
1940                 ports.push_back (str.substr(opos));
1941         }
1942
1943         return ports.size();
1944 }
1945
1946 bool
1947 IO::set_name (const string& requested_name)
1948 {
1949         if (requested_name == _name) {
1950                 return true;
1951         }
1952         
1953         string name;
1954         Route *rt;
1955         if ( (rt = dynamic_cast<Route *>(this))) {
1956                 name = Route::ensure_track_or_route_name(requested_name, _session);
1957         } else {
1958                 name = requested_name;
1959         }
1960
1961
1962         /* replace all colons in the name. i wish we didn't have to do this */
1963
1964         if (replace_all (name, ":", "-")) {
1965                 warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
1966         }
1967
1968         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
1969                 string current_name = i->short_name();
1970                 current_name.replace (current_name.find (_name), _name.length(), name);
1971                 i->set_name (current_name);
1972         }
1973
1974         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
1975                 string current_name = i->short_name();
1976                 current_name.replace (current_name.find (_name), _name.length(), name);
1977                 i->set_name (current_name);
1978         }
1979
1980         bool const r = SessionObject::set_name(name);
1981
1982         setup_bundles_for_inputs_and_outputs ();
1983
1984         return r;
1985 }
1986
1987 void
1988 IO::set_input_minimum (ChanCount n)
1989 {
1990         _input_minimum = n;
1991 }
1992
1993 void
1994 IO::set_input_maximum (ChanCount n)
1995 {
1996         _input_maximum = n;
1997 }
1998
1999 void
2000 IO::set_output_minimum (ChanCount n)
2001 {
2002         _output_minimum = n;
2003 }
2004
2005 void
2006 IO::set_output_maximum (ChanCount n)
2007 {
2008         _output_maximum = n;
2009 }
2010
2011 void
2012 IO::set_port_latency (nframes_t nframes)
2013 {
2014         Glib::Mutex::Lock lm (io_lock);
2015
2016         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2017                 i->set_latency (nframes);
2018         }
2019 }
2020
2021 nframes_t
2022 IO::output_latency () const
2023 {
2024         nframes_t max_latency;
2025         nframes_t latency;
2026
2027         max_latency = 0;
2028
2029         /* io lock not taken - must be protected by other means */
2030
2031         for (PortSet::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2032                 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
2033                         max_latency = latency;
2034                 }
2035         }
2036
2037         return max_latency;
2038 }
2039
2040 nframes_t
2041 IO::input_latency () const
2042 {
2043         nframes_t max_latency;
2044         nframes_t latency;
2045
2046         max_latency = 0;
2047
2048         /* io lock not taken - must be protected by other means */
2049
2050         for (PortSet::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2051                 if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) {
2052                         max_latency = latency;
2053                 } 
2054         }
2055
2056         return max_latency;
2057 }
2058
2059 int
2060 IO::connect_input_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
2061 {
2062         {
2063                 BLOCK_PROCESS_CALLBACK ();
2064                 Glib::Mutex::Lock lm2 (io_lock);
2065
2066                 /* Connect to the bundle, not worrying about any connections
2067                    that are already made. */
2068
2069                 ChanCount const channels = c->nchannels ();
2070                 uint32_t cnt = channels.get (default_type());
2071
2072                 for (uint32_t n = 0; n < cnt; ++n) {
2073                         const PortList& pl = c->channel_ports (n);
2074
2075                         for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2076
2077                           if (!_inputs.port(n)->connected_to (*i)) {
2078                                         
2079                                         if (_session.engine().connect (*i, _inputs.port(n)->name())) {
2080                                                 return -1;
2081                                         }
2082                                 }
2083                                 
2084                         }
2085                 }
2086
2087                 /* If this is a UserBundle, make a note of what we've done */
2088
2089                 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
2090                 if (ub) {
2091
2092                         /* See if we already know about this one */
2093                         std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin();
2094                         while (i != _bundles_connected_to_inputs.end() && i->bundle != ub) {
2095                                 ++i;
2096                         }
2097
2098                         if (i == _bundles_connected_to_inputs.end()) {
2099                                 /* We don't, so make a note */
2100                                 _bundles_connected_to_inputs.push_back (UserBundleInfo (this, ub));
2101                         }
2102                 }
2103         }
2104
2105         input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
2106         return 0;
2107 }
2108
2109 int
2110 IO::connect_output_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
2111 {
2112         {
2113                 BLOCK_PROCESS_CALLBACK ();
2114                 Glib::Mutex::Lock lm2 (io_lock);
2115
2116                 /* Connect to the bundle, not worrying about any connections
2117                    that are already made. */
2118
2119                 ChanCount const channels = c->nchannels ();
2120                 uint32_t cnt = channels.get (default_type());
2121
2122                 for (uint32_t n = 0; n < cnt; ++n) {
2123
2124                         const PortList& pl = c->channel_ports (n);
2125
2126                         for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
2127
2128                                 if (!_outputs.port(n)->connected_to (*i)) {
2129                                                 
2130                                         if (_session.engine().connect (_outputs.port(n)->name(), *i)) {
2131                                                 return -1;
2132                                         }
2133                                 }
2134                         }
2135                 }
2136
2137                 /* If this is a UserBundle, make a note of what we've done */
2138
2139                 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
2140                 if (ub) {
2141
2142                         /* See if we already know about this one */
2143                         std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin();
2144                         while (i != _bundles_connected_to_outputs.end() && i->bundle != ub) {
2145                                 ++i;
2146                         }
2147
2148                         if (i == _bundles_connected_to_outputs.end()) {
2149                                 /* We don't, so make a note */
2150                                 _bundles_connected_to_outputs.push_back (UserBundleInfo (this, ub));
2151                         }
2152                 }
2153         }
2154
2155         output_changed (IOChange (ConnectionsChanged|ConfigurationChanged), src); /* EMIT SIGNAL */
2156
2157         return 0;
2158 }
2159
2160 int
2161 IO::disable_connecting ()
2162 {
2163         connecting_legal = false;
2164         return 0;
2165 }
2166
2167 int
2168 IO::enable_connecting ()
2169 {
2170         connecting_legal = true;
2171         return ConnectingLegal ();
2172 }
2173
2174 int
2175 IO::disable_ports ()
2176 {
2177         ports_legal = false;
2178         return 0;
2179 }
2180
2181 int
2182 IO::enable_ports ()
2183 {
2184         ports_legal = true;
2185         return PortsLegal ();
2186 }
2187
2188 int
2189 IO::disable_panners (void)
2190 {
2191         panners_legal = false;
2192         return 0;
2193 }
2194
2195 int
2196 IO::reset_panners ()
2197 {
2198         panners_legal = true;
2199         return PannersLegal ();
2200 }
2201
2202 void
2203 IO::bundle_configuration_will_change ()
2204 {
2205         //XXX
2206 //      connect_input_ports_to_bundle (_input_bundle, this);
2207 }
2208
2209 void
2210 IO::bundle_configuration_has_changed ()
2211 {
2212         //XXX
2213 //      connect_input_ports_to_bundle (_input_bundle, this);
2214 }
2215
2216 void
2217 IO::bundle_ports_will_change (int ignored)
2218 {
2219 //XXX
2220 //      connect_output_ports_to_bundle (_output_bundle, this);
2221 }
2222
2223 void
2224 IO::bundle_ports_have_changed (int ignored)
2225 {
2226         //XXX
2227 //      connect_output_ports_to_bundle (_output_bundle, this);
2228 }
2229
2230 void
2231 IO::GainControl::set_value (float val)
2232 {
2233         // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2234         if (val > 1.99526231f)
2235                 val = 1.99526231f;
2236
2237         _io->set_gain (val, this);
2238         
2239         AutomationControl::set_value(val);
2240 }
2241
2242 float
2243 IO::GainControl::get_value (void) const
2244 {
2245         return AutomationControl::get_value();
2246 }
2247
2248 void
2249 IO::setup_peak_meters()
2250 {
2251         ChanCount max_streams = std::max (_inputs.count(), _outputs.count());
2252         _meter->configure_io (max_streams, max_streams);
2253 }
2254
2255 /**
2256     Update the peak meters.
2257
2258     The meter signal lock is taken to prevent modification of the 
2259     Meter signal while updating the meters, taking the meter signal
2260     lock prior to taking the io_lock ensures that all IO will remain 
2261     valid while metering.
2262 */   
2263 void
2264 IO::update_meters()
2265 {
2266         Glib::Mutex::Lock guard (m_meter_signal_lock);
2267         Meter(); /* EMIT SIGNAL */
2268 }
2269
2270 void
2271 IO::meter ()
2272 {
2273         // FIXME: Ugly.  Meter should manage the lock, if it's necessary
2274         
2275         Glib::Mutex::Lock lm (io_lock); // READER: meter thread.
2276         _meter->meter();
2277 }
2278
2279 void
2280 IO::clear_automation ()
2281 {
2282         data().clear (); // clears gain automation
2283         _panner->data().clear();
2284 }
2285
2286 void
2287 IO::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
2288 {
2289         // XXX: would be nice to get rid of this special hack
2290
2291         if (param.type() == GainAutomation) {
2292
2293                 bool changed = false;
2294
2295                 { 
2296                         Glib::Mutex::Lock lm (control_lock());
2297
2298                         boost::shared_ptr<AutomationList> gain_auto
2299                                 = boost::dynamic_pointer_cast<AutomationList>(_gain_control->list());
2300
2301                         if (state != gain_auto->automation_state()) {
2302                                 changed = true;
2303                                 _last_automation_snapshot = 0;
2304                                 gain_auto->set_automation_state (state);
2305
2306                                 if (state != Off) {
2307                                         // FIXME: shouldn't this use Curve?
2308                                         set_gain (gain_auto->eval (_session.transport_frame()), this);
2309                                 }
2310                         }
2311                 }
2312
2313                 if (changed) {
2314                         _session.set_dirty ();
2315                 }
2316
2317         } else {
2318                 AutomatableControls::set_parameter_automation_state(param, state);
2319         }
2320 }
2321
2322 void
2323 IO::inc_gain (gain_t factor, void *src)
2324 {
2325         if (_desired_gain == 0.0f)
2326                 set_gain (0.000001f + (0.000001f * factor), src);
2327         else
2328                 set_gain (_desired_gain + (_desired_gain * factor), src);
2329 }
2330
2331 void
2332 IO::set_gain (gain_t val, void *src)
2333 {
2334         // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
2335         if (val > 1.99526231f)
2336                 val = 1.99526231f;
2337
2338         if (src != _gain_control.get()) {
2339                 _gain_control->set_value(val);
2340                 // bit twisty, this will come back and call us again
2341                 // (this keeps control in sync with reality)
2342                 return;
2343         }
2344
2345         {
2346                 Glib::Mutex::Lock dm (declick_lock);
2347                 _desired_gain = val;
2348         }
2349
2350         if (_session.transport_stopped()) {
2351                 _gain = val;
2352         }
2353         
2354         /*
2355         if (_session.transport_stopped() && src != 0 && src != this && _gain_control->automation_write()) {
2356                 _gain_control->list()->add (_session.transport_frame(), val);
2357                 
2358         }
2359         */
2360
2361         _session.set_dirty();
2362 }
2363
2364 void
2365 IO::start_pan_touch (uint32_t which)
2366 {
2367         if (which < _panner->npanners()) {
2368                 (*_panner).pan_control(which)->start_touch();
2369         }
2370 }
2371
2372 void
2373 IO::end_pan_touch (uint32_t which)
2374 {
2375         if (which < _panner->npanners()) {
2376                 (*_panner).pan_control(which)->stop_touch();
2377         }
2378
2379 }
2380
2381 void
2382 IO::automation_snapshot (nframes_t now, bool force)
2383 {
2384         AutomatableControls::automation_snapshot (now, force);
2385         // XXX: This seems to be wrong. 
2386         // drobilla: shouldnt automation_snapshot for panner be called
2387         //           "automagically" because its an Automatable now ?
2388         //
2389         //           we could dump this whole method then. <3
2390
2391         if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
2392                 _panner->automation_snapshot (now, force);
2393         }
2394         
2395         _panner->automation_snapshot (now, force);
2396         _last_automation_snapshot = now;
2397 }
2398
2399 void
2400 IO::transport_stopped (nframes_t frame)
2401 {
2402         _gain_control->list()->reposition_for_rt_add (frame);
2403
2404         if (_gain_control->automation_state() != Off) {
2405                 
2406                 /* the src=0 condition is a special signal to not propagate 
2407                    automation gain changes into the mix group when locating.
2408                 */
2409
2410                 // FIXME: shouldn't this use Curve?
2411                 set_gain (_gain_control->list()->eval (frame), 0);
2412         }
2413
2414         _panner->transport_stopped (frame);
2415 }
2416
2417 string
2418 IO::build_legal_port_name (DataType type, bool in)
2419 {
2420         const int name_size = jack_port_name_size();
2421         int limit;
2422         string suffix;
2423         int maxports;
2424
2425         if (type == DataType::AUDIO) {
2426                 suffix = _("audio");
2427         } else if (type == DataType::MIDI) {
2428                 suffix = _("midi");
2429         } else {
2430                 throw unknown_type();
2431         }
2432         
2433         if (in) {
2434                 suffix += _("_in");
2435                 maxports = _input_maximum.get(type);
2436         } else {
2437                 suffix += _("_out");
2438                 maxports = _output_maximum.get(type);
2439         }
2440         
2441         if (maxports == 1) {
2442                 // allow space for the slash + the suffix
2443                 limit = name_size - _session.engine().client_name().length() - (suffix.length() + 1);
2444                 char buf[name_size+1];
2445                 snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
2446                 return string (buf);
2447         } 
2448         
2449         // allow up to 4 digits for the output port number, plus the slash, suffix and extra space
2450
2451         limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
2452
2453         char buf1[name_size+1];
2454         char buf2[name_size+1];
2455         
2456         snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
2457         
2458         int port_number;
2459         
2460         if (in) {
2461                 port_number = find_input_port_hole (buf1);
2462         } else {
2463                 port_number = find_output_port_hole (buf1);
2464         }
2465         
2466         snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
2467         
2468         return string (buf2);
2469 }
2470
2471 int32_t
2472 IO::find_input_port_hole (const char* base)
2473 {
2474         /* CALLER MUST HOLD IO LOCK */
2475
2476         uint32_t n;
2477
2478         if (_inputs.empty()) {
2479                 return 1;
2480         }
2481
2482         /* we only allow up to 4 characters for the port number
2483          */
2484
2485         for (n = 1; n < 9999; ++n) {
2486                 char buf[jack_port_name_size()];
2487                 PortSet::iterator i = _inputs.begin();
2488
2489                 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2490
2491                 for ( ; i != _inputs.end(); ++i) {
2492                         if (i->short_name() == buf) {
2493                                 break;
2494                         }
2495                 }
2496
2497                 if (i == _inputs.end()) {
2498                         break;
2499                 }
2500         }
2501         return n;
2502 }
2503
2504 int32_t
2505 IO::find_output_port_hole (const char* base)
2506 {
2507         /* CALLER MUST HOLD IO LOCK */
2508
2509         uint32_t n;
2510
2511         if (_outputs.empty()) {
2512                 return 1;
2513         }
2514
2515         /* we only allow up to 4 characters for the port number
2516          */
2517
2518         for (n = 1; n < 9999; ++n) {
2519                 char buf[jack_port_name_size()];
2520                 PortSet::iterator i = _outputs.begin();
2521
2522                 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
2523
2524                 for ( ; i != _outputs.end(); ++i) {
2525                         if (i->short_name() == buf) {
2526                                 break;
2527                         }
2528                 }
2529
2530                 if (i == _outputs.end()) {
2531                         break;
2532                 }
2533         }
2534         
2535         return n;
2536 }
2537
2538 void
2539 IO::set_active (bool yn)
2540 {
2541         _active = yn; 
2542          active_changed(); /* EMIT SIGNAL */
2543 }
2544
2545
2546 AudioPort*
2547 IO::audio_input(uint32_t n) const
2548 {
2549         return dynamic_cast<AudioPort*>(input(n));
2550 }
2551
2552 AudioPort*
2553 IO::audio_output(uint32_t n) const
2554 {
2555         return dynamic_cast<AudioPort*>(output(n));
2556 }
2557
2558 MidiPort*
2559 IO::midi_input(uint32_t n) const
2560 {
2561         return dynamic_cast<MidiPort*>(input(n));
2562 }
2563
2564 MidiPort*
2565 IO::midi_output(uint32_t n) const
2566 {
2567         return dynamic_cast<MidiPort*>(output(n));
2568 }
2569
2570 void
2571 IO::set_phase_invert (bool yn, void *src)
2572 {
2573         if (_phase_invert != yn) {
2574                 _phase_invert = yn;
2575                 //  phase_invert_changed (src); /* EMIT SIGNAL */
2576         }
2577 }
2578
2579 void
2580 IO::set_denormal_protection (bool yn, void *src)
2581 {
2582         if (_denormal_protection != yn) {
2583                 _denormal_protection = yn;
2584                 //  denormal_protection_changed (src); /* EMIT SIGNAL */
2585         }
2586 }
2587
2588 void
2589 IO::update_port_total_latencies ()
2590 {
2591         /* io_lock, not taken: function must be called from Session::process() calltree */
2592
2593         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2594                 _session.engine().update_total_latency (*i);
2595         }
2596
2597         for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
2598                 _session.engine().update_total_latency (*i);
2599         }
2600 }
2601
2602
2603 /**
2604  *  Setup bundles that describe our inputs and outputs.
2605  */
2606
2607 void
2608 IO::setup_bundles_for_inputs_and_outputs ()
2609 {
2610         char buf[32];
2611
2612         snprintf(buf, sizeof (buf), _("%s in"), _name.c_str());
2613         _bundle_for_inputs->set_name (buf);
2614         uint32_t const ni = inputs().num_ports();
2615         _bundle_for_inputs->set_channels (ni);
2616         for (uint32_t i = 0; i < ni; ++i) {
2617                 _bundle_for_inputs->set_port (i, inputs().port(i)->name());
2618         }
2619
2620         snprintf(buf, sizeof (buf), _("%s out"), _name.c_str());
2621         _bundle_for_outputs->set_name (buf);
2622         uint32_t const no = outputs().num_ports();
2623         _bundle_for_outputs->set_channels (no);
2624         for (uint32_t i = 0; i < no; ++i) {
2625                 _bundle_for_outputs->set_port (i, outputs().port(i)->name());
2626         }
2627 }
2628
2629
2630 /**
2631  *  Create and setup bundles that describe our inputs and outputs.
2632  */
2633
2634 void
2635 IO::create_bundles_for_inputs_and_outputs ()
2636 {
2637         _bundle_for_inputs = boost::shared_ptr<AutoBundle> (new AutoBundle (true));
2638         _bundle_for_outputs = boost::shared_ptr<AutoBundle> (new AutoBundle (false));
2639         setup_bundles_for_inputs_and_outputs ();
2640 }
2641
2642 /** Add a bundle to a list if is connected to our inputs.
2643  *  @param b Bundle to check.
2644  *  @param bundles List to add to.
2645  */
2646 void
2647 IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
2648 {
2649         boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
2650
2651         if (ab == 0 || ab->ports_are_outputs() == false) {
2652                 return;
2653         }
2654         
2655         if (ab->nchannels().get (default_type()) != n_inputs().n_total ()) {
2656                 return;
2657         }
2658
2659         for (uint32_t i = 0; i < n_inputs().n_total (); ++i) {
2660
2661                 PortList const & pl = b->channel_ports (i);
2662
2663                 if (pl.empty()) {
2664                         return;
2665                 }
2666
2667                 if (!input(i)->connected_to (pl[0])) {
2668                         return;
2669                 }
2670         }
2671
2672         bundles->push_back (b);
2673 }
2674
2675 /** @return Bundles connected to our inputs */
2676 std::vector<boost::shared_ptr<Bundle> >
2677 IO::bundles_connected_to_inputs ()
2678 {
2679         std::vector<boost::shared_ptr<Bundle> > bundles;
2680         
2681         /* User bundles */
2682         for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); i != _bundles_connected_to_inputs.end(); ++i) {
2683                 bundles.push_back (i->bundle);
2684         }
2685
2686         /* Auto bundles */
2687         _session.foreach_bundle (
2688                 sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_input_bundle_to_list), &bundles)
2689                 );
2690
2691         return bundles;
2692 }
2693
2694
2695 /** Add a bundle to a list if is connected to our outputs.
2696  *  @param b Bundle to check.
2697  *  @param bundles List to add to.
2698  */
2699 void
2700 IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
2701 {
2702         boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
2703         if (ab == 0 || ab->ports_are_inputs() == false) {
2704                 return;
2705         }
2706
2707         if (ab->nchannels ().get (default_type()) != n_outputs().n_total ()) {
2708                 return;
2709         }
2710
2711         for (uint32_t i = 0; i < n_outputs().n_total (); ++i) {
2712
2713                 PortList const & pl = b->channel_ports (i);
2714
2715                 if (pl.empty()) {
2716                         return;
2717                 }
2718
2719                 if (!output(i)->connected_to (pl[0])) {
2720                         return;
2721                 }
2722         }
2723
2724         bundles->push_back (b);
2725 }
2726
2727
2728 /* @return Bundles connected to our outputs */
2729 std::vector<boost::shared_ptr<Bundle> >
2730 IO::bundles_connected_to_outputs ()
2731 {
2732         std::vector<boost::shared_ptr<Bundle> > bundles;
2733
2734         /* User bundles */
2735         for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); i != _bundles_connected_to_outputs.end(); ++i) {
2736                 bundles.push_back (i->bundle);
2737         }
2738
2739         /* Auto bundles */
2740         _session.foreach_bundle (
2741                 sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_output_bundle_to_list), &bundles)
2742                 );
2743
2744         return bundles; 
2745 }
2746
2747
2748 IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
2749 {
2750         bundle = b;
2751         configuration_will_change = b->ConfigurationWillChange.connect (
2752                 sigc::mem_fun (*io, &IO::bundle_configuration_will_change)
2753                 );
2754         configuration_has_changed = b->ConfigurationHasChanged.connect (
2755                 sigc::mem_fun (*io, &IO::bundle_configuration_has_changed)
2756                 );
2757         ports_will_change = b->PortsWillChange.connect (
2758                 sigc::mem_fun (*io, &IO::bundle_ports_will_change)
2759                 );
2760         ports_have_changed = b->PortsHaveChanged.connect (
2761                 sigc::mem_fun (*io, &IO::bundle_ports_have_changed)
2762                 );
2763 }
2764
2765 void
2766 IO::prepare_inputs (nframes_t nframes, nframes_t offset)
2767 {
2768         /* io_lock, not taken: function must be called from Session::process() calltree */
2769
2770         for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
2771                 (*i).cycle_start (nframes, offset);
2772         }
2773 }