7c92ab87cdf829b52cd1548f29afbf8220d373c3
[ardour.git] / libs / ardour / io.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <fstream>
20 #include <algorithm>
21 #include <unistd.h>
22 #include <locale.h>
23 #include <errno.h>
24
25 #include <sigc++/bind.h>
26
27 #include <glibmm.h>
28 #include <glibmm/thread.h>
29
30 #include "pbd/xml++.h"
31 #include "pbd/replace_all.h"
32 #include "pbd/unknown_type.h"
33 #include "pbd/enumwriter.h"
34
35 #include "ardour/audioengine.h"
36 #include "ardour/buffer.h"
37 #include "ardour/io.h"
38 #include "ardour/route.h"
39 #include "ardour/port.h"
40 #include "ardour/audio_port.h"
41 #include "ardour/midi_port.h"
42 #include "ardour/session.h"
43 #include "ardour/cycle_timer.h"
44 #include "ardour/buffer_set.h"
45 #include "ardour/meter.h"
46 #include "ardour/amp.h"
47 #include "ardour/user_bundle.h"
48
49 #include "i18n.h"
50
51 #include <cmath>
52
53 /*
54   A bug in OS X's cmath that causes isnan() and isinf() to be
55   "undeclared". the following works around that
56 */
57
58 #if defined(__APPLE__) && defined(__MACH__)
59 extern "C" int isnan (double);
60 extern "C" int isinf (double);
61 #endif
62
63 #define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock())
64
65 using namespace std;
66 using namespace ARDOUR;
67 using namespace PBD;
68
69 const string                 IO::state_node_name = "IO";
70 bool                         IO::connecting_legal = false;
71 sigc::signal<int>            IO::ConnectingLegal;
72 sigc::signal<void,ChanCount> IO::PortCountChanged;
73
74 /** @param default_type The type of port that will be created by ensure_io
75  * and friends if no type is explicitly requested (to avoid breakage).
76  */
77 IO::IO (Session& s, const string& name, Direction dir, DataType default_type)
78         : SessionObject (s, name)
79         , _direction (dir)
80         , _default_type (default_type)
81 {
82         _active = true;
83         pending_state_node = 0;
84         setup_bundles ();
85 }
86
87 IO::IO (Session& s, const XMLNode& node, DataType dt)
88         : SessionObject(s, "unnamed io")
89         , _direction (Input)
90         , _default_type (dt)
91 {
92         _active = true;
93         pending_state_node = 0;
94
95         set_state (node, Stateful::loading_state_version);
96         setup_bundles ();
97 }
98
99 IO::~IO ()
100 {
101         Glib::Mutex::Lock lm (io_lock);
102
103         BLOCK_PROCESS_CALLBACK ();
104
105         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
106                 _session.engine().unregister_port (*i);
107         }
108 }
109
110 void
111 IO::silence (nframes_t nframes)
112 {
113         /* io_lock, not taken: function must be called from Session::process() calltree */
114
115         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
116                 i->get_buffer(nframes).silence (nframes);
117         }
118 }
119
120 void
121 IO::check_bundles_connected ()
122 {
123         check_bundles (_bundles_connected, ports());
124 }
125
126 void
127 IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
128 {
129         std::vector<UserBundleInfo> new_list;
130
131         for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) {
132
133                 uint32_t const N = i->bundle->nchannels ();
134
135                 if (_ports.num_ports (default_type()) < N) {
136                         continue;
137                 }
138
139                 bool ok = true;
140
141                 for (uint32_t j = 0; j < N; ++j) {
142                         /* Every port on bundle channel j must be connected to our input j */
143                         Bundle::PortList const pl = i->bundle->channel_ports (j);
144                         for (uint32_t k = 0; k < pl.size(); ++k) {
145                                 if (ports.port(j)->connected_to (pl[k]) == false) {
146                                         ok = false;
147                                         break;
148                                 }
149                         }
150
151                         if (ok == false) {
152                                 break;
153                         }
154                 }
155
156                 if (ok) {
157                         new_list.push_back (*i);
158                 } else {
159                         i->changed.disconnect ();
160                 }
161         }
162
163         list = new_list;
164 }
165
166
167 int
168 IO::disconnect (Port* our_port, string other_port, void* src)
169 {
170         if (other_port.length() == 0 || our_port == 0) {
171                 return 0;
172         }
173
174         {
175                 BLOCK_PROCESS_CALLBACK ();
176
177                 {
178                         Glib::Mutex::Lock lm (io_lock);
179
180                         /* check that our_port is really one of ours */
181
182                         if ( ! _ports.contains(our_port)) {
183                                 return -1;
184                         }
185
186                         /* disconnect it from the source */
187
188                         if (our_port->disconnect (other_port)) {
189                                 error << string_compose(_("IO: cannot disconnect port %1 from %2"), our_port->name(), other_port) << endmsg;
190                                 return -1;
191                         }
192
193                         check_bundles_connected ();
194                 }
195         }
196
197         changed (ConnectionsChanged, src); /* EMIT SIGNAL */
198         _session.set_dirty ();
199
200         return 0;
201 }
202
203 int
204 IO::connect (Port* our_port, string other_port, void* src)
205 {
206         if (other_port.length() == 0 || our_port == 0) {
207                 return 0;
208         }
209
210         {
211                 BLOCK_PROCESS_CALLBACK ();
212
213                 {
214                         Glib::Mutex::Lock lm (io_lock);
215
216                         /* check that our_port is really one of ours */
217
218                         if ( ! _ports.contains(our_port) ) {
219                                 return -1;
220                         }
221
222                         /* connect it to the source */
223
224                         if (our_port->connect (other_port)) {
225                                 return -1;
226                         }
227                 }
228         }
229
230         changed (ConnectionsChanged, src); /* EMIT SIGNAL */
231         _session.set_dirty ();
232         return 0;
233 }
234
235 int
236 IO::remove_port (Port* port, void* src)
237 {
238         IOChange change (NoChange);
239
240         {
241                 BLOCK_PROCESS_CALLBACK ();
242
243
244                 {
245                         Glib::Mutex::Lock lm (io_lock);
246
247                         if (_ports.remove(port)) {
248                                 change = IOChange (change|ConfigurationChanged);
249
250                                 if (port->connected()) {
251                                         change = IOChange (change|ConnectionsChanged);
252                                 }
253
254                                 _session.engine().unregister_port (*port);
255                                 check_bundles_connected ();
256                         }
257                 }
258
259                 PortCountChanged (n_ports()); /* EMIT SIGNAL */
260         }
261
262         if (change & ConfigurationChanged) {
263                 setup_bundles ();
264         }
265
266         if (change != NoChange) {
267                 changed (change, src);
268                 _session.set_dirty ();
269                 return 0;
270         }
271
272         return -1;
273 }
274
275 /** Add an output port.
276  *
277  * @param destination Name of input port to connect new port to.
278  * @param src Source for emitted ConfigurationChanged signal.
279  * @param type Data type of port.  Default value (NIL) will use this IO's default type.
280  */
281 int
282 IO::add_port (string destination, void* src, DataType type)
283 {
284         Port* our_port;
285
286         if (type == DataType::NIL) {
287                 type = _default_type;
288         }
289
290         {
291                 BLOCK_PROCESS_CALLBACK ();
292
293
294                 {
295                         Glib::Mutex::Lock lm (io_lock);
296
297                         /* Create a new output port */
298
299                         string portname = build_legal_port_name (type);
300
301                         if (_direction == Input) {
302                                 if ((our_port = _session.engine().register_input_port (type, portname)) == 0) {
303                                         error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
304                                         return -1;
305                                 }
306                         } else {
307                                 if ((our_port = _session.engine().register_output_port (type, portname)) == 0) {
308                                         error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
309                                         return -1;
310                                 }
311                         }
312
313                         _ports.add (our_port);
314                 }
315
316                 PortCountChanged (n_ports()); /* EMIT SIGNAL */
317         }
318
319         if (destination.length()) {
320                 if (our_port->connect (destination)) {
321                         return -1;
322                 }
323         }
324
325         // pan_changed (src); /* EMIT SIGNAL */
326         changed (ConfigurationChanged, src); /* EMIT SIGNAL */
327         setup_bundles ();
328         _session.set_dirty ();
329
330         return 0;
331 }
332
333 int
334 IO::disconnect (void* src)
335 {
336         {
337                 BLOCK_PROCESS_CALLBACK ();
338
339                 {
340                         Glib::Mutex::Lock lm (io_lock);
341
342                         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
343                                 i->disconnect_all ();
344                         }
345
346                         check_bundles_connected ();
347                 }
348         }
349
350         changed (ConnectionsChanged, src); /* EMIT SIGNAL */
351
352         return 0;
353 }
354
355 bool
356 IO::ensure_ports_locked (ChanCount count, bool clear, void* /*src*/)
357 {
358         Port* port = 0;
359         bool  changed    = false;
360
361         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
362
363                 const size_t n = count.get(*t);
364
365                 /* remove unused ports */
366                 for (size_t i = n_ports().get(*t); i > n; --i) {
367                         port = _ports.port(*t, i-1);
368
369                         assert(port);
370                         _ports.remove(port);
371                         _session.engine().unregister_port (*port);
372
373                         changed = true;
374                 }
375
376                 /* create any necessary new ports */
377                 while (n_ports().get(*t) < n) {
378
379                         string portname = build_legal_port_name (*t);
380
381                         try {
382
383                                 if (_direction == Input) {
384                                         if ((port = _session.engine().register_input_port (*t, portname)) == 0) {
385                                                 error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
386                                                 return -1;
387                                         }
388                                 } else {
389                                         if ((port = _session.engine().register_output_port (*t, portname)) == 0) {
390                                                 error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
391                                                 return -1;
392                                         }
393                                 }
394                         }
395
396                         catch (AudioEngine::PortRegistrationFailure& err) {
397                                 /* pass it on */
398                                 throw AudioEngine::PortRegistrationFailure();
399                         }
400
401                         _ports.add (port);
402                         changed = true;
403                 }
404         }
405
406         if (changed) {
407                 check_bundles_connected ();
408                 PortCountChanged (n_ports()); /* EMIT SIGNAL */
409                 _session.set_dirty ();
410         }
411
412         if (clear) {
413                 /* disconnect all existing ports so that we get a fresh start */
414                 for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
415                         i->disconnect_all ();
416                 }
417         }
418
419         return changed;
420 }
421
422
423 int
424 IO::ensure_ports (ChanCount count, bool clear, bool lockit, void* src)
425 {
426         bool changed = false;
427
428         if (count == n_ports() && !clear) {
429                 return 0;
430         }
431
432         if (lockit) {
433                 BLOCK_PROCESS_CALLBACK ();
434                 Glib::Mutex::Lock im (io_lock);
435                 changed = ensure_ports_locked (count, clear, src);
436         } else {
437                 changed = ensure_ports_locked (count, clear, src);
438         }
439
440         if (changed) {
441                 this->changed (ConfigurationChanged, src); /* EMIT SIGNAL */
442                 setup_bundles ();
443                 _session.set_dirty ();
444         }
445
446         return 0;
447 }
448
449 int
450 IO::ensure_io (ChanCount count, bool clear, void* src)
451 {
452         return ensure_ports (count, clear, true, src);
453 }
454
455 XMLNode&
456 IO::get_state (void)
457 {
458         return state (true);
459 }
460
461 XMLNode&
462 IO::state (bool /*full_state*/)
463 {
464         XMLNode* node = new XMLNode (state_node_name);
465         char buf[64];
466         string str;
467         vector<string>::iterator ci;
468         int n;
469         LocaleGuard lg (X_("POSIX"));
470         Glib::Mutex::Lock lm (io_lock);
471
472         node->add_property("name", _name);
473         id().print (buf, sizeof (buf));
474         node->add_property("id", buf);
475         node->add_property ("direction", enum_2_string (_direction));
476         node->add_property ("default-type", _default_type.to_string());
477
478         for (std::vector<UserBundleInfo>::iterator i = _bundles_connected.begin(); i != _bundles_connected.end(); ++i) {
479                 XMLNode* n = new XMLNode ("Bundle");
480                 n->add_property ("name", i->bundle->name ());
481                 node->add_child_nocopy (*n);
482         }
483
484         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
485
486                 vector<string> connections;
487
488                 XMLNode* pnode = new XMLNode (X_("Port"));
489                 pnode->add_property (X_("type"), i->type().to_string());
490                 pnode->add_property (X_("name"), i->name());
491
492                 if (i->get_connections (connections)) {
493
494                         for (n = 0, ci = connections.begin(); ci != connections.end(); ++ci, ++n) {
495
496                                 /* if its a connection to our own port,
497                                    return only the port name, not the
498                                    whole thing. this allows connections
499                                    to be re-established even when our
500                                    client name is different.
501                                 */
502
503                                 XMLNode* cnode = new XMLNode (X_("Connection"));
504
505                                 cnode->add_property (X_("other"), _session.engine().make_port_name_relative (*ci));
506                                 pnode->add_child_nocopy (*cnode);
507                         }
508                 }
509
510                 node->add_child_nocopy (*pnode);
511         }
512
513         return *node;
514 }
515
516 int
517 IO::set_state (const XMLNode& node, int version)
518 {
519         /* callers for version < 3000 need to call set_state_2X directly, as A3 IOs
520          * are input OR output, not both, so the direction needs to be specified
521          * by the caller.
522          */
523         assert (version >= 3000);
524
525         const XMLProperty* prop;
526         XMLNodeConstIterator iter;
527         LocaleGuard lg (X_("POSIX"));
528
529         /* force use of non-localized representation of decimal point,
530            since we use it a lot in XML files and so forth.
531         */
532
533         if (node.name() != state_node_name) {
534                 error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg;
535                 return -1;
536         }
537
538         if ((prop = node.property ("name")) != 0) {
539                 set_name (prop->value());
540         }
541
542         if ((prop = node.property (X_("default-type"))) != 0) {
543                 _default_type = DataType(prop->value());
544                 assert(_default_type != DataType::NIL);
545         }
546
547         if ((prop = node.property ("id")) != 0) {
548                 _id = prop->value ();
549         }
550
551         if ((prop = node.property ("direction")) != 0) {
552                 _direction = (Direction) string_2_enum (prop->value(), _direction);
553         }
554
555         if (create_ports (node, version)) {
556                 return -1;
557         }
558
559         if (connecting_legal) {
560
561                 if (make_connections (node, version, false)) {
562                         return -1;
563                 }
564
565         } else {
566
567                 pending_state_node = new XMLNode (node);
568                 pending_state_node_version = version;
569                 pending_state_node_in = false;
570                 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
571         }
572
573
574         return 0;
575 }
576
577 int
578 IO::set_state_2X (const XMLNode& node, int version, bool in)
579 {
580         const XMLProperty* prop;
581         XMLNodeConstIterator iter;
582         LocaleGuard lg (X_("POSIX"));
583
584         /* force use of non-localized representation of decimal point,
585            since we use it a lot in XML files and so forth.
586         */
587
588         if (node.name() != state_node_name) {
589                 error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg;
590                 return -1;
591         }
592
593         if ((prop = node.property ("name")) != 0) {
594                 set_name (prop->value());
595         }
596
597         if ((prop = node.property (X_("default-type"))) != 0) {
598                 _default_type = DataType(prop->value());
599                 assert(_default_type != DataType::NIL);
600         }
601
602         if ((prop = node.property ("id")) != 0) {
603                 _id = prop->value ();
604         }
605
606         _direction = in ? Input : Output;
607
608         if (create_ports (node, version)) {
609                 return -1;
610         }
611
612         if (connecting_legal) {
613
614                 if (make_connections_2X (node, version, in)) {
615                         return -1;
616                 }
617
618         } else {
619
620                 pending_state_node = new XMLNode (node);
621                 pending_state_node_version = version;
622                 pending_state_node_in = in;
623                 connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal));
624         }
625
626         return 0;
627 }
628
629 int
630 IO::connecting_became_legal ()
631 {
632         int ret;
633
634         assert (pending_state_node);
635
636         connection_legal_c.disconnect ();
637
638         ret = make_connections (*pending_state_node, pending_state_node_version, pending_state_node_in);
639
640         delete pending_state_node;
641         pending_state_node = 0;
642
643         return ret;
644 }
645
646 boost::shared_ptr<Bundle>
647 IO::find_possible_bundle (const string &desired_name)
648 {
649         static const string digits = "0123456789";
650         const string &default_name = (_direction == Input ? _("in") : _("out"));
651         const string &bundle_type_name = (_direction == Input ? _("input") : _("output"));
652
653         boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
654
655         if (!c) {
656                 int bundle_number, mask;
657                 string possible_name;
658                 bool stereo = false;
659                 string::size_type last_non_digit_pos;
660
661                 error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
662                       << endmsg;
663
664                 // find numeric suffix of desired name
665                 bundle_number = 0;
666
667                 last_non_digit_pos = desired_name.find_last_not_of(digits);
668
669                 if (last_non_digit_pos != string::npos) {
670                         stringstream s;
671                         s << desired_name.substr(last_non_digit_pos);
672                         s >> bundle_number;
673                 }
674
675                 // see if it's a stereo connection e.g. "in 3+4"
676
677                 if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
678                         int left_bundle_number = 0;
679                         string::size_type left_last_non_digit_pos;
680
681                         left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
682
683                         if (left_last_non_digit_pos != string::npos) {
684                                 stringstream s;
685                                 s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
686                                 s >> left_bundle_number;
687
688                                 if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
689                                         bundle_number--;
690                                         stereo = true;
691                                 }
692                         }
693                 }
694
695                 // make 0-based
696                 if (bundle_number)
697                         bundle_number--;
698
699                 // find highest set bit
700                 mask = 1;
701                 while ((mask <= bundle_number) && (mask <<= 1)) {}
702
703                 // "wrap" bundle number into largest possible power of 2
704                 // that works...
705
706                 while (mask) {
707
708                         if (bundle_number & mask) {
709                                 bundle_number &= ~mask;
710
711                                 stringstream s;
712                                 s << default_name << " " << bundle_number + 1;
713
714                                 if (stereo) {
715                                         s << "+" << bundle_number + 2;
716                                 }
717
718                                 possible_name = s.str();
719
720                                 if ((c = _session.bundle_by_name (possible_name)) != 0) {
721                                         break;
722                                 }
723                         }
724                         mask >>= 1;
725                 }
726                 if (c) {
727                         info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
728                              << endmsg;
729                 } else {
730                         error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
731                               << endmsg;
732                 }
733
734         }
735
736         return c;
737
738 }
739
740 int
741 IO::get_port_counts_2X (XMLNode const & node, int /*version*/, ChanCount& n, boost::shared_ptr<Bundle>& /*c*/)
742 {
743         XMLProperty const * prop;
744         XMLNodeList children = node.children ();
745
746         uint32_t n_audio = 0;
747
748         for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
749
750                 if ((prop = node.property ("inputs")) != 0 && _direction == Input) {
751                         n_audio = count (prop->value().begin(), prop->value().end(), '{');
752                 } else if ((prop = node.property ("outputs")) != 0 && _direction == Output) {
753                         n_audio = count (prop->value().begin(), prop->value().end(), '{');
754                 }
755         }
756
757         ChanCount cnt;
758         cnt.set_audio (n_audio);
759         n = ChanCount::max (n, cnt);
760
761         return 0;
762 }
763
764 int
765 IO::get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c)
766 {
767         if (version < 3000) {
768                 return get_port_counts_2X (node, version, n, c);
769         }
770
771         XMLProperty const * prop;
772         XMLNodeConstIterator iter;
773         uint32_t n_audio = 0;
774         uint32_t n_midi = 0;
775         ChanCount cnt;
776
777         n = n_ports();
778
779         if ((prop = node.property ("connection")) != 0) {
780
781                 if ((c = find_possible_bundle (prop->value())) != 0) {
782                         n = ChanCount::max (n, ChanCount(c->type(), c->nchannels()));
783                 }
784                 return 0;
785         }
786
787         for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
788
789                 if ((*iter)->name() == X_("Bundle")) {
790                         if ((c = find_possible_bundle (prop->value())) != 0) {
791                                 n = ChanCount::max (n, ChanCount(c->type(), c->nchannels()));
792                                 return 0;
793                         } else {
794                                 return -1;
795                         }
796                 }
797
798                 if ((*iter)->name() == X_("Port")) {
799                         prop = (*iter)->property (X_("type"));
800
801                         if (!prop) {
802                                 continue;
803                         }
804
805                         if (prop->value() == X_("audio")) {
806                                 cnt.set_audio (++n_audio);
807                         } else if (prop->value() == X_("midi")) {
808                                 cnt.set_midi (++n_midi);
809                         }
810                 }
811         }
812
813         n = ChanCount::max (n, cnt);
814         return 0;
815 }
816
817 int
818 IO::create_ports (const XMLNode& node, int version)
819 {
820         ChanCount n;
821         boost::shared_ptr<Bundle> c;
822
823         get_port_counts (node, version, n, c);
824
825         if (ensure_ports (n, true, true, this)) {
826                 error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
827                 return -1;
828         }
829
830         /* XXX use c */
831
832         return 0;
833 }
834
835 int
836 IO::make_connections (const XMLNode& node, int version, bool in)
837 {
838         if (version < 3000) {
839                 return make_connections_2X (node, version, in);
840         }
841
842         const XMLProperty* prop;
843
844         for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) {
845
846                 if ((*i)->name() == "Bundle") {
847                         XMLProperty const * prop = (*i)->property ("name");
848                         if (prop) {
849                                 boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value());
850                                 if (b) {
851                                         connect_ports_to_bundle (b, this);
852                                 }
853                         }
854
855                         return 0;
856                 }
857
858                 if ((*i)->name() == "Port") {
859
860                         prop = (*i)->property (X_("name"));
861
862                         if (!prop) {
863                                 continue;
864                         }
865
866                         Port* p = port_by_name (prop->value());
867
868                         if (p) {
869                                 for (XMLNodeConstIterator c = (*i)->children().begin(); c != (*i)->children().end(); ++c) {
870
871                                         XMLNode* cnode = (*c);
872
873                                         if (cnode->name() != X_("Connection")) {
874                                                 continue;
875                                         }
876
877                                         if ((prop = cnode->property (X_("other"))) == 0) {
878                                                 continue;
879                                         }
880
881                                         if (prop) {
882                                                 p->connect (prop->value());
883                                         }
884                                 }
885                         }
886                 }
887         }
888
889         return 0;
890 }
891
892
893 int
894 IO::make_connections_2X (const XMLNode& node, int /*version*/, bool in)
895 {
896         const XMLProperty* prop;
897
898         /* XXX: bundles ("connections" as was) */
899
900         if ((prop = node.property ("inputs")) != 0 && in) {
901
902                 string::size_type ostart = 0;
903                 string::size_type start = 0;
904                 string::size_type end = 0;
905                 int i = 0;
906                 int n;
907                 vector<string> ports;
908
909                 string const str = prop->value ();
910
911                 while ((start = str.find_first_of ('{', ostart)) != string::npos) {
912                         start += 1;
913
914                         if ((end = str.find_first_of ('}', start)) == string::npos) {
915                                 error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
916                                 return -1;
917                         }
918
919                         if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
920                                 error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
921
922                                 return -1;
923
924                         } else if (n > 0) {
925
926
927                                 for (int x = 0; x < n; ++x) {
928                                         /* XXX: this is a bit of a hack; need to check if it's always valid */
929                                         string::size_type const p = ports[x].find ("/out");
930                                         if (p != string::npos) {
931                                                 ports[x].replace (p, 4, "/audio_out");
932                                         }
933                                         nth(i)->connect (ports[x]);
934                                 }
935                         }
936
937                         ostart = end+1;
938                         i++;
939                 }
940
941         }
942
943         if ((prop = node.property ("outputs")) != 0 && !in) {
944
945                 string::size_type ostart = 0;
946                 string::size_type start = 0;
947                 string::size_type end = 0;
948                 int i = 0;
949                 int n;
950                 vector<string> ports;
951
952                 string const str = prop->value ();
953
954                 while ((start = str.find_first_of ('{', ostart)) != string::npos) {
955                         start += 1;
956
957                         if ((end = str.find_first_of ('}', start)) == string::npos) {
958                                 error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg;
959                                 return -1;
960                         }
961
962                         if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
963                                 error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg;
964
965                                 return -1;
966
967                         } else if (n > 0) {
968
969                                 for (int x = 0; x < n; ++x) {
970                                         /* XXX: this is a bit of a hack; need to check if it's always valid */
971                                         string::size_type const p = ports[x].find ("/in");
972                                         if (p != string::npos) {
973                                                 ports[x].replace (p, 3, "/audio_in");
974                                         }
975                                         nth(i)->connect (ports[x]);
976                                 }
977                         }
978
979                         ostart = end+1;
980                         i++;
981                 }
982         }
983
984         return 0;
985 }
986
987 int
988 IO::set_ports (const string& str)
989 {
990         vector<string> ports;
991         int i;
992         int n;
993         uint32_t nports;
994
995         if ((nports = count (str.begin(), str.end(), '{')) == 0) {
996                 return 0;
997         }
998
999         // FIXME: audio-only
1000         if (ensure_ports (ChanCount(DataType::AUDIO, nports), true, true, this)) {
1001                 return -1;
1002         }
1003
1004         string::size_type start, end, ostart;
1005
1006         ostart = 0;
1007         start = 0;
1008         end = 0;
1009         i = 0;
1010
1011         while ((start = str.find_first_of ('{', ostart)) != string::npos) {
1012                 start += 1;
1013
1014                 if ((end = str.find_first_of ('}', start)) == string::npos) {
1015                         error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg;
1016                         return -1;
1017                 }
1018
1019                 if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) {
1020                         error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg;
1021
1022                         return -1;
1023
1024                 } else if (n > 0) {
1025
1026                         for (int x = 0; x < n; ++x) {
1027                                 connect (nth (i), ports[x], this);
1028                         }
1029                 }
1030
1031                 ostart = end+1;
1032                 i++;
1033         }
1034
1035         return 0;
1036 }
1037
1038 int
1039 IO::parse_io_string (const string& str, vector<string>& ports)
1040 {
1041         string::size_type pos, opos;
1042
1043         if (str.length() == 0) {
1044                 return 0;
1045         }
1046
1047         pos = 0;
1048         opos = 0;
1049
1050         ports.clear ();
1051
1052         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1053                 ports.push_back (str.substr (opos, pos - opos));
1054                 opos = pos + 1;
1055         }
1056
1057         if (opos < str.length()) {
1058                 ports.push_back (str.substr(opos));
1059         }
1060
1061         return ports.size();
1062 }
1063
1064 int
1065 IO::parse_gain_string (const string& str, vector<string>& ports)
1066 {
1067         string::size_type pos, opos;
1068
1069         pos = 0;
1070         opos = 0;
1071         ports.clear ();
1072
1073         while ((pos = str.find_first_of (',', opos)) != string::npos) {
1074                 ports.push_back (str.substr (opos, pos - opos));
1075                 opos = pos + 1;
1076         }
1077
1078         if (opos < str.length()) {
1079                 ports.push_back (str.substr(opos));
1080         }
1081
1082         return ports.size();
1083 }
1084
1085 bool
1086 IO::set_name (const string& requested_name)
1087 {
1088         string name = requested_name;
1089
1090         if (name == _name) {
1091                 return true;
1092         }
1093
1094         /* replace all colons in the name. i wish we didn't have to do this */
1095
1096         if (replace_all (name, ":", "-")) {
1097                 warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
1098         }
1099
1100         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
1101                 string current_name = i->name();
1102                 current_name.replace (current_name.find (_name), _name.length(), name);
1103                 i->set_name (current_name);
1104         }
1105
1106         bool const r = SessionObject::set_name (name);
1107
1108         setup_bundles ();
1109
1110         return r;
1111 }
1112
1113 void
1114 IO::set_port_latency (nframes_t nframes)
1115 {
1116         Glib::Mutex::Lock lm (io_lock);
1117
1118         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
1119                 i->set_latency (nframes);
1120         }
1121 }
1122
1123 nframes_t
1124 IO::latency () const
1125 {
1126         nframes_t max_latency;
1127         nframes_t latency;
1128
1129         max_latency = 0;
1130
1131         /* io lock not taken - must be protected by other means */
1132
1133         for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
1134                 if ((latency = i->total_latency ()) > max_latency) {
1135                         max_latency = latency;
1136                 }
1137         }
1138
1139         return max_latency;
1140 }
1141
1142 void
1143 IO::update_port_total_latencies ()
1144 {
1145         /* io_lock, not taken: function must be called from Session::process() calltree */
1146
1147         for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
1148                 _session.engine().update_total_latency (*i);
1149         }
1150 }
1151
1152 int
1153 IO::connect_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
1154 {
1155         {
1156                 BLOCK_PROCESS_CALLBACK ();
1157                 Glib::Mutex::Lock lm2 (io_lock);
1158
1159                 c->connect (_bundle, _session.engine());
1160
1161                 /* If this is a UserBundle, make a note of what we've done */
1162
1163                 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
1164                 if (ub) {
1165
1166                         /* See if we already know about this one */
1167                         std::vector<UserBundleInfo>::iterator i = _bundles_connected.begin();
1168                         while (i != _bundles_connected.end() && i->bundle != ub) {
1169                                 ++i;
1170                         }
1171
1172                         if (i == _bundles_connected.end()) {
1173                                 /* We don't, so make a note */
1174                                 _bundles_connected.push_back (UserBundleInfo (this, ub));
1175                         }
1176                 }
1177         }
1178
1179         changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
1180         return 0;
1181 }
1182
1183 int
1184 IO::disconnect_ports_from_bundle (boost::shared_ptr<Bundle> c, void* src)
1185 {
1186         {
1187                 BLOCK_PROCESS_CALLBACK ();
1188                 Glib::Mutex::Lock lm2 (io_lock);
1189
1190                 c->disconnect (_bundle, _session.engine());
1191
1192                 /* If this is a UserBundle, make a note of what we've done */
1193
1194                 boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c);
1195                 if (ub) {
1196
1197                         std::vector<UserBundleInfo>::iterator i = _bundles_connected.begin();
1198                         while (i != _bundles_connected.end() && i->bundle != ub) {
1199                                 ++i;
1200                         }
1201
1202                         if (i != _bundles_connected.end()) {
1203                                 _bundles_connected.erase (i);
1204                         }
1205                 }
1206         }
1207
1208         changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */
1209         return 0;
1210 }
1211
1212
1213 int
1214 IO::disable_connecting ()
1215 {
1216         connecting_legal = false;
1217         return 0;
1218 }
1219
1220 int
1221 IO::enable_connecting ()
1222 {
1223         connecting_legal = true;
1224         return ConnectingLegal ();
1225 }
1226
1227 void
1228 IO::bundle_changed (Bundle::Change /*c*/)
1229 {
1230         //XXX
1231 //      connect_input_ports_to_bundle (_input_bundle, this);
1232 }
1233
1234
1235 string
1236 IO::build_legal_port_name (DataType type)
1237 {
1238         const int name_size = jack_port_name_size();
1239         int limit;
1240         string suffix;
1241
1242         if (type == DataType::AUDIO) {
1243                 suffix = _("audio");
1244         } else if (type == DataType::MIDI) {
1245                 suffix = _("midi");
1246         } else {
1247                 throw unknown_type();
1248         }
1249
1250         /* note that if "in" or "out" are translated it will break a session
1251            across locale switches because a port's connection list will
1252            show (old) translated names, but the current port name will
1253            use the (new) translated name.
1254         */
1255
1256         if (_direction == Input) {
1257                 suffix += X_("_in");
1258         } else {
1259                 suffix += X_("_out");
1260         }
1261
1262         // allow up to 4 digits for the output port number, plus the slash, suffix and extra space
1263
1264         limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
1265
1266         char buf1[name_size+1];
1267         char buf2[name_size+1];
1268
1269         snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
1270
1271         int port_number = find_port_hole (buf1);
1272         snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
1273
1274         return string (buf2);
1275 }
1276
1277 int32_t
1278 IO::find_port_hole (const char* base)
1279 {
1280         /* CALLER MUST HOLD IO LOCK */
1281
1282         uint32_t n;
1283
1284         if (_ports.empty()) {
1285                 return 1;
1286         }
1287
1288         /* we only allow up to 4 characters for the port number
1289          */
1290
1291         for (n = 1; n < 9999; ++n) {
1292                 char buf[jack_port_name_size()];
1293                 PortSet::iterator i = _ports.begin();
1294
1295                 snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
1296
1297                 for ( ; i != _ports.end(); ++i) {
1298                         if (i->name() == buf) {
1299                                 break;
1300                         }
1301                 }
1302
1303                 if (i == _ports.end()) {
1304                         break;
1305                 }
1306         }
1307         return n;
1308 }
1309
1310
1311 AudioPort*
1312 IO::audio(uint32_t n) const
1313 {
1314         return _ports.nth_audio_port (n);
1315
1316 }
1317
1318 MidiPort*
1319 IO::midi(uint32_t n) const
1320 {
1321         return _ports.nth_midi_port (n);
1322 }
1323
1324 /**
1325  *  Setup bundles that describe our inputs and outputs. Also creates bundles if necessary.
1326  */
1327
1328 void
1329 IO::setup_bundles ()
1330 {
1331         char buf[32];
1332
1333         if (!_bundle) {
1334                 _bundle.reset (new Bundle (_direction == Input));
1335         }
1336
1337         _bundle->suspend_signals ();
1338
1339         _bundle->set_type (default_type ());
1340
1341         _bundle->remove_channels ();
1342
1343         if (_direction == Input) {
1344                 snprintf(buf, sizeof (buf), _("%s in"), _name.c_str());
1345         } else {
1346                 snprintf(buf, sizeof (buf), _("%s out"), _name.c_str());
1347         }
1348         _bundle->set_name (buf);
1349         uint32_t const ni = _ports.num_ports();
1350         for (uint32_t i = 0; i < ni; ++i) {
1351                 _bundle->add_channel (bundle_channel_name (i, ni));
1352                 _bundle->set_port (i, _session.engine().make_port_name_non_relative (_ports.port(i)->name()));
1353         }
1354
1355         _bundle->resume_signals ();
1356 }
1357
1358 /** @return Bundles connected to our ports */
1359 BundleList
1360 IO::bundles_connected ()
1361 {
1362         BundleList bundles;
1363
1364         /* User bundles */
1365         for (std::vector<UserBundleInfo>::iterator i = _bundles_connected.begin(); i != _bundles_connected.end(); ++i) {
1366                 bundles.push_back (i->bundle);
1367         }
1368
1369         /* Session bundles */
1370         boost::shared_ptr<ARDOUR::BundleList> b = _session.bundles ();
1371         for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
1372                 if ((*i)->connected_to (_bundle, _session.engine())) {
1373                         bundles.push_back (*i);
1374                 }
1375         }
1376
1377         /* Route bundles */
1378
1379         boost::shared_ptr<ARDOUR::RouteList> r = _session.get_routes ();
1380
1381         if (_direction == Input) {
1382                 for (ARDOUR::RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1383                         if ((*i)->output()->bundle()->connected_to (_bundle, _session.engine())) {
1384                                 bundles.push_back ((*i)->output()->bundle());
1385                         }
1386                 }
1387         } else {
1388                 for (ARDOUR::RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1389                         if ((*i)->input()->bundle()->connected_to (_bundle, _session.engine())) {
1390                                 bundles.push_back ((*i)->input()->bundle());
1391                         }
1392                 }
1393         }
1394
1395         return bundles;
1396 }
1397
1398
1399 IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
1400 {
1401         bundle = b;
1402         changed = b->Changed.connect (
1403                 sigc::mem_fun (*io, &IO::bundle_changed)
1404                 );
1405 }
1406
1407 std::string
1408 IO::bundle_channel_name (uint32_t c, uint32_t n) const
1409 {
1410         char buf[32];
1411
1412         switch (n) {
1413         case 1:
1414                 return _("mono");
1415         case 2:
1416                 return c == 0 ? _("L") : _("R");
1417         default:
1418                 snprintf (buf, sizeof(buf), _("%d"), (c + 1));
1419                 return buf;
1420         }
1421
1422         return "";
1423 }
1424
1425 string
1426 IO::name_from_state (const XMLNode& node)
1427 {
1428         const XMLProperty* prop;
1429
1430         if ((prop = node.property ("name")) != 0) {
1431                 return prop->value();
1432         }
1433
1434         return string();
1435 }
1436
1437 void
1438 IO::set_name_in_state (XMLNode& node, const string& new_name)
1439 {
1440         const XMLProperty* prop;
1441
1442         if ((prop = node.property ("name")) != 0) {
1443                 node.add_property ("name", new_name);
1444         }
1445 }
1446
1447 bool
1448 IO::connected_to (boost::shared_ptr<const IO> other) const
1449 {
1450         if (!other) {
1451                 /* do we have any connections at all? */
1452
1453                 for (PortSet::const_iterator p = _ports.begin(); p != _ports.end(); ++p) {
1454                         if (p->connected()) {
1455                                 return true;
1456                         }
1457                 }
1458
1459                 return false;
1460         }
1461
1462         assert (_direction != other->direction());
1463
1464         uint32_t i, j;
1465         uint32_t no = n_ports().n_total();
1466         uint32_t ni = other->n_ports ().n_total();
1467
1468         for (i = 0; i < no; ++i) {
1469                 for (j = 0; j < ni; ++j) {
1470                         if (nth(i)->connected_to (other->nth(j)->name())) {
1471                                 return true;
1472                         }
1473                 }
1474         }
1475
1476         return false;
1477 }
1478
1479 void
1480 IO::process_input (boost::shared_ptr<Processor> proc, sframes_t start_frame, sframes_t end_frame, nframes_t nframes)
1481 {
1482         BufferSet bufs;
1483
1484         /* don't read the data into new buffers - just use the port buffers directly */
1485
1486         bufs.attach_buffers (_ports, nframes, 0);
1487         proc->run (bufs, start_frame, end_frame, nframes);
1488 }
1489
1490 void
1491 IO::collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset)
1492 {
1493         assert(bufs.available() >= _ports.count());
1494
1495         if (_ports.count() == ChanCount::ZERO) {
1496                 return;
1497         }
1498
1499         bufs.set_count (_ports.count());
1500
1501         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1502                 PortSet::iterator   i = _ports.begin(*t);
1503                 BufferSet::iterator b = bufs.begin(*t);
1504
1505                 for (uint32_t off = 0; off < offset.get(*t); ++off, ++b) {
1506                         if (b == bufs.end(*t)) {
1507                                 continue;
1508                         }
1509                 }
1510
1511                 for ( ; i != _ports.end(*t); ++i, ++b) {
1512                         Buffer& bb (i->get_buffer (nframes));
1513                         b->read_from (bb, nframes);
1514                 }
1515         }
1516 }
1517
1518 void
1519 IO::copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes, nframes_t offset)
1520 {
1521         // Copy any buffers 1:1 to outputs
1522
1523         PortSet::iterator o = _ports.begin(type);
1524         BufferSet::iterator i = bufs.begin(type);
1525         BufferSet::iterator prev = i;
1526
1527         while (i != bufs.end(type) && o != _ports.end (type)) {
1528                 Buffer& port_buffer (o->get_buffer (nframes));
1529                 port_buffer.read_from (*i, nframes, offset);
1530                 prev = i;
1531                 ++i;
1532                 ++o;
1533         }
1534
1535         // Copy last buffer to any extra outputs
1536
1537         while (o != _ports.end(type)) {
1538                 Buffer& port_buffer (o->get_buffer (nframes));
1539                 port_buffer.read_from (*prev, nframes, offset);
1540                 ++o;
1541         }
1542 }
1543
1544 Port*
1545 IO::port_by_name (const std::string& str) const
1546 {
1547         /* to be called only from ::set_state() - no locking */
1548
1549         for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
1550
1551                 const Port& p(*i);
1552
1553                 if (p.name() == str) {
1554                         return const_cast<Port*>(&p);
1555                 }
1556         }
1557
1558         return 0;
1559 }