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