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