diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-28 23:55:33 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-28 23:55:33 +0000 |
commit | e10d0339ccd3659e0de58db29131e528571bc8c4 (patch) | |
tree | b64e5f98da755f189e9b8ea43a6ed693700b5ef0 /libs | |
parent | 679ece14a3dda8dd1bc0c1a0a65abfcde9aeb0cd (diff) |
add sysex support to MIDI binding maps, and a couple more functions
git-svn-id: svn://localhost/ardour2/branches/3.0@6410 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/surfaces/generic_midi/generic_midi_control_protocol.cc | 78 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/midifunction.cc | 49 | ||||
-rw-r--r-- | libs/surfaces/generic_midi/midifunction.h | 11 |
3 files changed, 120 insertions, 18 deletions
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 67e940d905..d0d74f4c12 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -20,6 +20,7 @@ #define __STDC_FORMAT_MACROS 1 #include <stdint.h> +#include <sstream> #include <algorithm> #include "pbd/error.h" @@ -469,6 +470,8 @@ GenericMidiControlProtocol::load_bindings (const string& xmlpath) } else if (child->property ("function")) { + cerr << "try to create a function from " << child->property ("function")->value() << endl; + /* function */ MIDIFunction* mf; @@ -541,18 +544,13 @@ MIDIFunction* GenericMidiControlProtocol::create_function (const XMLNode& node) { const XMLProperty* prop; - int detail; - int channel; + int intval; + MIDI::byte detail = 0; + MIDI::channel_t channel = 0; string uri; MIDI::eventType ev; - - if ((prop = node.property (X_("channel"))) == 0) { - return 0; - } - - if (sscanf (prop->value().c_str(), "%d", &channel) != 1) { - return 0; - } + MIDI::byte* sysex = 0; + uint32_t sysex_size = 0; if ((prop = node.property (X_("ctl"))) != 0) { ev = MIDI::controller; @@ -560,25 +558,77 @@ GenericMidiControlProtocol::create_function (const XMLNode& node) ev = MIDI::on; } else if ((prop = node.property (X_("pgm"))) != 0) { ev = MIDI::program; + } else if ((prop = node.property (X_("sysex"))) != 0) { + + ev = MIDI::sysex; + int val; + uint32_t cnt; + + { + cnt = 0; + stringstream ss (prop->value()); + ss << hex; + + while (ss >> val) { + cnt++; + } + } + + if (cnt == 0) { + return 0; + } + + sysex = new MIDI::byte[cnt]; + sysex_size = cnt; + + { + stringstream ss (prop->value()); + ss << hex; + cnt = 0; + + while (ss >> val) { + sysex[cnt++] = (MIDI::byte) val; + cerr << hex << (int) sysex[cnt-1] << dec << ' ' << endl; + } + } + } else { + warning << "Binding ignored - unknown type" << endmsg; return 0; } - if (sscanf (prop->value().c_str(), "%d", &detail) != 1) { - return 0; + if (sysex_size == 0) { + if ((prop = node.property (X_("channel"))) == 0) { + return 0; + } + + if (sscanf (prop->value().c_str(), "%d", &intval) != 1) { + return 0; + } + channel = (MIDI::channel_t) intval; + /* adjust channel to zero-based counting */ + if (channel > 0) { + channel -= 1; + } + + if (sscanf (prop->value().c_str(), "%d", &intval) != 1) { + return 0; + } + + detail = (MIDI::byte) intval; } prop = node.property (X_("function")); MIDIFunction* mf = new MIDIFunction (*_port); - if (mf->init (*this, prop->value())) { + if (mf->init (*this, prop->value(), sysex, sysex_size)) { delete mf; return 0; } mf->bind_midi (channel, ev, detail); - + cerr << "New MF with function = " << prop->value() << endl; return mf; diff --git a/libs/surfaces/generic_midi/midifunction.cc b/libs/surfaces/generic_midi/midifunction.cc index e36af93ab3..609aca3bbc 100644 --- a/libs/surfaces/generic_midi/midifunction.cc +++ b/libs/surfaces/generic_midi/midifunction.cc @@ -28,14 +28,17 @@ using namespace MIDI; MIDIFunction::MIDIFunction (MIDI::Port& p) : _port (p) { + sysex_size = 0; + sysex = 0; } MIDIFunction::~MIDIFunction () { + delete sysex; } int -MIDIFunction::init (BasicUI& ui, const std::string& function_name) +MIDIFunction::init (BasicUI& ui, const std::string& function_name, MIDI::byte* sysex_data, size_t sysex_sz) { if (strcasecmp (function_name.c_str(), "transport-stop") == 0) { _function = TransportStop; @@ -47,11 +50,24 @@ MIDIFunction::init (BasicUI& ui, const std::string& function_name) _function = TransportStart; } else if (strcasecmp (function_name.c_str(), "transport-end") == 0) { _function = TransportEnd; + } else if (strcasecmp (function_name.c_str(), "loop-toggle") == 0) { + _function = TransportLoopToggle; + } else if (strcasecmp (function_name.c_str(), "rec-enable") == 0) { + _function = TransportRecordEnable; + } else if (strcasecmp (function_name.c_str(), "rec-disable") == 0) { + _function = TransportRecordDisable; } else { return -1; } _ui = &ui; + + if (sysex_sz) { + /* we take ownership of the sysex data */ + sysex = sysex_data; + sysex_size = sysex_sz; + } + return 0; } @@ -78,6 +94,18 @@ MIDIFunction::execute () case TransportEnd: _ui->goto_end (); break; + + case TransportLoopToggle: + _ui->loop_toggle (); + break; + + case TransportRecordEnable: + _ui->set_record_enable (true); + break; + + case TransportRecordDisable: + _ui->set_record_enable (false); + break; } } @@ -118,6 +146,20 @@ MIDIFunction::midi_sense_program_change (Parser &, byte msg) } void +MIDIFunction::midi_sense_sysex (Parser &, byte* msg, size_t sz) +{ + if (sz != sysex_size) { + return; + } + + if (memcmp (msg, sysex, sysex_size) != 0) { + return; + } + + execute (); +} + +void MIDIFunction::bind_midi (channel_t chn, eventType ev, MIDI::byte additional) { midi_sense_connection[0].disconnect (); @@ -156,6 +198,10 @@ MIDIFunction::bind_midi (channel_t chn, eventType ev, MIDI::byte additional) p.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_program_change, this, _1, _2)); break; + case MIDI::sysex: + p.sysex.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIFunction::midi_sense_sysex, this, _1, _2, _3)); + break; + default: break; } @@ -173,3 +219,4 @@ MIDIFunction::set_state (const XMLNode& node, int version) { return 0; } + diff --git a/libs/surfaces/generic_midi/midifunction.h b/libs/surfaces/generic_midi/midifunction.h index 5374d94157..8931e2c9eb 100644 --- a/libs/surfaces/generic_midi/midifunction.h +++ b/libs/surfaces/generic_midi/midifunction.h @@ -45,13 +45,16 @@ class MIDIFunction : public PBD::Stateful TransportStop, TransportZero, TransportStart, - TransportEnd + TransportEnd, + TransportLoopToggle, + TransportRecordEnable, + TransportRecordDisable }; MIDIFunction (MIDI::Port&); virtual ~MIDIFunction (); - int init (BasicUI&, const std::string&); + int init (BasicUI&, const std::string& function_name, MIDI::byte* sysex = 0, size_t ssize = 0); MIDI::Port& get_port() const { return _port; } const std::string& function_name() const { return _function_name; } @@ -73,8 +76,9 @@ class MIDIFunction : public PBD::Stateful MIDI::eventType control_type; MIDI::byte control_additional; MIDI::channel_t control_channel; + MIDI::byte* sysex; + size_t sysex_size; - void init (const std::string& function_name); void execute (); void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on); @@ -82,6 +86,7 @@ class MIDIFunction : public PBD::Stateful void midi_sense_note_off (MIDI::Parser &p, MIDI::EventTwoBytes *tb); void midi_sense_controller (MIDI::Parser &, MIDI::EventTwoBytes *); void midi_sense_program_change (MIDI::Parser &, MIDI::byte); + void midi_sense_sysex (MIDI::Parser &, MIDI::byte*, size_t); }; #endif // __gm_midicontrollable_h__ |