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