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