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