mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
adjust generic MIDI surface support to (1) properly use boost::shared_ptr<Port> (2) detect connection changes
This commit is contained in:
parent
2f48997dfb
commit
3d79e3c116
3 changed files with 101 additions and 11 deletions
|
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
|
|
||||||
|
#include "ardour/async_midi_port.h"
|
||||||
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/filesystem_paths.h"
|
#include "ardour/filesystem_paths.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
|
@ -58,12 +60,13 @@ using namespace std;
|
||||||
|
|
||||||
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||||
: ControlProtocol (s, _("Generic MIDI"))
|
: ControlProtocol (s, _("Generic MIDI"))
|
||||||
|
, connection_state (ConnectionState (0))
|
||||||
, _motorised (false)
|
, _motorised (false)
|
||||||
, _threshold (10)
|
, _threshold (10)
|
||||||
, gui (0)
|
, gui (0)
|
||||||
{
|
{
|
||||||
_input_port = s.midi_input_port ();
|
_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort> (s.midi_input_port ());
|
||||||
_output_port = s.midi_output_port ();
|
_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort> (s.midi_output_port ());
|
||||||
|
|
||||||
do_feedback = false;
|
do_feedback = false;
|
||||||
_feedback_interval = 10000; // microseconds
|
_feedback_interval = 10000; // microseconds
|
||||||
|
|
@ -94,6 +97,11 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||||
|
|
||||||
Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
|
Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
|
||||||
|
|
||||||
|
/* Catch port connections and disconnections (cross-thread) */
|
||||||
|
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR,
|
||||||
|
boost::bind (&GenericMidiControlProtocol::connection_handler, this, _1, _2, _3, _4, _5),
|
||||||
|
midi_ui_context());
|
||||||
|
|
||||||
reload_maps ();
|
reload_maps ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +237,9 @@ GenericMidiControlProtocol::drop_bindings ()
|
||||||
int
|
int
|
||||||
GenericMidiControlProtocol::set_active (bool /*yn*/)
|
GenericMidiControlProtocol::set_active (bool /*yn*/)
|
||||||
{
|
{
|
||||||
/* start/stop delivery/outbound thread */
|
/* nothing to do here: the MIDI UI thread in libardour handles all our
|
||||||
|
I/O needs.
|
||||||
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1137,3 +1147,67 @@ GenericMidiControlProtocol::set_threshold (int t)
|
||||||
{
|
{
|
||||||
_threshold = t;
|
_threshold = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GenericMidiControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
|
||||||
|
{
|
||||||
|
if (!_input_port || !_output_port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_input_port)->name());
|
||||||
|
string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_output_port)->name());
|
||||||
|
|
||||||
|
if (ni == name1 || ni == name2) {
|
||||||
|
if (yn) {
|
||||||
|
connection_state |= InputConnected;
|
||||||
|
} else {
|
||||||
|
connection_state &= ~InputConnected;
|
||||||
|
}
|
||||||
|
} else if (no == name1 || no == name2) {
|
||||||
|
if (yn) {
|
||||||
|
connection_state |= OutputConnected;
|
||||||
|
} else {
|
||||||
|
connection_state &= ~OutputConnected;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* not our ports */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
|
||||||
|
|
||||||
|
/* XXX this is a horrible hack. Without a short sleep here,
|
||||||
|
something prevents the device wakeup messages from being
|
||||||
|
sent and/or the responses from being received.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_usleep (100000);
|
||||||
|
connected ();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionChange (); /* emit signal for our GUI */
|
||||||
|
|
||||||
|
return true; /* connection status changed */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GenericMidiControlProtocol::connected ()
|
||||||
|
{
|
||||||
|
cerr << "Now connected\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Port>
|
||||||
|
GenericMidiControlProtocol::output_port() const
|
||||||
|
{
|
||||||
|
return _output_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Port>
|
||||||
|
GenericMidiControlProtocol::input_port() const
|
||||||
|
{
|
||||||
|
return _input_port;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,9 @@ namespace PBD {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class Session;
|
class AsyncMIDIPort;
|
||||||
class MidiPort;
|
class MidiPort;
|
||||||
|
class Session;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
@ -54,8 +55,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
int set_active (bool yn);
|
int set_active (bool yn);
|
||||||
static bool probe() { return true; }
|
static bool probe() { return true; }
|
||||||
|
|
||||||
ARDOUR::Port* input_port () const { return ((ARDOUR::Port*) _input_port); }
|
boost::shared_ptr<ARDOUR::Port> input_port () const;
|
||||||
ARDOUR::Port* output_port () const { return ((ARDOUR::Port*) _output_port); }
|
boost::shared_ptr<ARDOUR::Port> output_port () const;
|
||||||
|
|
||||||
void set_feedback_interval (ARDOUR::microseconds_t);
|
void set_feedback_interval (ARDOUR::microseconds_t);
|
||||||
|
|
||||||
|
|
@ -103,9 +104,11 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
PBD::Signal0<void> ConnectionChange;
|
PBD::Signal0<void> ConnectionChange;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MIDI::Port* _input_port;
|
boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
|
||||||
MIDI::Port* _output_port;
|
boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
|
||||||
|
|
||||||
ARDOUR::microseconds_t _feedback_interval;
|
ARDOUR::microseconds_t _feedback_interval;
|
||||||
ARDOUR::microseconds_t last_feedback_time;
|
ARDOUR::microseconds_t last_feedback_time;
|
||||||
|
|
||||||
|
|
@ -143,6 +146,16 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
void reset_controllables ();
|
void reset_controllables ();
|
||||||
void drop_all ();
|
void drop_all ();
|
||||||
|
|
||||||
|
enum ConnectionState {
|
||||||
|
InputConnected = 0x1,
|
||||||
|
OutputConnected = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
|
int connection_state;
|
||||||
|
bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
|
||||||
|
PBD::ScopedConnection port_connection;
|
||||||
|
void connected();
|
||||||
|
|
||||||
std::string _current_binding;
|
std::string _current_binding;
|
||||||
uint32_t _bank_size;
|
uint32_t _bank_size;
|
||||||
uint32_t _current_bank;
|
uint32_t _current_bank;
|
||||||
|
|
@ -156,6 +169,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
|
|
||||||
mutable void *gui;
|
mutable void *gui;
|
||||||
void build_gui ();
|
void build_gui ();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ardour_generic_midi_control_protocol_h */
|
#endif /* ardour_generic_midi_control_protocol_h */
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ GMCPGUI::GMCPGUI (GenericMidiControlProtocol& p)
|
||||||
, motorised_button ("Motorised")
|
, motorised_button ("Motorised")
|
||||||
, threshold_adjustment (p.threshold(), 1, 127, 1, 10)
|
, threshold_adjustment (p.threshold(), 1, 127, 1, 10)
|
||||||
, threshold_spinner (threshold_adjustment)
|
, threshold_spinner (threshold_adjustment)
|
||||||
|
, ignore_active_change (false)
|
||||||
{
|
{
|
||||||
vector<string> popdowns;
|
vector<string> popdowns;
|
||||||
popdowns.push_back (_("Reset All"));
|
popdowns.push_back (_("Reset All"));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue