2 Copyright (C) 2009 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.
21 #include "libardour-config.h"
24 #include "ardour/port.h"
25 #include "ardour/audioengine.h"
26 #include "pbd/failed_constructor.h"
27 #include "pbd/error.h"
28 #include "pbd/compose.h"
34 using namespace ARDOUR
;
36 AudioEngine
* Port::_engine
= 0;
37 pframes_t
Port::_buffer_size
= 0;
38 bool Port::_connecting_blocked
= false;
40 /** @param n Port short name */
41 Port::Port (std::string
const & n
, DataType t
, Flags f
)
42 : _last_monitor (false)
47 /* Unfortunately we have to pass the DataType into this constructor so that we can
48 create the right kind of JACK port; aside from this we'll use the virtual function type ()
52 assert (_name
.find_first_of (':') == std::string::npos
);
54 if (!_engine
->connected()) {
55 throw failed_constructor ();
58 if ((_jack_port
= jack_port_register (_engine
->jack (), _name
.c_str (), t
.to_jack_type (), _flags
, 0)) == 0) {
59 cerr
<< "Failed to register JACK port, reason is unknown from here\n";
60 throw failed_constructor ();
64 /** Port destructor */
67 if (_engine
->jack ()) {
68 jack_port_unregister (_engine
->jack (), _jack_port
);
72 /** @return true if this port is connected to anything */
74 Port::connected () const
76 return (jack_port_connected (_jack_port
) != 0);
80 Port::disconnect_all ()
82 jack_port_disconnect (_engine
->jack(), _jack_port
);
83 _connections
.clear ();
88 /** @param o Port name
89 * @return true if this port is connected to o, otherwise false.
92 Port::connected_to (std::string
const & o
) const
94 if (!_engine
->connected()) {
95 /* in some senses, this answer isn't the right one all the time,
96 because we know about our connections and will re-establish
97 them when we reconnect to JACK.
102 return jack_port_connected_to (_jack_port
, _engine
->make_port_name_non_relative(o
).c_str ());
105 /** @param o Filled in with port full names of ports that we are connected to */
107 Port::get_connections (std::vector
<std::string
> & c
) const
111 if (_engine
->connected()) {
112 const char** jc
= jack_port_get_connections (_jack_port
);
114 for (int i
= 0; jc
[i
]; ++i
) {
127 Port::connect (std::string
const & other
)
129 std::string
const other_shrt
= _engine
->make_port_name_non_relative (other
);
130 std::string
const this_shrt
= _engine
->make_port_name_non_relative (_name
);
134 if (_connecting_blocked
) {
138 if (sends_output ()) {
139 r
= jack_connect (_engine
->jack (), this_shrt
.c_str (), other_shrt
.c_str ());
141 r
= jack_connect (_engine
->jack (), other_shrt
.c_str (), this_shrt
.c_str());
145 _connections
.insert (other
);
152 Port::disconnect (std::string
const & other
)
154 std::string
const other_shrt
= _engine
->make_port_name_non_relative (other
);
155 std::string
const this_shrt
= _engine
->make_port_name_non_relative (_name
);
159 if (sends_output ()) {
160 r
= jack_disconnect (_engine
->jack (), this_shrt
.c_str (), other_shrt
.c_str ());
162 r
= jack_disconnect (_engine
->jack (), other_shrt
.c_str (), this_shrt
.c_str ());
166 _connections
.erase (other
);
174 Port::connected_to (Port
* o
) const
176 return connected_to (o
->name ());
180 Port::connect (Port
* o
)
182 return connect (o
->name ());
186 Port::disconnect (Port
* o
)
188 return disconnect (o
->name ());
192 Port::set_engine (AudioEngine
* e
)
198 Port::ensure_monitor_input (bool yn
)
200 jack_port_ensure_monitor (_jack_port
, yn
);
204 Port::monitoring_input () const
206 return jack_port_monitoring_input (_jack_port
);
212 _last_monitor
= false;
220 Port::recompute_total_latency () const
222 #ifdef HAVE_JACK_RECOMPUTE_LATENCY
223 jack_client_t
* jack
= _engine
->jack();
229 jack_recompute_total_latency (jack
, _jack_port
);
234 Port::total_latency () const
236 jack_client_t
* jack
= _engine
->jack();
242 return jack_port_get_total_latency (jack
, _jack_port
);
248 jack_client_t
* jack
= _engine
->jack();
254 cerr
<< "RE-REGISTER: " << _name
.c_str() << endl
;
255 _jack_port
= jack_port_register (jack
, _name
.c_str(), type().to_jack_type(), _flags
, 0);
257 if (_jack_port
== 0) {
258 PBD::error
<< string_compose (_("could not reregister %1"), _name
) << endmsg
;
271 /* caller must hold process lock; intended to be used only after reestablish() */
273 for (std::set
<string
>::iterator i
= _connections
.begin(); i
!= _connections
.end(); ++i
) {
282 /** @param n Short port name (no JACK client name) */
284 Port::set_name (std::string
const & n
)
290 int const r
= jack_port_set_name (_jack_port
, n
.c_str());
300 Port::request_monitor_input (bool yn
)
302 jack_port_request_monitor (_jack_port
, yn
);
306 Port::set_latency (framecnt_t n
)
308 jack_port_set_latency (_jack_port
, n
);
312 Port::physically_connected () const
314 const char** jc
= jack_port_get_connections (_jack_port
);
317 for (int i
= 0; jc
[i
]; ++i
) {
319 jack_port_t
* port
= jack_port_by_name (_engine
->jack(), jc
[i
]);
321 if (port
&& (jack_port_flags (port
) & JackPortIsPhysical
)) {