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