summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-07-05 15:41:05 +0000
committerCarl Hetherington <carl@carlh.net>2010-07-05 15:41:05 +0000
commitdf2298c846527e71a794b957baec7684fabe46aa (patch)
tree89bf7f9dc9ba0fe050679fa8b05209c451063d74
parentc686dee0cee50b09f6c0eda3240b85dee1eaff8f (diff)
Reestablish libmidi++ JACK ports on jack reconnection, so that control MIDI can still be sent after a JACK disconnect/reconnect. Fixes remainder of #3301.
git-svn-id: svn://localhost/ardour2/branches/3.0@7373 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/audioengine.cc5
-rw-r--r--libs/midi++2/jack_midiport.cc43
-rw-r--r--libs/midi++2/manager.cc18
-rw-r--r--libs/midi++2/midi++/jack.h6
-rw-r--r--libs/midi++2/midi++/manager.h3
-rw-r--r--libs/midi++2/midi++/port.h3
6 files changed, 71 insertions, 7 deletions
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 0058acc7e2..b9ec8e465b 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -34,6 +34,7 @@
#include "midi++/jack.h"
#include "midi++/mmc.h"
+#include "midi++/manager.h"
#include "ardour/amp.h"
#include "ardour/audio_port.h"
@@ -1395,6 +1396,8 @@ AudioEngine::reconnect_to_jack ()
GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
+ MIDI::Manager::instance()->reestablish (_priv_jack);
+
if (_session) {
_session->reset_jack_connection (_priv_jack);
jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
@@ -1435,6 +1438,8 @@ AudioEngine::reconnect_to_jack ()
(*i)->reconnect ();
}
+ MIDI::Manager::instance()->reconnect ();
+
Running (); /* EMIT SIGNAL*/
start_metering_thread ();
diff --git a/libs/midi++2/jack_midiport.cc b/libs/midi++2/jack_midiport.cc
index 07b044f077..b55cf3adf6 100644
--- a/libs/midi++2/jack_midiport.cc
+++ b/libs/midi++2/jack_midiport.cc
@@ -268,13 +268,26 @@ JACK_MidiPort::create_ports(const XMLNode& node)
assert(!_jack_input_port);
assert(!_jack_output_port);
- jack_nframes_t nframes = jack_get_buffer_size(_jack_client);
+ if (desc.mode == O_RDWR || desc.mode == O_WRONLY) {
+ _jack_output_port_name = string(desc.tag).append ("_out");
+ }
+
+ if (desc.mode == O_RDWR || desc.mode == O_RDONLY) {
+ _jack_input_port_name = string(desc.tag).append ("_in");
+ }
+ return create_ports ();
+}
+
+int
+JACK_MidiPort::create_ports ()
+{
bool ret = true;
- if (desc.mode == O_RDWR || desc.mode == O_WRONLY) {
- _jack_output_port = jack_port_register(_jack_client,
- string(desc.tag).append("_out").c_str(),
+ jack_nframes_t nframes = jack_get_buffer_size(_jack_client);
+
+ if (!_jack_output_port_name.empty()) {
+ _jack_output_port = jack_port_register(_jack_client, _jack_output_port_name.c_str(),
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
if (_jack_output_port) {
jack_midi_clear_buffer(jack_port_get_buffer(_jack_output_port, nframes));
@@ -282,9 +295,8 @@ JACK_MidiPort::create_ports(const XMLNode& node)
ret = ret && (_jack_output_port != NULL);
}
- if (desc.mode == O_RDWR || desc.mode == O_RDONLY) {
- _jack_input_port = jack_port_register(_jack_client,
- string(desc.tag).append("_in").c_str(),
+ if (!_jack_input_port_name.empty()) {
+ _jack_input_port = jack_port_register(_jack_client, _jack_input_port_name.c_str(),
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
if (_jack_input_port) {
jack_midi_clear_buffer(jack_port_get_buffer(_jack_input_port, nframes));
@@ -402,3 +414,20 @@ JACK_MidiPort::is_process_thread()
{
return (pthread_self() == _process_thread);
}
+
+void
+JACK_MidiPort::reestablish (void* jack)
+{
+ _jack_client = static_cast<jack_client_t*> (jack);
+ int const r = create_ports ();
+
+ if (r) {
+ PBD::error << "could not reregister ports for " << name() << endmsg;
+ }
+}
+
+void
+JACK_MidiPort::reconnect ()
+{
+ make_connections ();
+}
diff --git a/libs/midi++2/manager.cc b/libs/midi++2/manager.cc
index ffc8f4e1bc..a84b5ab68a 100644
--- a/libs/midi++2/manager.cc
+++ b/libs/midi++2/manager.cc
@@ -234,3 +234,21 @@ Manager::get_known_ports (vector<PortSet>& ports)
{
return PortFactory::get_known_ports (ports);
}
+
+/** Re-register ports that disappear on JACK shutdown */
+void
+Manager::reestablish (void* a)
+{
+ for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ (*p)->reestablish (a);
+ }
+}
+
+/** Re-connect ports after a reestablish () */
+void
+Manager::reconnect ()
+{
+ for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p) {
+ (*p)->reconnect ();
+ }
+}
diff --git a/libs/midi++2/midi++/jack.h b/libs/midi++2/midi++/jack.h
index 0433e4ae45..099bc4e639 100644
--- a/libs/midi++2/midi++/jack.h
+++ b/libs/midi++2/midi++/jack.h
@@ -71,6 +71,9 @@ public:
nframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
+ void reestablish (void *);
+ void reconnect ();
+
static PBD::Signal0<void> MakeConnections;
static PBD::Signal0<void> JackHalted;
@@ -81,9 +84,12 @@ public:
private:
int create_ports(const XMLNode&);
+ int create_ports ();
jack_client_t* _jack_client;
+ std::string _jack_input_port_name; /// input port name, or empty if there isn't one
jack_port_t* _jack_input_port;
+ std::string _jack_output_port_name; /// output port name, or empty if there isn't one
jack_port_t* _jack_output_port;
nframes_t _last_read_index;
timestamp_t _last_write_timestamp;
diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h
index 90bdde3e70..33835a05bf 100644
--- a/libs/midi++2/midi++/manager.h
+++ b/libs/midi++2/midi++/manager.h
@@ -83,6 +83,9 @@ class Manager {
int get_known_ports (std::vector<PortSet>&);
+ void reestablish (void *);
+ void reconnect ();
+
PBD::Signal0<void> PortsChanged;
private:
diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h
index 16db09f0e4..c45f5ba2fc 100644
--- a/libs/midi++2/midi++/port.h
+++ b/libs/midi++2/midi++/port.h
@@ -157,6 +157,9 @@ class Port {
XMLNode& get_state();
};
+ virtual void reestablish (void *) {}
+ virtual void reconnect () {}
+
protected:
bool _ok;
bool _currently_in_cycle;