mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
Fix JACK-MIDI monitoring when hotplugging devices
During initial setup, PortManager::reestablish_ports(),
the jack client is not yet active and port_connect failed:
"Cannot connect ports owned by inactive clients".
Later hotplugged devices were likewise not connected because
"JACK: Cannot callback the server in notification thread!"
see also 2007bf2d5f
This commit is contained in:
parent
84b75f6627
commit
07d7e0bf54
1 changed files with 48 additions and 6 deletions
|
|
@ -784,11 +784,17 @@ PortManager::reconnect_ports ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config->get_work_around_jack_no_copy_optimization () && AudioEngine::instance()->current_backend_name() == X_("JACK")) {
|
if (Config->get_work_around_jack_no_copy_optimization () && AudioEngine::instance()->current_backend_name() == X_("JACK")) {
|
||||||
std::string const our_name = AudioEngine::instance()->make_port_name_non_relative (X_("physical_audio_input_monitor_enable"));
|
std::string const audio_port = AudioEngine::instance()->make_port_name_non_relative (X_("physical_audio_input_monitor_enable"));
|
||||||
|
std::string const midi_port = AudioEngine::instance()->make_port_name_non_relative (X_("physical_midi_input_monitor_enable"));
|
||||||
std::vector<std::string> audio_ports;
|
std::vector<std::string> audio_ports;
|
||||||
|
std::vector<std::string> midi_ports;
|
||||||
get_physical_inputs (DataType::AUDIO, audio_ports);
|
get_physical_inputs (DataType::AUDIO, audio_ports);
|
||||||
|
get_physical_inputs (DataType::MIDI, midi_ports);
|
||||||
for (std::vector<std::string>::iterator p = audio_ports.begin(); p != audio_ports.end(); ++p) {
|
for (std::vector<std::string>::iterator p = audio_ports.begin(); p != audio_ports.end(); ++p) {
|
||||||
port_engine().connect (*p, our_name);
|
port_engine().connect (*p, audio_port);
|
||||||
|
}
|
||||||
|
for (std::vector<std::string>::iterator p = midi_ports.begin(); p != midi_ports.end(); ++p) {
|
||||||
|
port_engine().connect (*p, midi_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,6 +856,26 @@ PortManager::registration_callback ()
|
||||||
PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
|
PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MIDIConnectCall {
|
||||||
|
MIDIConnectCall (std::vector<std::string> const& pl)
|
||||||
|
: port_list (pl)
|
||||||
|
{}
|
||||||
|
std::vector<std::string> port_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void*
|
||||||
|
_midi_connect (void *arg)
|
||||||
|
{
|
||||||
|
MIDIConnectCall* mcl = static_cast<MIDIConnectCall*> (arg);
|
||||||
|
std::string const our_name = AudioEngine::instance()->make_port_name_non_relative (X_("physical_midi_input_monitor_enable"));
|
||||||
|
|
||||||
|
for (vector<string>::const_iterator p = mcl->port_list.begin (); p != mcl->port_list.end (); ++p) {
|
||||||
|
AudioEngine::instance()->connect (*p, our_name);
|
||||||
|
}
|
||||||
|
delete mcl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PortManager::update_input_ports (bool clear)
|
PortManager::update_input_ports (bool clear)
|
||||||
{
|
{
|
||||||
|
|
@ -930,6 +956,8 @@ PortManager::update_input_ports (bool clear)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> physical_midi_connection_list;
|
||||||
|
|
||||||
if (!new_midi.empty () || !old_midi.empty () || clear) {
|
if (!new_midi.empty () || !old_midi.empty () || clear) {
|
||||||
RCUWriter<MIDIInputPorts> mpwr (_midi_input_ports);
|
RCUWriter<MIDIInputPorts> mpwr (_midi_input_ports);
|
||||||
boost::shared_ptr<MIDIInputPorts> mpw = mpwr.get_copy ();
|
boost::shared_ptr<MIDIInputPorts> mpw = mpwr.get_copy ();
|
||||||
|
|
@ -952,17 +980,31 @@ PortManager::update_input_ports (bool clear)
|
||||||
mpw->insert (make_pair (*p, MIDIInputPort (32)));
|
mpw->insert (make_pair (*p, MIDIInputPort (32)));
|
||||||
|
|
||||||
if (Config->get_work_around_jack_no_copy_optimization () && AudioEngine::instance()->current_backend_name() == X_("JACK")) {
|
if (Config->get_work_around_jack_no_copy_optimization () && AudioEngine::instance()->current_backend_name() == X_("JACK")) {
|
||||||
std::string const our_name = AudioEngine::instance()->make_port_name_non_relative (X_("physical_midi_input_monitor_enable"));
|
physical_midi_connection_list.push_back (*p);
|
||||||
port_engine().connect (*p, our_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
/* don't send notifcation for initial setup */
|
/* don't send notifcation for initial setup.
|
||||||
|
* Physical I/O is initially connected in
|
||||||
|
* reconnect_ports(), it is too early to
|
||||||
|
* do this when called from ::reestablish_ports()
|
||||||
|
* "JACK: Cannot connect ports owned by inactive clients"
|
||||||
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!physical_midi_connection_list.empty ()) {
|
||||||
|
/* handle hotplug, connect in bg thread, because
|
||||||
|
* "JACK: Cannot callback the server in notification thread!"
|
||||||
|
*/
|
||||||
|
pthread_t thread;
|
||||||
|
MIDIConnectCall* mcl = new MIDIConnectCall (physical_midi_connection_list);
|
||||||
|
pthread_create_and_store ("midi-connect", &thread, _midi_connect, mcl);
|
||||||
|
pthread_detach (thread);
|
||||||
|
}
|
||||||
|
|
||||||
if (!old_audio.empty ()) {
|
if (!old_audio.empty ()) {
|
||||||
PhysInputChanged (DataType::AUDIO, old_audio, false);
|
PhysInputChanged (DataType::AUDIO, old_audio, false);
|
||||||
}
|
}
|
||||||
|
|
@ -1843,7 +1885,7 @@ PortManager::run_input_meters (pframes_t n_samples, samplecnt_t rate)
|
||||||
assert (!port_is_mine (p->first));
|
assert (!port_is_mine (p->first));
|
||||||
|
|
||||||
PortEngine::PortHandle ph = _backend->get_port_by_name (p->first);
|
PortEngine::PortHandle ph = _backend->get_port_by_name (p->first);
|
||||||
if (!ph) {
|
if (!ph || !_backend->connected (ph)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue