13
0

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
This commit is contained in:
Carl Hetherington 2010-07-05 15:41:05 +00:00
parent c686dee0ce
commit df2298c846
6 changed files with 71 additions and 7 deletions

View File

@ -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 ();

View File

@ -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 ();
}

View File

@ -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 ();
}
}

View File

@ -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;

View File

@ -83,6 +83,9 @@ class Manager {
int get_known_ports (std::vector<PortSet>&);
void reestablish (void *);
void reconnect ();
PBD::Signal0<void> PortsChanged;
private:

View File

@ -157,6 +157,9 @@ class Port {
XMLNode& get_state();
};
virtual void reestablish (void *) {}
virtual void reconnect () {}
protected:
bool _ok;
bool _currently_in_cycle;