2 Copyright (C) 2000-2006 Paul Davis
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.
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.
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.
28 #include <glibmm/thread.h>
30 #include "pbd/xml++.h"
31 #include "pbd/replace_all.h"
32 #include "pbd/unknown_type.h"
33 #include "pbd/enumwriter.h"
35 #include "ardour/audioengine.h"
36 #include "ardour/buffer.h"
37 #include "ardour/debug.h"
38 #include "ardour/io.h"
39 #include "ardour/route.h"
40 #include "ardour/port.h"
41 #include "ardour/audio_port.h"
42 #include "ardour/midi_port.h"
43 #include "ardour/session.h"
44 #include "ardour/cycle_timer.h"
45 #include "ardour/buffer_set.h"
46 #include "ardour/meter.h"
47 #include "ardour/amp.h"
48 #include "ardour/user_bundle.h"
52 #define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (AudioEngine::instance()->process_lock())
55 using namespace ARDOUR
;
58 const string
IO::state_node_name
= "IO";
59 bool IO::connecting_legal
= false;
60 PBD::Signal0
<int> IO::ConnectingLegal
;
61 PBD::Signal1
<void,ChanCount
> IO::PortCountChanged
;
63 /** @param default_type The type of port that will be created by ensure_io
64 * and friends if no type is explicitly requested (to avoid breakage).
66 IO::IO (Session
& s
, const string
& name
, Direction dir
, DataType default_type
)
67 : SessionObject (s
, name
)
69 , _default_type (default_type
)
72 pending_state_node
= 0;
76 IO::IO (Session
& s
, const XMLNode
& node
, DataType dt
)
77 : SessionObject(s
, "unnamed io")
82 pending_state_node
= 0;
84 set_state (node
, Stateful::loading_state_version
);
90 Glib::Mutex::Lock
lm (io_lock
);
92 BLOCK_PROCESS_CALLBACK ();
94 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
95 _session
.engine().unregister_port (*i
);
100 IO::increment_port_buffer_offset (pframes_t offset
)
102 /* io_lock, not taken: function must be called from Session::process() calltree */
104 if (_direction
== Output
) {
105 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
106 i
->increment_port_buffer_offset (offset
);
112 IO::silence (framecnt_t nframes
)
114 /* io_lock, not taken: function must be called from Session::process() calltree */
116 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
117 i
->get_buffer(nframes
).silence (nframes
);
122 IO::check_bundles_connected ()
124 check_bundles (_bundles_connected
, ports());
127 /** Check the bundles in list to see which are connected to a given PortSet,
128 * and update list with those that are connected such that every port on every
129 * bundle channel x is connected to port x in ports.
132 IO::check_bundles (std::vector
<UserBundleInfo
*>& list
, const PortSet
& ports
)
134 std::vector
<UserBundleInfo
*> new_list
;
136 for (std::vector
<UserBundleInfo
*>::iterator i
= list
.begin(); i
!= list
.end(); ++i
) {
138 uint32_t const N
= (*i
)->bundle
->nchannels().n_total();
140 if (_ports
.num_ports() < N
) {
146 for (uint32_t j
= 0; j
< N
; ++j
) {
147 /* Every port on bundle channel j must be connected to our input j */
148 Bundle::PortList
const pl
= (*i
)->bundle
->channel_ports (j
);
149 for (uint32_t k
= 0; k
< pl
.size(); ++k
) {
150 if (ports
.port(j
)->connected_to (pl
[k
]) == false) {
162 new_list
.push_back (*i
);
173 IO::disconnect (Port
* our_port
, string other_port
, void* src
)
175 if (other_port
.length() == 0 || our_port
== 0) {
180 Glib::Mutex::Lock
lm (io_lock
);
182 /* check that our_port is really one of ours */
184 if ( ! _ports
.contains(our_port
)) {
188 /* disconnect it from the source */
190 if (our_port
->disconnect (other_port
)) {
191 error
<< string_compose(_("IO: cannot disconnect port %1 from %2"), our_port
->name(), other_port
) << endmsg
;
195 check_bundles_connected ();
198 changed (IOChange (IOChange::ConnectionsChanged
), src
); /* EMIT SIGNAL */
200 _session
.set_dirty ();
206 IO::connect (Port
* our_port
, string other_port
, void* src
)
208 if (other_port
.length() == 0 || our_port
== 0) {
213 Glib::Mutex::Lock
lm (io_lock
);
215 /* check that our_port is really one of ours */
217 if ( ! _ports
.contains(our_port
) ) {
221 /* connect it to the source */
223 if (our_port
->connect (other_port
)) {
227 changed (IOChange (IOChange::ConnectionsChanged
), src
); /* EMIT SIGNAL */
228 _session
.set_dirty ();
233 IO::remove_port (Port
* port
, void* src
)
235 ChanCount before
= _ports
.count ();
236 ChanCount after
= before
;
237 after
.set (port
->type(), after
.get (port
->type()) - 1);
239 bool const r
= PortCountChanging (after
); /* EMIT SIGNAL */
247 BLOCK_PROCESS_CALLBACK ();
250 Glib::Mutex::Lock
lm (io_lock
);
252 if (_ports
.remove(port
)) {
253 change
.type
= IOChange::Type (change
.type
| IOChange::ConfigurationChanged
);
254 change
.before
= before
;
255 change
.after
= _ports
.count ();
257 if (port
->connected()) {
258 change
.type
= IOChange::Type (change
.type
| IOChange::ConnectionsChanged
);
261 _session
.engine().unregister_port (*port
);
262 check_bundles_connected ();
266 PortCountChanged (n_ports()); /* EMIT SIGNAL */
268 if (change
.type
!= IOChange::NoChange
) {
269 changed (change
, src
);
270 _session
.set_dirty ();
274 if (change
.type
& IOChange::ConfigurationChanged
) {
278 if (change
.type
== IOChange::NoChange
) {
287 * @param destination Name of port to connect new port to.
288 * @param src Source for emitted ConfigurationChanged signal.
289 * @param type Data type of port. Default value (NIL) will use this IO's default type.
292 IO::add_port (string destination
, void* src
, DataType type
)
296 if (type
== DataType::NIL
) {
297 type
= _default_type
;
303 BLOCK_PROCESS_CALLBACK ();
307 Glib::Mutex::Lock
lm (io_lock
);
309 /* Create a new port */
311 string portname
= build_legal_port_name (type
);
313 if (_direction
== Input
) {
314 if ((our_port
= _session
.engine().register_input_port (type
, portname
)) == 0) {
315 error
<< string_compose(_("IO: cannot register input port %1"), portname
) << endmsg
;
319 if ((our_port
= _session
.engine().register_output_port (type
, portname
)) == 0) {
320 error
<< string_compose(_("IO: cannot register output port %1"), portname
) << endmsg
;
325 change
.before
= _ports
.count ();
326 _ports
.add (our_port
);
329 PortCountChanged (n_ports()); /* EMIT SIGNAL */
331 // pan_changed (src); /* EMIT SIGNAL */
332 change
.type
= IOChange::ConfigurationChanged
;
333 change
.after
= _ports
.count ();
334 changed (change
, src
); /* EMIT SIGNAL */
337 if (destination
.length()) {
338 if (our_port
->connect (destination
)) {
344 _session
.set_dirty ();
350 IO::disconnect (void* src
)
353 Glib::Mutex::Lock
lm (io_lock
);
355 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
356 i
->disconnect_all ();
359 check_bundles_connected ();
362 changed (IOChange (IOChange::ConnectionsChanged
), src
); /* EMIT SIGNAL */
367 /** Caller must hold process lock */
369 IO::ensure_ports_locked (ChanCount count
, bool clear
, void* /*src*/)
371 assert (!AudioEngine::instance()->process_lock().trylock());
374 bool changed
= false;
376 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
378 const size_t n
= count
.get(*t
);
380 /* remove unused ports */
381 for (size_t i
= n_ports().get(*t
); i
> n
; --i
) {
382 port
= _ports
.port(*t
, i
-1);
386 _session
.engine().unregister_port (*port
);
391 /* create any necessary new ports */
392 while (n_ports().get(*t
) < n
) {
394 string portname
= build_legal_port_name (*t
);
398 if (_direction
== Input
) {
399 if ((port
= _session
.engine().register_input_port (*t
, portname
)) == 0) {
400 error
<< string_compose(_("IO: cannot register input port %1"), portname
) << endmsg
;
404 if ((port
= _session
.engine().register_output_port (*t
, portname
)) == 0) {
405 error
<< string_compose(_("IO: cannot register output port %1"), portname
) << endmsg
;
411 catch (AudioEngine::PortRegistrationFailure
& err
) {
422 check_bundles_connected ();
423 PortCountChanged (n_ports()); /* EMIT SIGNAL */
424 _session
.set_dirty ();
428 /* disconnect all existing ports so that we get a fresh start */
429 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
430 i
->disconnect_all ();
437 /** Caller must hold process lock */
439 IO::ensure_ports (ChanCount count
, bool clear
, void* src
)
441 assert (!AudioEngine::instance()->process_lock().trylock());
443 bool changed
= false;
445 if (count
== n_ports() && !clear
) {
451 change
.before
= _ports
.count ();
454 Glib::Mutex::Lock
im (io_lock
);
455 changed
= ensure_ports_locked (count
, clear
, src
);
459 change
.after
= _ports
.count ();
460 change
.type
= IOChange::ConfigurationChanged
;
461 this->changed (change
, src
); /* EMIT SIGNAL */
462 _buffers
.attach_buffers (_ports
);
464 _session
.set_dirty ();
470 /** Caller must hold process lock */
472 IO::ensure_io (ChanCount count
, bool clear
, void* src
)
474 assert (!AudioEngine::instance()->process_lock().trylock());
476 return ensure_ports (count
, clear
, src
);
486 IO::state (bool /*full_state*/)
488 XMLNode
* node
= new XMLNode (state_node_name
);
491 vector
<string
>::iterator ci
;
493 LocaleGuard
lg (X_("POSIX"));
494 Glib::Mutex::Lock
lm (io_lock
);
496 node
->add_property("name", _name
);
497 id().print (buf
, sizeof (buf
));
498 node
->add_property("id", buf
);
499 node
->add_property ("direction", enum_2_string (_direction
));
500 node
->add_property ("default-type", _default_type
.to_string());
502 for (std::vector
<UserBundleInfo
*>::iterator i
= _bundles_connected
.begin(); i
!= _bundles_connected
.end(); ++i
) {
503 XMLNode
* n
= new XMLNode ("Bundle");
504 n
->add_property ("name", (*i
)->bundle
->name ());
505 node
->add_child_nocopy (*n
);
508 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
510 vector
<string
> connections
;
512 XMLNode
* pnode
= new XMLNode (X_("Port"));
513 pnode
->add_property (X_("type"), i
->type().to_string());
514 pnode
->add_property (X_("name"), i
->name());
516 if (i
->get_connections (connections
)) {
518 for (n
= 0, ci
= connections
.begin(); ci
!= connections
.end(); ++ci
, ++n
) {
520 /* if its a connection to our own port,
521 return only the port name, not the
522 whole thing. this allows connections
523 to be re-established even when our
524 client name is different.
527 XMLNode
* cnode
= new XMLNode (X_("Connection"));
529 cnode
->add_property (X_("other"), _session
.engine().make_port_name_relative (*ci
));
530 pnode
->add_child_nocopy (*cnode
);
534 node
->add_child_nocopy (*pnode
);
541 IO::set_state (const XMLNode
& node
, int version
)
543 /* callers for version < 3000 need to call set_state_2X directly, as A3 IOs
544 * are input OR output, not both, so the direction needs to be specified
547 assert (version
>= 3000);
549 const XMLProperty
* prop
;
550 XMLNodeConstIterator iter
;
551 LocaleGuard
lg (X_("POSIX"));
553 /* force use of non-localized representation of decimal point,
554 since we use it a lot in XML files and so forth.
557 if (node
.name() != state_node_name
) {
558 error
<< string_compose(_("incorrect XML node \"%1\" passed to IO object"), node
.name()) << endmsg
;
562 if ((prop
= node
.property ("name")) != 0) {
563 set_name (prop
->value());
566 if ((prop
= node
.property (X_("default-type"))) != 0) {
567 _default_type
= DataType(prop
->value());
568 assert(_default_type
!= DataType::NIL
);
571 if ((prop
= node
.property ("id")) != 0) {
572 _id
= prop
->value ();
575 if ((prop
= node
.property ("direction")) != 0) {
576 _direction
= (Direction
) string_2_enum (prop
->value(), _direction
);
579 if (create_ports (node
, version
)) {
583 if (connecting_legal
) {
585 if (make_connections (node
, version
, false)) {
591 pending_state_node
= new XMLNode (node
);
592 pending_state_node_version
= version
;
593 pending_state_node_in
= false;
594 ConnectingLegal
.connect_same_thread (connection_legal_c
, boost::bind (&IO::connecting_became_legal
, this));
602 IO::set_state_2X (const XMLNode
& node
, int version
, bool in
)
604 const XMLProperty
* prop
;
605 XMLNodeConstIterator iter
;
606 LocaleGuard
lg (X_("POSIX"));
608 /* force use of non-localized representation of decimal point,
609 since we use it a lot in XML files and so forth.
612 if (node
.name() != state_node_name
) {
613 error
<< string_compose(_("incorrect XML node \"%1\" passed to IO object"), node
.name()) << endmsg
;
617 if ((prop
= node
.property ("name")) != 0) {
618 set_name (prop
->value());
621 if ((prop
= node
.property (X_("default-type"))) != 0) {
622 _default_type
= DataType(prop
->value());
623 assert(_default_type
!= DataType::NIL
);
626 if ((prop
= node
.property ("id")) != 0) {
627 _id
= prop
->value ();
630 _direction
= in
? Input
: Output
;
632 if (create_ports (node
, version
)) {
636 if (connecting_legal
) {
638 if (make_connections_2X (node
, version
, in
)) {
644 pending_state_node
= new XMLNode (node
);
645 pending_state_node_version
= version
;
646 pending_state_node_in
= in
;
647 ConnectingLegal
.connect_same_thread (connection_legal_c
, boost::bind (&IO::connecting_became_legal
, this));
654 IO::connecting_became_legal ()
658 assert (pending_state_node
);
660 connection_legal_c
.disconnect ();
662 ret
= make_connections (*pending_state_node
, pending_state_node_version
, pending_state_node_in
);
664 delete pending_state_node
;
665 pending_state_node
= 0;
670 boost::shared_ptr
<Bundle
>
671 IO::find_possible_bundle (const string
&desired_name
)
673 static const string digits
= "0123456789";
674 const string
&default_name
= (_direction
== Input
? _("in") : _("out"));
675 const string
&bundle_type_name
= (_direction
== Input
? _("input") : _("output"));
677 boost::shared_ptr
<Bundle
> c
= _session
.bundle_by_name (desired_name
);
680 int bundle_number
, mask
;
681 string possible_name
;
683 string::size_type last_non_digit_pos
;
685 error
<< string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name
, bundle_type_name
, _name
)
688 // find numeric suffix of desired name
691 last_non_digit_pos
= desired_name
.find_last_not_of(digits
);
693 if (last_non_digit_pos
!= string::npos
) {
695 s
<< desired_name
.substr(last_non_digit_pos
);
699 // see if it's a stereo connection e.g. "in 3+4"
701 if (last_non_digit_pos
> 1 && desired_name
[last_non_digit_pos
] == '+') {
702 string::size_type left_last_non_digit_pos
;
704 left_last_non_digit_pos
= desired_name
.find_last_not_of(digits
, last_non_digit_pos
-1);
706 if (left_last_non_digit_pos
!= string::npos
) {
707 int left_bundle_number
= 0;
709 s
<< desired_name
.substr(left_last_non_digit_pos
, last_non_digit_pos
-1);
710 s
>> left_bundle_number
;
712 if (left_bundle_number
> 0 && left_bundle_number
+ 1 == bundle_number
) {
723 // find highest set bit
725 while ((mask
<= bundle_number
) && (mask
<<= 1)) {}
727 // "wrap" bundle number into largest possible power of 2
732 if (bundle_number
& mask
) {
733 bundle_number
&= ~mask
;
736 s
<< default_name
<< " " << bundle_number
+ 1;
739 s
<< "+" << bundle_number
+ 2;
742 possible_name
= s
.str();
744 if ((c
= _session
.bundle_by_name (possible_name
)) != 0) {
751 info
<< string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name
, possible_name
)
754 error
<< string_compose(_("No %1 bundles available as a replacement"), bundle_type_name
)
765 IO::get_port_counts_2X (XMLNode
const & node
, int /*version*/, ChanCount
& n
, boost::shared_ptr
<Bundle
>& /*c*/)
767 XMLProperty
const * prop
;
768 XMLNodeList children
= node
.children ();
770 uint32_t n_audio
= 0;
772 for (XMLNodeIterator i
= children
.begin(); i
!= children
.end(); ++i
) {
774 if ((prop
= node
.property ("inputs")) != 0 && _direction
== Input
) {
775 n_audio
= count (prop
->value().begin(), prop
->value().end(), '{');
776 } else if ((prop
= node
.property ("input-connection")) != 0 && _direction
== Input
) {
778 } else if ((prop
= node
.property ("outputs")) != 0 && _direction
== Output
) {
779 n_audio
= count (prop
->value().begin(), prop
->value().end(), '{');
780 } else if ((prop
= node
.property ("output-connection")) != 0 && _direction
== Output
) {
786 cnt
.set_audio (n_audio
);
787 n
= ChanCount::max (n
, cnt
);
793 IO::get_port_counts (const XMLNode
& node
, int version
, ChanCount
& n
, boost::shared_ptr
<Bundle
>& c
)
795 if (version
< 3000) {
796 return get_port_counts_2X (node
, version
, n
, c
);
799 XMLProperty
const * prop
;
800 XMLNodeConstIterator iter
;
801 uint32_t n_audio
= 0;
807 if ((prop
= node
.property ("connection")) != 0) {
809 if ((c
= find_possible_bundle (prop
->value())) != 0) {
810 n
= ChanCount::max (n
, c
->nchannels());
815 for (iter
= node
.children().begin(); iter
!= node
.children().end(); ++iter
) {
817 if ((*iter
)->name() == X_("Bundle")) {
818 if ((c
= find_possible_bundle (prop
->value())) != 0) {
819 n
= ChanCount::max (n
, c
->nchannels());
826 if ((*iter
)->name() == X_("Port")) {
827 prop
= (*iter
)->property (X_("type"));
833 if (prop
->value() == X_("audio")) {
834 cnt
.set_audio (++n_audio
);
835 } else if (prop
->value() == X_("midi")) {
836 cnt
.set_midi (++n_midi
);
841 n
= ChanCount::max (n
, cnt
);
846 IO::create_ports (const XMLNode
& node
, int version
)
849 boost::shared_ptr
<Bundle
> c
;
851 get_port_counts (node
, version
, n
, c
);
854 Glib::Mutex::Lock
lm (AudioEngine::instance()->process_lock ());
856 if (ensure_ports (n
, true, this)) {
857 error
<< string_compose(_("%1: cannot create I/O ports"), _name
) << endmsg
;
868 IO::make_connections (const XMLNode
& node
, int version
, bool in
)
870 if (version
< 3000) {
871 return make_connections_2X (node
, version
, in
);
874 const XMLProperty
* prop
;
876 for (XMLNodeConstIterator i
= node
.children().begin(); i
!= node
.children().end(); ++i
) {
878 if ((*i
)->name() == "Bundle") {
879 XMLProperty
const * prop
= (*i
)->property ("name");
881 boost::shared_ptr
<Bundle
> b
= find_possible_bundle (prop
->value());
883 connect_ports_to_bundle (b
, this);
890 if ((*i
)->name() == "Port") {
892 prop
= (*i
)->property (X_("name"));
898 Port
* p
= port_by_name (prop
->value());
901 for (XMLNodeConstIterator c
= (*i
)->children().begin(); c
!= (*i
)->children().end(); ++c
) {
903 XMLNode
* cnode
= (*c
);
905 if (cnode
->name() != X_("Connection")) {
909 if ((prop
= cnode
->property (X_("other"))) == 0) {
914 connect (p
, prop
->value(), this);
926 IO::make_connections_2X (const XMLNode
& node
, int /*version*/, bool in
)
928 const XMLProperty
* prop
;
930 /* XXX: bundles ("connections" as was) */
932 if ((prop
= node
.property ("inputs")) != 0 && in
) {
934 string::size_type ostart
= 0;
935 string::size_type start
= 0;
936 string::size_type end
= 0;
939 vector
<string
> ports
;
941 string
const str
= prop
->value ();
943 while ((start
= str
.find_first_of ('{', ostart
)) != string::npos
) {
946 if ((end
= str
.find_first_of ('}', start
)) == string::npos
) {
947 error
<< string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str
) << endmsg
;
951 if ((n
= parse_io_string (str
.substr (start
, end
- start
), ports
)) < 0) {
952 error
<< string_compose(_("bad input string in XML node \"%1\""), str
) << endmsg
;
959 for (int x
= 0; x
< n
; ++x
) {
960 /* XXX: this is a bit of a hack; need to check if it's always valid */
961 string::size_type
const p
= ports
[x
].find ("/out");
962 if (p
!= string::npos
) {
963 ports
[x
].replace (p
, 4, "/audio_out");
965 nth(i
)->connect (ports
[x
]);
975 if ((prop
= node
.property ("outputs")) != 0 && !in
) {
977 string::size_type ostart
= 0;
978 string::size_type start
= 0;
979 string::size_type end
= 0;
982 vector
<string
> ports
;
984 string
const str
= prop
->value ();
986 while ((start
= str
.find_first_of ('{', ostart
)) != string::npos
) {
989 if ((end
= str
.find_first_of ('}', start
)) == string::npos
) {
990 error
<< string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str
) << endmsg
;
994 if ((n
= parse_io_string (str
.substr (start
, end
- start
), ports
)) < 0) {
995 error
<< string_compose(_("IO: bad output string in XML node \"%1\""), str
) << endmsg
;
1001 for (int x
= 0; x
< n
; ++x
) {
1002 /* XXX: this is a bit of a hack; need to check if it's always valid */
1003 string::size_type
const p
= ports
[x
].find ("/in");
1004 if (p
!= string::npos
) {
1005 ports
[x
].replace (p
, 3, "/audio_in");
1007 nth(i
)->connect (ports
[x
]);
1020 IO::set_ports (const string
& str
)
1022 vector
<string
> ports
;
1027 if ((nports
= count (str
.begin(), str
.end(), '{')) == 0) {
1032 Glib::Mutex::Lock
lm (AudioEngine::instance()->process_lock ());
1034 // FIXME: audio-only
1035 if (ensure_ports (ChanCount(DataType::AUDIO
, nports
), true, this)) {
1040 string::size_type start
, end
, ostart
;
1047 while ((start
= str
.find_first_of ('{', ostart
)) != string::npos
) {
1050 if ((end
= str
.find_first_of ('}', start
)) == string::npos
) {
1051 error
<< string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str
) << endmsg
;
1055 if ((n
= parse_io_string (str
.substr (start
, end
- start
), ports
)) < 0) {
1056 error
<< string_compose(_("bad input string in XML node \"%1\""), str
) << endmsg
;
1062 for (int x
= 0; x
< n
; ++x
) {
1063 connect (nth (i
), ports
[x
], this);
1075 IO::parse_io_string (const string
& str
, vector
<string
>& ports
)
1077 string::size_type pos
, opos
;
1079 if (str
.length() == 0) {
1088 while ((pos
= str
.find_first_of (',', opos
)) != string::npos
) {
1089 ports
.push_back (str
.substr (opos
, pos
- opos
));
1093 if (opos
< str
.length()) {
1094 ports
.push_back (str
.substr(opos
));
1097 return ports
.size();
1101 IO::parse_gain_string (const string
& str
, vector
<string
>& ports
)
1103 string::size_type pos
, opos
;
1109 while ((pos
= str
.find_first_of (',', opos
)) != string::npos
) {
1110 ports
.push_back (str
.substr (opos
, pos
- opos
));
1114 if (opos
< str
.length()) {
1115 ports
.push_back (str
.substr(opos
));
1118 return ports
.size();
1122 IO::set_name (const string
& requested_name
)
1124 string name
= requested_name
;
1126 if (_name
== name
) {
1130 /* replace all colons in the name. i wish we didn't have to do this */
1132 replace_all (name
, ":", "-");
1134 for (PortSet::iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
1135 string current_name
= i
->name();
1136 current_name
.replace (current_name
.find (_name
), _name
.val().length(), name
);
1137 i
->set_name (current_name
);
1140 bool const r
= SessionObject::set_name (name
);
1148 IO::latency () const
1150 framecnt_t max_latency
;
1155 /* io lock not taken - must be protected by other means */
1157 for (PortSet::const_iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
1158 if ((latency
= i
->private_latency_range (_direction
== Output
).max
) > max_latency
) {
1159 max_latency
= latency
;
1163 DEBUG_TRACE (DEBUG::Latency
, string_compose ("%1: max %4 latency from %2 ports = %3\n",
1164 name(), _ports
.num_ports(), max_latency
,
1165 ((_direction
== Output
) ? "PLAYBACK" : "CAPTURE")));
1170 IO::connect_ports_to_bundle (boost::shared_ptr
<Bundle
> c
, void* src
)
1172 BLOCK_PROCESS_CALLBACK ();
1175 Glib::Mutex::Lock
lm2 (io_lock
);
1177 c
->connect (_bundle
, _session
.engine());
1179 /* If this is a UserBundle, make a note of what we've done */
1181 boost::shared_ptr
<UserBundle
> ub
= boost::dynamic_pointer_cast
<UserBundle
> (c
);
1184 /* See if we already know about this one */
1185 std::vector
<UserBundleInfo
*>::iterator i
= _bundles_connected
.begin();
1186 while (i
!= _bundles_connected
.end() && (*i
)->bundle
!= ub
) {
1190 if (i
== _bundles_connected
.end()) {
1191 /* We don't, so make a note */
1192 _bundles_connected
.push_back (new UserBundleInfo (this, ub
));
1197 changed (IOChange (IOChange::ConnectionsChanged
), src
); /* EMIT SIGNAL */
1202 IO::disconnect_ports_from_bundle (boost::shared_ptr
<Bundle
> c
, void* src
)
1204 BLOCK_PROCESS_CALLBACK ();
1207 Glib::Mutex::Lock
lm2 (io_lock
);
1209 c
->disconnect (_bundle
, _session
.engine());
1211 /* If this is a UserBundle, make a note of what we've done */
1213 boost::shared_ptr
<UserBundle
> ub
= boost::dynamic_pointer_cast
<UserBundle
> (c
);
1216 std::vector
<UserBundleInfo
*>::iterator i
= _bundles_connected
.begin();
1217 while (i
!= _bundles_connected
.end() && (*i
)->bundle
!= ub
) {
1221 if (i
!= _bundles_connected
.end()) {
1223 _bundles_connected
.erase (i
);
1228 changed (IOChange (IOChange::ConnectionsChanged
), src
); /* EMIT SIGNAL */
1234 IO::disable_connecting ()
1236 connecting_legal
= false;
1241 IO::enable_connecting ()
1243 connecting_legal
= true;
1244 boost::optional
<int> r
= ConnectingLegal ();
1245 return r
.get_value_or (0);
1249 IO::bundle_changed (Bundle::Change
/*c*/)
1252 // connect_input_ports_to_bundle (_input_bundle, this);
1257 IO::build_legal_port_name (DataType type
)
1259 const int name_size
= jack_port_name_size();
1263 if (type
== DataType::AUDIO
) {
1264 suffix
= _("audio");
1265 } else if (type
== DataType::MIDI
) {
1268 throw unknown_type();
1271 /* note that if "in" or "out" are translated it will break a session
1272 across locale switches because a port's connection list will
1273 show (old) translated names, but the current port name will
1274 use the (new) translated name.
1277 if (_direction
== Input
) {
1278 suffix
+= X_("_in");
1280 suffix
+= X_("_out");
1283 // allow up to 4 digits for the output port number, plus the slash, suffix and extra space
1285 limit
= name_size
- _session
.engine().client_name().length() - (suffix
.length() + 5);
1287 char buf1
[name_size
+1];
1288 char buf2
[name_size
+1];
1290 snprintf (buf1
, name_size
+1, ("%.*s/%s"), limit
, _name
.val().c_str(), suffix
.c_str());
1292 int port_number
= find_port_hole (buf1
);
1293 snprintf (buf2
, name_size
+1, "%s %d", buf1
, port_number
);
1295 return string (buf2
);
1299 IO::find_port_hole (const char* base
)
1301 /* CALLER MUST HOLD IO LOCK */
1305 if (_ports
.empty()) {
1309 /* we only allow up to 4 characters for the port number
1312 for (n
= 1; n
< 9999; ++n
) {
1313 char buf
[jack_port_name_size()];
1314 PortSet::iterator i
= _ports
.begin();
1316 snprintf (buf
, jack_port_name_size(), _("%s %u"), base
, n
);
1318 for ( ; i
!= _ports
.end(); ++i
) {
1319 if (i
->name() == buf
) {
1324 if (i
== _ports
.end()) {
1333 IO::audio(uint32_t n
) const
1335 return _ports
.nth_audio_port (n
);
1340 IO::midi(uint32_t n
) const
1342 return _ports
.nth_midi_port (n
);
1346 * Setup a bundle that describe our inputs or outputs. Also creates the bundle if necessary.
1355 _bundle
.reset (new Bundle (_direction
== Input
));
1358 _bundle
->suspend_signals ();
1360 _bundle
->remove_channels ();
1362 if (_direction
== Input
) {
1363 snprintf(buf
, sizeof (buf
), _("%s in"), _name
.val().c_str());
1365 snprintf(buf
, sizeof (buf
), _("%s out"), _name
.val().c_str());
1367 _bundle
->set_name (buf
);
1370 for (DataType::iterator i
= DataType::begin(); i
!= DataType::end(); ++i
) {
1372 uint32_t const N
= _ports
.count().get (*i
);
1373 for (uint32_t j
= 0; j
< N
; ++j
) {
1374 _bundle
->add_channel (bundle_channel_name (j
, N
, *i
), *i
);
1375 _bundle
->set_port (c
, _session
.engine().make_port_name_non_relative (_ports
.port(*i
, j
)->name()));
1381 _bundle
->resume_signals ();
1384 /** @return Bundles connected to our ports */
1386 IO::bundles_connected ()
1391 for (std::vector
<UserBundleInfo
*>::iterator i
= _bundles_connected
.begin(); i
!= _bundles_connected
.end(); ++i
) {
1392 bundles
.push_back ((*i
)->bundle
);
1395 /* Session bundles */
1396 boost::shared_ptr
<ARDOUR::BundleList
> b
= _session
.bundles ();
1397 for (ARDOUR::BundleList::iterator i
= b
->begin(); i
!= b
->end(); ++i
) {
1398 if ((*i
)->connected_to (_bundle
, _session
.engine())) {
1399 bundles
.push_back (*i
);
1405 boost::shared_ptr
<ARDOUR::RouteList
> r
= _session
.get_routes ();
1407 if (_direction
== Input
) {
1408 for (ARDOUR::RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1409 if ((*i
)->output()->bundle()->connected_to (_bundle
, _session
.engine())) {
1410 bundles
.push_back ((*i
)->output()->bundle());
1414 for (ARDOUR::RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
1415 if ((*i
)->input()->bundle()->connected_to (_bundle
, _session
.engine())) {
1416 bundles
.push_back ((*i
)->input()->bundle());
1425 IO::UserBundleInfo::UserBundleInfo (IO
* io
, boost::shared_ptr
<UserBundle
> b
)
1428 b
->Changed
.connect_same_thread (changed
, boost::bind (&IO::bundle_changed
, io
, _1
));
1432 IO::bundle_channel_name (uint32_t c
, uint32_t n
, DataType t
) const
1436 if (t
== DataType::AUDIO
) {
1442 return c
== 0 ? _("L") : _("R");
1444 snprintf (buf
, sizeof(buf
), _("%d"), (c
+ 1));
1450 snprintf (buf
, sizeof(buf
), _("%d"), (c
+ 1));
1459 IO::name_from_state (const XMLNode
& node
)
1461 const XMLProperty
* prop
;
1463 if ((prop
= node
.property ("name")) != 0) {
1464 return prop
->value();
1471 IO::set_name_in_state (XMLNode
& node
, const string
& new_name
)
1473 const XMLProperty
* prop
;
1475 if ((prop
= node
.property ("name")) != 0) {
1476 node
.add_property ("name", new_name
);
1481 IO::connected () const
1483 /* do we have any connections at all? */
1485 for (PortSet::const_iterator p
= _ports
.begin(); p
!= _ports
.end(); ++p
) {
1486 if (p
->connected()) {
1495 IO::connected_to (boost::shared_ptr
<const IO
> other
) const
1498 return connected ();
1501 assert (_direction
!= other
->direction());
1504 uint32_t no
= n_ports().n_total();
1505 uint32_t ni
= other
->n_ports ().n_total();
1507 for (i
= 0; i
< no
; ++i
) {
1508 for (j
= 0; j
< ni
; ++j
) {
1509 if (nth(i
)->connected_to (other
->nth(j
)->name())) {
1519 IO::process_input (boost::shared_ptr
<Processor
> proc
, framepos_t start_frame
, framepos_t end_frame
, pframes_t nframes
)
1521 /* don't read the data into new buffers - just use the port buffers directly */
1523 _buffers
.get_jack_port_addresses (_ports
, nframes
);
1524 proc
->run (_buffers
, start_frame
, end_frame
, nframes
, true);
1528 IO::collect_input (BufferSet
& bufs
, pframes_t nframes
, ChanCount offset
)
1530 assert(bufs
.available() >= _ports
.count());
1532 if (_ports
.count() == ChanCount::ZERO
) {
1536 bufs
.set_count (_ports
.count());
1538 for (DataType::iterator t
= DataType::begin(); t
!= DataType::end(); ++t
) {
1539 PortSet::iterator i
= _ports
.begin(*t
);
1540 BufferSet::iterator b
= bufs
.begin(*t
);
1542 for (uint32_t off
= 0; off
< offset
.get(*t
); ++off
, ++b
) {
1543 if (b
== bufs
.end(*t
)) {
1548 for ( ; i
!= _ports
.end(*t
); ++i
, ++b
) {
1549 Buffer
& bb (i
->get_buffer (nframes
));
1550 b
->read_from (bb
, nframes
);
1556 IO::copy_to_outputs (BufferSet
& bufs
, DataType type
, pframes_t nframes
, framecnt_t offset
)
1558 // Copy any buffers 1:1 to outputs
1560 PortSet::iterator o
= _ports
.begin(type
);
1561 BufferSet::iterator i
= bufs
.begin(type
);
1562 BufferSet::iterator prev
= i
;
1564 while (i
!= bufs
.end(type
) && o
!= _ports
.end (type
)) {
1565 Buffer
& port_buffer (o
->get_buffer (nframes
));
1566 port_buffer
.read_from (*i
, nframes
, offset
);
1572 // Copy last buffer to any extra outputs
1574 while (o
!= _ports
.end(type
)) {
1575 Buffer
& port_buffer (o
->get_buffer (nframes
));
1576 port_buffer
.read_from (*prev
, nframes
, offset
);
1582 IO::port_by_name (const std::string
& str
) const
1584 /* to be called only from ::set_state() - no locking */
1586 for (PortSet::const_iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
1590 if (p
.name() == str
) {
1591 return const_cast<Port
*>(&p
);
1599 IO::physically_connected () const
1601 for (PortSet::const_iterator i
= _ports
.begin(); i
!= _ports
.end(); ++i
) {
1602 if (i
->physically_connected()) {
1611 IO::has_port (Port
* p
) const
1613 Glib::Mutex::Lock
lm (io_lock
);
1614 return _ports
.contains (p
);