zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

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:
Msrc/Nio/MidiIn.cpp | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Nio/MidiIn.h | 12+++++++++---
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]; }; }