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