summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-12-06 16:32:53 +0100
committerRobin Gareus <robin@gareus.org>2017-12-06 16:33:58 +0100
commit561c8eea0cfa45f0b54461b149b4c330e0bbaa3b (patch)
tree5cdf7b34175f5c774c19b7a4cffe2cc55c7cd333
parentab5be61f51523197818d7215cc022c100e764a3a (diff)
Prototype to allow embedding sysex in midi-map
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc44
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h2
2 files changed, 45 insertions, 1 deletions
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 4d394e5082..d973ba77b6 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -42,6 +42,7 @@
#include "ardour/session.h"
#include "ardour/midi_ui.h"
#include "ardour/rc_configuration.h"
+#include "ardour/raw_midi_parser.h"
#include "ardour/midiport_manager.h"
#include "ardour/debug.h"
@@ -241,6 +242,8 @@ GenericMidiControlProtocol::drop_all ()
delete *i;
}
actions.clear ();
+
+ _sysex_init = "";
}
void
@@ -266,6 +269,7 @@ GenericMidiControlProtocol::drop_bindings ()
_current_binding = "";
_bank_size = 0;
_current_bank = 0;
+ _sysex_init = "";
}
int
@@ -720,7 +724,7 @@ GenericMidiControlProtocol::load_bindings (const string& xmlpath)
DEBUG_TRACE (DEBUG::GenericMidi, "Load bindings: Reading midi map\n");
XMLTree state_tree;
- if (!state_tree.read (xmlpath.c_str())) {
+ if (!state_tree.read (xmlpath)) {
error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
return -1;
}
@@ -792,12 +796,25 @@ GenericMidiControlProtocol::load_bindings (const string& xmlpath)
}
}
}
+
+ if ((*citer)->name() == "Sysex") {
+ for (XMLNodeList::const_iterator n = (*citer)->children ().begin (); n != (*citer)->children ().end (); ++n) {
+ if (!(*n)->is_content ()) { continue; }
+ _sysex_init = (*n)->content ();
+ break;
+ }
+ }
+
}
if ((prop = root->property ("name")) != 0) {
_current_binding = prop->value ();
}
+ if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
+
+ send_sysex_init ();
+ }
reset_controllables ();
return 0;
@@ -1221,6 +1238,31 @@ void
GenericMidiControlProtocol::connected ()
{
cerr << "Now connected\n";
+ send_sysex_init ();
+}
+
+void
+GenericMidiControlProtocol::send_sysex_init ()
+{
+ if (_sysex_init.empty ()) {
+ return;
+ }
+
+ boost::shared_ptr<AsyncMIDIPort> p = boost::dynamic_pointer_cast<AsyncMIDIPort> (_output_port);
+ assert (p);
+
+ gsize size = 0;
+ guchar* buf = g_base64_decode (_sysex_init.c_str(), &size);
+
+ RawMidiParser mp;
+ for (size_t i = 0; i < size; ++i) {
+ if (mp.process_byte (buf[i])) {
+ p->write (mp.midi_buffer (), mp.buffer_size (), 0);
+ /* delay for physical MIDI rate; 320usec / byte */
+ g_usleep (400 * mp.buffer_size ());
+ }
+ }
+ g_free (buf);
}
boost::shared_ptr<Port>
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
index 6585c7ea24..8a2670bfd7 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
@@ -162,6 +162,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
void reset_controllables ();
void drop_all ();
+ void send_sysex_init ();
enum ConnectionState {
InputConnected = 0x1,
@@ -174,6 +175,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
void connected();
std::string _current_binding;
+ std::string _sysex_init;
uint32_t _bank_size;
uint32_t _current_bank;
/** true if this surface is motorised. If it is, we assume