2 Copyright (C) 2013 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 <io.h> // Microsoft's nearest equivalent to <unistd.h>
22 #include <ardourext/misc.h>
27 #include "pbd/convert.h"
28 #include "pbd/error.h"
30 #include "ardour/async_midi_port.h"
31 #include "ardour/audio_backend.h"
32 #include "ardour/audio_port.h"
33 #include "ardour/debug.h"
34 #include "ardour/midi_port.h"
35 #include "ardour/midiport_manager.h"
36 #include "ardour/port_manager.h"
37 #include "ardour/profile.h"
38 #include "ardour/session.h"
42 using namespace ARDOUR;
47 PortManager::PortManager ()
49 , _port_remove_in_progress (false)
50 , _port_deletions_pending (8192) /* ick, arbitrary sizing */
55 PortManager::clear_pending_port_deletions ()
59 while (_port_deletions_pending.read (&p, 1) == 1) {
65 PortManager::remove_all_ports ()
67 /* make sure that JACK callbacks that will be invoked as we cleanup
68 * ports know that they have nothing to do.
71 _port_remove_in_progress = true;
73 /* process lock MUST be held by caller
77 RCUWriter<Ports> writer (ports);
78 boost::shared_ptr<Ports> ps = writer.get_copy ();
82 /* clear dead wood list in RCU */
86 /* clear out pending port deletion list. we know this is safe because
87 * the auto connect thread in Session is already dead when this is
88 * done. It doesn't use shared_ptr<Port> anyway.
91 _port_deletions_pending.reset ();
93 _port_remove_in_progress = false;
98 PortManager::make_port_name_relative (const string& portname) const
104 string::size_type colon = portname.find (':');
106 if (colon == string::npos) {
110 if (portname.substr (0, colon) == _backend->my_name()) {
111 return portname.substr (colon+1);
118 PortManager::make_port_name_non_relative (const string& portname) const
122 if (portname.find_first_of (':') != string::npos) {
126 str = _backend->my_name();
134 PortManager::get_pretty_name_by_name(const std::string& portname) const
136 PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
140 if (0 == _backend->get_port_property (ph,
141 "http://jackaudio.org/metadata/pretty-name",
151 PortManager::port_is_mine (const string& portname) const
157 string self = _backend->my_name();
159 if (portname.find_first_of (':') != string::npos) {
160 if (portname.substr (0, self.length ()) != self) {
169 PortManager::port_is_physical (const std::string& portname) const
175 PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
180 return _backend->port_is_physical (ph);
184 PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
190 _backend->get_physical_outputs (type, s);
194 PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
201 _backend->get_physical_inputs (type, s);
205 PortManager::n_physical_outputs () const
208 return ChanCount::ZERO;
211 return _backend->n_physical_outputs ();
215 PortManager::n_physical_inputs () const
218 return ChanCount::ZERO;
220 return _backend->n_physical_inputs ();
223 /** @param name Full or short name of port
224 * @return Corresponding Port or 0.
227 boost::shared_ptr<Port>
228 PortManager::get_port_by_name (const string& portname)
231 return boost::shared_ptr<Port>();
234 if (!port_is_mine (portname)) {
235 /* not an ardour port */
236 return boost::shared_ptr<Port> ();
239 boost::shared_ptr<Ports> pr = ports.reader();
240 std::string rel = make_port_name_relative (portname);
241 Ports::iterator x = pr->find (rel);
243 if (x != pr->end()) {
244 /* its possible that the port was renamed by some 3rd party and
245 we don't know about it. check for this (the check is quick
246 and cheap), and if so, rename the port (which will alter
247 the port map as a side effect).
249 const std::string check = make_port_name_relative (_backend->get_port_name (x->second->port_handle()));
251 x->second->set_name (check);
256 return boost::shared_ptr<Port> ();
260 PortManager::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
262 RCUWriter<Ports> writer (ports);
263 boost::shared_ptr<Ports> p = writer.get_copy();
264 Ports::iterator x = p->find (old_relative_name);
267 boost::shared_ptr<Port> port = x->second;
269 p->insert (make_pair (new_relative_name, port));
274 PortManager::get_ports (DataType type, PortList& pl)
276 boost::shared_ptr<Ports> plist = ports.reader();
277 for (Ports::iterator p = plist->begin(); p != plist->end(); ++p) {
278 if (p->second->type() == type) {
279 pl.push_back (p->second);
286 PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
294 return _backend->get_ports (port_name_pattern, type, flags, s);
298 PortManager::port_registration_failure (const std::string& portname)
304 string full_portname = _backend->my_name();
305 full_portname += ':';
306 full_portname += portname;
309 PortEngine::PortHandle p = _backend->get_port_by_name (full_portname);
313 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
315 reason = string_compose (_("No more ports are available. You will need to stop %1 and restart with more ports if you need this many tracks."), PROGRAM_NAME);
318 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
323 void operator() (Port* p) {
324 AudioEngine::instance()->add_pending_port_deletion (p);
328 boost::shared_ptr<Port>
329 PortManager::register_port (DataType dtype, const string& portname, bool input, bool async, PortFlags flags)
331 boost::shared_ptr<Port> newport;
333 /* limit the possible flags that can be set */
335 flags = PortFlags (flags & (Hidden|Shadow|IsTerminal));
338 if (dtype == DataType::AUDIO) {
339 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
341 newport.reset (new AudioPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
343 } else if (dtype == DataType::MIDI) {
345 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
347 newport.reset (new AsyncMIDIPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
350 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
352 newport.reset (new MidiPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
356 throw PortRegistrationFailure("unable to create port (unknown type)");
359 RCUWriter<Ports> writer (ports);
360 boost::shared_ptr<Ports> ps = writer.get_copy ();
361 ps->insert (make_pair (make_port_name_relative (portname), newport));
363 /* writer goes out of scope, forces update */
367 catch (PortRegistrationFailure& err) {
369 } catch (std::exception& e) {
370 throw PortRegistrationFailure(string_compose(
371 _("unable to create port: %1"), e.what()).c_str());
373 throw PortRegistrationFailure("unable to create port (unknown error)");
376 DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
380 boost::shared_ptr<Port>
381 PortManager::register_input_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
383 return register_port (type, portname, true, async, extra_flags);
386 boost::shared_ptr<Port>
387 PortManager::register_output_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
389 return register_port (type, portname, false, async, extra_flags);
393 PortManager::unregister_port (boost::shared_ptr<Port> port)
395 /* This is a little subtle. We do not call the backend's port
396 * unregistration code from here. That is left for the Port
397 * destructor. We are trying to drop references to the Port object
398 * here, so that its destructor will run and it will unregister itself.
401 /* caller must hold process lock */
404 RCUWriter<Ports> writer (ports);
405 boost::shared_ptr<Ports> ps = writer.get_copy ();
406 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
408 if (x != ps->end()) {
412 /* writer goes out of scope, forces update */
421 PortManager::connected (const string& port_name)
427 PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
433 return _backend->connected (handle);
437 PortManager::physically_connected (const string& port_name)
443 PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
449 return _backend->physically_connected (handle);
453 PortManager::get_connections (const string& port_name, std::vector<std::string>& s)
460 PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
467 return _backend->get_connections (handle, s);
471 PortManager::connect (const string& source, const string& destination)
475 string s = make_port_name_non_relative (source);
476 string d = make_port_name_non_relative (destination);
478 boost::shared_ptr<Port> src = get_port_by_name (s);
479 boost::shared_ptr<Port> dst = get_port_by_name (d);
482 ret = src->connect (d);
484 ret = dst->connect (s);
486 /* neither port is known to us ...hand-off to the PortEngine
489 ret = _backend->connect (s, d);
496 /* already exists - no error, no warning */
497 } else if (ret < 0) {
498 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
499 source, s, destination, d)
507 PortManager::disconnect (const string& source, const string& destination)
511 string s = make_port_name_non_relative (source);
512 string d = make_port_name_non_relative (destination);
514 boost::shared_ptr<Port> src = get_port_by_name (s);
515 boost::shared_ptr<Port> dst = get_port_by_name (d);
518 ret = src->disconnect (d);
520 ret = dst->disconnect (s);
522 /* neither port is known to us ...hand-off to the PortEngine
525 ret = _backend->disconnect (s, d);
534 PortManager::disconnect (boost::shared_ptr<Port> port)
536 return port->disconnect_all ();
540 PortManager::reestablish_ports ()
544 boost::shared_ptr<Ports> p = ports.reader ();
546 DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
548 for (i = p->begin(); i != p->end(); ++i) {
549 if (i->second->reestablish ()) {
550 error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
551 std::cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << std::endl;
566 PortManager::reconnect_ports ()
568 boost::shared_ptr<Ports> p = ports.reader ();
570 if (!Profile->get_trx()) {
571 /* re-establish connections */
573 DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
575 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
576 i->second->reconnect ();
584 PortManager::connect_callback (const string& a, const string& b, bool conn)
586 boost::shared_ptr<Port> port_a;
587 boost::shared_ptr<Port> port_b;
589 boost::shared_ptr<Ports> pr = ports.reader ();
591 x = pr->find (make_port_name_relative (a));
592 if (x != pr->end()) {
596 x = pr->find (make_port_name_relative (b));
597 if (x != pr->end()) {
601 PortConnectedOrDisconnected (
609 PortManager::registration_callback ()
611 if (!_port_remove_in_progress) {
612 PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
617 PortManager::can_request_input_monitoring () const
623 return _backend->can_monitor_input ();
627 PortManager::request_input_monitoring (const string& name, bool yn) const
633 PortEngine::PortHandle ph = _backend->get_port_by_name (name);
636 _backend->request_input_monitoring (ph, yn);
641 PortManager::ensure_input_monitoring (const string& name, bool yn) const
647 PortEngine::PortHandle ph = _backend->get_port_by_name (name);
650 _backend->ensure_input_monitoring (ph, yn);
655 PortManager::port_name_size() const
661 return _backend->port_name_size ();
665 PortManager::my_name() const
671 return _backend->my_name();
675 PortManager::graph_order_callback ()
677 if (!_port_remove_in_progress) {
678 GraphReordered(); /* EMIT SIGNAL */
685 PortManager::cycle_start (pframes_t nframes)
687 Port::set_global_port_buffer_offset (0);
688 Port::set_cycle_framecnt (nframes);
690 _cycle_ports = ports.reader ();
692 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
693 p->second->cycle_start (nframes);
698 PortManager::cycle_end (pframes_t nframes)
700 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
701 p->second->cycle_end (nframes);
704 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
705 p->second->flush_buffers (nframes);
708 _cycle_ports.reset ();
714 PortManager::silence (pframes_t nframes, Session *s)
716 for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
717 if (s && i->second == s->mtc_output_port ()) {
720 if (s && i->second == s->midi_clock_output_port ()) {
723 if (s && i->second == s->ltc_output_port ()) {
726 if (boost::dynamic_pointer_cast<AsyncMIDIPort>(i->second)) {
729 if (i->second->sends_output()) {
730 i->second->get_buffer(nframes).silence(nframes);
736 PortManager::silence_outputs (pframes_t nframes)
738 std::vector<std::string> port_names;
739 if (get_ports("", DataType::AUDIO, IsOutput, port_names)) {
740 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
741 if (!port_is_mine(*p)) {
744 PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
748 void *buf = _backend->get_buffer(ph, nframes);
752 memset (buf, 0, sizeof(float) * nframes);
756 if (get_ports("", DataType::MIDI, IsOutput, port_names)) {
757 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
758 if (!port_is_mine(*p)) {
761 PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
765 void *buf = _backend->get_buffer(ph, nframes);
769 _backend->midi_clear (buf);
775 PortManager::check_monitoring ()
777 for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
781 if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
782 i->second->set_last_monitor (x);
783 /* XXX I think this is dangerous, due to
784 a likely mutex in the signal handlers ...
786 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
792 PortManager::fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes)
794 for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
796 if (i->second->sends_output()) {
798 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
800 Sample* s = ap->engine_get_whole_audio_buffer ();
801 gain_t g = base_gain;
803 for (pframes_t n = 0; n < nframes; ++n) {
813 PortManager::port_engine()
820 PortManager::port_is_control_only (std::string const& name)
822 static regex_t compiled_pattern;
823 static string pattern;
825 if (pattern.empty()) {
827 /* This is a list of regular expressions that match ports
828 * related to physical MIDI devices that we do not want to
829 * expose as normal physical ports.
832 const char * const control_only_ports[] = {
833 X_(".*Ableton Push.*"),
834 X_(".*FaderPort .*"),
838 for (size_t n = 0; n < sizeof (control_only_ports)/sizeof (control_only_ports[0]); ++n) {
842 pattern += control_only_ports[n];
846 regcomp (&compiled_pattern, pattern.c_str(), REG_EXTENDED|REG_NOSUB);
849 return regexec (&compiled_pattern, name.c_str(), 0, 0, 0) == 0;