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