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.
20 #include "ardour/port.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/i18n.h"
23 #include "pbd/failed_constructor.h"
24 #include "pbd/error.h"
25 #include "pbd/compose.h"
29 using namespace ARDOUR;
31 AudioEngine* Port::_engine = 0;
33 /** @param n Port short name */
34 Port::Port (std::string const & n, DataType t, Flags f, bool e)
36 , _last_monitor (false)
42 /* Unfortunately we have to pass the DataType into this constructor so that we can
43 create the right kind of JACK port; aside from this we'll use the virtual function type ()
47 assert (_name.find_first_of (':') == std::string::npos);
51 cerr << "NEW PORT " << _name << " ext = " << e << endl;
55 throw failed_constructor ();
60 /** Port destructor */
64 jack_port_unregister (_engine->jack (), _jack_port);
68 /** Make this port externally visible by setting it up to use a JACK port.
69 * @param t Data type, so that we can call this method from the constructor.
72 Port::do_make_external (DataType t)
75 /* already external */
79 if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
80 throw std::runtime_error ("Could not register JACK port");
85 Port::make_external ()
87 do_make_external (type ());
90 /** @return true if this port is connected to anything */
92 Port::connected () const
94 if (!_connections.empty ()) {
95 /* connected to a Port* */
99 if (_jack_port == 0) {
100 /* not using a JACK port, so can't be connected to anything else */
104 return (jack_port_connected (_jack_port) != 0);
107 /** @return true if this port is connected to anything via an external port */
109 Port::externally_connected () const
111 if (_jack_port == 0) {
112 /* not using a JACK port, so can't be connected to anything else */
116 return (jack_port_connected (_jack_port) != 0);
120 Port::disconnect_all ()
122 /* Disconnect from Port* connections */
123 for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
124 (*i)->_connections.erase (this);
127 _connections.clear ();
129 /* And JACK connections */
130 jack_port_disconnect (_engine->jack(), _jack_port);
131 _named_connections.clear ();
133 check_buffer_status ();
138 /** @param o Port name
139 * @return true if this port is connected to o, otherwise false.
142 Port::connected_to (std::string const & o) const
144 std::string const full = _engine->make_port_name_non_relative (o);
145 std::string const shrt = _engine->make_port_name_non_relative (o);
147 if (_jack_port && jack_port_connected_to (_jack_port, full.c_str ())) {
148 /* connected via JACK */
152 for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
153 if ((*i)->name () == shrt) {
154 /* connected internally */
162 /** @param o Filled in with port full names of ports that we are connected to */
164 Port::get_connections (std::vector<std::string> & c) const
168 /* JACK connections */
170 const char** jc = jack_port_get_connections (_jack_port);
172 for (int i = 0; jc[i]; ++i) {
179 /* Internal connections */
180 for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
181 std::string const full = _engine->make_port_name_non_relative ((*i)->name());
190 Port::connect (std::string const & other)
192 /* caller must hold process lock */
194 std::string const other_shrt = _engine->make_port_name_non_relative (other);
196 Port* p = _engine->get_port_by_name_locked (other_shrt);
200 if (p && !p->external ()) {
201 /* non-external Ardour port; connect using Port* */
204 /* connect using name */
206 /* for this to work, we must be an external port */
211 std::string const this_shrt = _engine->make_port_name_non_relative (_name);
213 if (sends_output ()) {
214 r = jack_connect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
216 r = jack_connect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str());
220 _named_connections.insert (other);
224 check_buffer_status ();
230 Port::disconnect (std::string const & other)
232 /* caller must hold process lock */
234 std::string const other_shrt = _engine->make_port_name_non_relative (other);
236 Port* p = _engine->get_port_by_name_locked (other_shrt);
239 if (p && !p->external ()) {
240 /* non-external Ardour port; disconnect using Port* */
243 /* disconnect using name */
245 std::string const this_shrt = _engine->make_port_name_non_relative (_name);
247 if (sends_output ()) {
248 r = jack_disconnect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
250 r = jack_disconnect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str ());
254 _named_connections.erase (other);
257 check_buffer_status ();
265 Port::connected_to (Port* o) const
267 return connected_to (o->name ());
271 Port::connect (Port* o)
273 /* caller must hold process lock */
275 if (external () && o->external ()) {
276 /* we're both external; connect using name */
277 return connect (o->name ());
280 /* otherwise connect by Port* */
281 _connections.insert (o);
282 o->_connections.insert (this);
284 check_buffer_status ();
285 o->check_buffer_status ();
291 Port::disconnect (Port* o)
293 if (external () && o->external ()) {
294 /* we're both external; try disconnecting using name */
295 int const r = disconnect (o->name ());
301 _connections.erase (o);
302 o->_connections.erase (this);
304 check_buffer_status ();
305 o->check_buffer_status ();
311 Port::set_engine (AudioEngine* e)
317 Port::ensure_monitor_input (bool yn)
320 jack_port_ensure_monitor (_jack_port, yn);
325 Port::monitoring_input () const
328 return jack_port_monitoring_input (_jack_port);
337 _last_monitor = false;
345 Port::recompute_total_latency () const
347 #ifdef HAVE_JACK_RECOMPUTE_LATENCY
349 jack_recompute_total_latency (_engine->jack (), _jack_port);
355 Port::total_latency () const
358 return jack_port_get_total_latency (_engine->jack (), _jack_port);
371 _jack_port = jack_port_register (_engine->jack(), _name.c_str(), type().to_jack_type(), _flags, 0);
373 if (_jack_port == 0) {
374 PBD::error << string_compose (_("could not reregister %1"), _name) << endmsg;
387 /* caller must hold process lock; intended to be used only after reestablish() */
393 for (std::set<string>::iterator i = _named_connections.begin(); i != _named_connections.end(); ++i) {
402 /** @param n Short name */
404 Port::set_name (std::string const & n)
406 assert (_name.find_first_of (':') == std::string::npos);
411 r = jack_port_set_name (_jack_port, n.c_str());
423 Port::set_latency (nframes_t n)
429 Port::request_monitor_input (bool yn)
432 jack_port_request_monitor (_jack_port, yn);
437 Port::check_buffer_status ()
439 if (external() && receives_input()) {
440 if (!externally_connected()) {
441 if (!_connections.empty()) {
443 /* There are no external connections, so the
444 external port buffer will be the silent buffer. We cannot write into it.
445 But we have to write somewhere because there is at least one internal
446 connection that is supplying us with data.
449 if (!using_internal_data()) {
450 use_internal_data ();
455 /* There are no external connections and no internal ones
456 either, so we can revert to use the externally supplied
457 buffer which will be silent (whatever the semantics of
458 that are for a particular data type.
461 if (using_internal_data()) {
462 use_external_data ();