commit 8785eafa7d124d1014392215b6f201bcfe6b87f9
parent bd4c2a6488f5f81b5e05a021ae7fe859406a067b
Author: Hans Petter Selasky <hps@selasky.org>
Date: Tue, 22 Jan 2019 16:01:02 +0100
Implement support for MIDI floating point note event via SysEx.
Signed-off-by: Hans Petter Selasky <hps@selasky.org>
Diffstat:
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/src/Nio/MidiIn.cpp b/src/Nio/MidiIn.cpp
@@ -17,12 +17,69 @@
namespace zyn {
+MidiIn::MidiIn()
+{
+ sysex_offset = 0;
+ memset(sysex_data, 0, sizeof(sysex_data));
+}
+
+uint8_t MidiIn::midiSysEx(unsigned char data)
+{
+ if (data & 0x80) {
+ if (data == 0xF0) {
+ sysex_offset = 0; /* begin */
+ } else if (data == 0xF7) {
+ return (2); /* end */
+ } else {
+ return (1); /* error */
+ }
+ } else if (sysex_offset >= sizeof(sysex_data)) {
+ return (1); /* error */
+ }
+ sysex_data[sysex_offset++] = data;
+ return (0);
+}
+
void MidiIn::midiProcess(unsigned char head,
unsigned char num,
unsigned char value)
{
MidiEvent ev;
unsigned char chan = head & 0x0f;
+
+ /* SYSEX handling */
+ if (head == 0xF0 || sysex_offset != 0) {
+ uint8_t status = 0;
+
+ status |= midiSysEx(head);
+ status |= midiSysEx(num);
+ status |= midiSysEx(value);
+
+ if (status & 1) {
+ /* error parsing SYSEX */
+ sysex_offset = 0;
+ } else if (status & 2) {
+ /* message complete */
+
+ if (sysex_offset >= 10 &&
+ sysex_data[1] == 0x0A &&
+ sysex_data[2] == 0x55) {
+ ev.type = M_FLOAT_NOTE;
+ ev.channel = sysex_data[3] & 0x0F;
+ ev.num = sysex_data[4];
+ ev.value = sysex_data[5];
+ ev.log2_freq = (sysex_data[6] +
+ (sysex_data[7] / (128.0f)) +
+ (sysex_data[8] / (128.0f * 128.0f)) +
+ (sysex_data[9] / (128.0f * 128.0f * 128.0f))
+ ) / 12.0f;
+ InMgr::getInstance().putEvent(ev);
+ }
+ return; /* message complete */
+ } else {
+ return; /* wait for more data */
+ }
+ }
switch(head & 0xf0) {
case 0x80: //Note Off
ev.type = M_NOTE;
diff --git a/src/Nio/MidiIn.h b/src/Nio/MidiIn.h
@@ -24,13 +24,19 @@ namespace zyn {
class MidiIn:public virtual Engine
{
public:
+ MidiIn();
+
/**Enables or disables driver based upon value*/
virtual void setMidiEn(bool nval) = 0;
/**Returns if driver is initialized*/
virtual bool getMidiEn() const = 0;
- static void midiProcess(unsigned char head,
- unsigned char num,
- unsigned char value);
+ void midiProcess(unsigned char head,
+ unsigned char num,
+ unsigned char value);
+ private:
+ uint8_t midiSysEx(unsigned char data);
+ uint8_t sysex_offset;
+ uint8_t sysex_data[64];
};
}