now with MIDI supprt
This commit is contained in:
parent
3a234b1969
commit
e4c0c8cbe0
6 changed files with 623 additions and 46 deletions
|
@ -12,6 +12,11 @@
|
|||
#include <Arduino.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_MIDI
|
||||
#include <MIDIUSB.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXTERNAL_EEPROM
|
||||
#include <EEPROM.h>
|
||||
#endif
|
||||
|
@ -166,11 +171,14 @@ void CimditProfile::load(uint8_t num) {
|
|||
for (uint8_t i = 0; i < m_numMappedButtons ; ++i) {
|
||||
m_mappedButtons[i].m_number = nextUInt8();
|
||||
m_mappedButtons[i].m_type = (MappingType)(nextUInt8());
|
||||
m_mappedButtons[i].m_value = nextUInt8();
|
||||
m_mappedButtons[i].m_value1 = nextUInt8();
|
||||
if (m_mappedButtons[i].m_type == MIDI_NOTE || m_mappedButtons[i].m_type == MIDI_CTRL || m_mappedButtons[i].m_type == MIDI_PITCH) {
|
||||
m_mappedButtons[i].m_value2 = nextUInt8();
|
||||
m_mappedButtons[i].m_value3 = nextUInt8();
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of mapped buttons
|
||||
|
||||
// mapped axis
|
||||
// number of mapped axis
|
||||
m_numMappedAxis = nextUInt8();
|
||||
|
@ -178,11 +186,13 @@ void CimditProfile::load(uint8_t num) {
|
|||
for (uint8_t i = 0; i < m_numMappedAxis ; ++i) {
|
||||
m_mappedAxis[i].m_number = nextUInt8();
|
||||
m_mappedAxis[i].m_type = (MappingType)(nextUInt8());
|
||||
m_mappedAxis[i].m_value = nextUInt8();
|
||||
m_mappedAxis[i].m_value1 = nextUInt8();
|
||||
if (m_mappedAxis[i].m_type == MIDI_CTRL_AXIS) {
|
||||
m_mappedAxis[i].m_value2 = nextUInt8();
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of mapped axis
|
||||
|
||||
// mapped rotary
|
||||
// number of mapped rotary
|
||||
m_numMappedRotary = nextUInt8();
|
||||
|
@ -190,7 +200,7 @@ void CimditProfile::load(uint8_t num) {
|
|||
for (uint8_t i = 0; i < m_numMappedRotary ; ++i) {
|
||||
m_mappedRotary[i].m_number = nextUInt8();
|
||||
m_mappedRotary[i].m_type = (MappingType)(nextUInt8());
|
||||
m_mappedRotary[i].m_value = nextUInt8();
|
||||
m_mappedRotary[i].m_value1 = nextUInt8();
|
||||
}
|
||||
}
|
||||
// end of mapped rotary
|
||||
|
@ -305,14 +315,14 @@ void CimditProfile::scanOrExecuteMacro(uint8_t macroNum, bool execute) {
|
|||
for (uint8_t i = 0; i < m_numMappedAxis; ++i) {
|
||||
if (m_mappedAxis[i].m_number == axis) {
|
||||
m_mappedAxis[i].m_type = MOUSE_REL_X_AXIS;
|
||||
m_mappedAxis[i].m_value = value8;
|
||||
m_mappedAxis[i].m_value1 = value8;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
m_mappedAxis[m_numMappedAxis].m_type = MOUSE_REL_X_AXIS;
|
||||
m_mappedAxis[m_numMappedAxis].m_number = axis;
|
||||
m_mappedAxis[m_numMappedAxis++].m_value = value8;
|
||||
m_mappedAxis[m_numMappedAxis++].m_value1 = value8;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -337,14 +347,14 @@ void CimditProfile::scanOrExecuteMacro(uint8_t macroNum, bool execute) {
|
|||
for (uint8_t i = 0; i < m_numMappedAxis; ++i) {
|
||||
if (m_mappedAxis[i].m_number == axis) {
|
||||
m_mappedAxis[i].m_type = MOUSE_REL_Y_AXIS;
|
||||
m_mappedAxis[i].m_value = value8;
|
||||
m_mappedAxis[i].m_value1 = value8;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
m_mappedAxis[m_numMappedAxis].m_type = MOUSE_REL_Y_AXIS;
|
||||
m_mappedAxis[m_numMappedAxis].m_number = axis;
|
||||
m_mappedAxis[m_numMappedAxis++].m_value = value8;
|
||||
m_mappedAxis[m_numMappedAxis++].m_value1 = value8;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -359,6 +369,61 @@ void CimditProfile::scanOrExecuteMacro(uint8_t macroNum, bool execute) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case MACRO_MIDI_NOTEON:
|
||||
{
|
||||
uint8_t channel = nextUInt8();
|
||||
value8 = nextUInt8();
|
||||
uint8_t velocity = nextUInt8();
|
||||
#ifdef HAVE_MIDI
|
||||
if (execute) {
|
||||
midiEventPacket_t noteOn = {0x09, (uint8_t)(0x90 | channel), value8, velocity};
|
||||
MidiUSB.sendMIDI(noteOn);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case MACRO_MIDI_NOTEOFF:
|
||||
{
|
||||
uint8_t channel = nextUInt8();
|
||||
value8 = nextUInt8();
|
||||
uint8_t velocity = nextUInt8();
|
||||
#ifdef HAVE_MIDI
|
||||
if (execute) {
|
||||
midiEventPacket_t noteOff = {0x08, (uint8_t)(0x80 | channel), value8, velocity};
|
||||
MidiUSB.sendMIDI(noteOff);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case MACRO_MIDI_CTRL:
|
||||
{
|
||||
uint8_t channel = nextUInt8();
|
||||
uint8_t control = nextUInt8();
|
||||
value8 = nextUInt8();
|
||||
#ifdef HAVE_MIDI
|
||||
if (execute) {
|
||||
midiEventPacket_t event= {0x0B, (uint8_t)(0xB0 | channel), control, value8};
|
||||
MidiUSB.sendMIDI(event);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case MACRO_MIDI_PITCH:
|
||||
{
|
||||
uint8_t channel = nextUInt8();
|
||||
uint16_t value = nextUInt16();
|
||||
#ifdef HAVE_MIDI
|
||||
if (execute) {
|
||||
midiEventPacket_t event = {0x0E, (uint8_t)(0xE0 | channel), (unsigned char)(value&127), (uint8_t)(value>>7)};
|
||||
MidiUSB.sendMIDI(event);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (token != MACRO_NULL);
|
||||
}
|
||||
|
@ -375,13 +440,13 @@ void CimditProfile::rotaryAction(uint8_t num, int8_t delta) {
|
|||
// rotary supports mouse rel axis, next/prev profile and macro
|
||||
switch (m_mappedRotary[i].m_type) {
|
||||
case MOUSE_REL_X_AXIS:
|
||||
Mouse.move(m_mappedRotary[i].m_value * delta, 0, 0);
|
||||
Mouse.move(m_mappedRotary[i].m_value1 * delta, 0, 0);
|
||||
break;
|
||||
case MOUSE_REL_Y_AXIS:
|
||||
Mouse.move(0, m_mappedRotary[i].m_value * delta, 0);
|
||||
Mouse.move(0, m_mappedRotary[i].m_value1 * delta, 0);
|
||||
break;
|
||||
case MOUSE_REL_WHEEL:
|
||||
Mouse.move(0, 0, m_mappedRotary[i].m_value * delta);
|
||||
Mouse.move(0, 0, m_mappedRotary[i].m_value1 * delta);
|
||||
break;
|
||||
case NEXT_PROFILE:
|
||||
case PREV_PROFILE:
|
||||
|
@ -397,7 +462,7 @@ void CimditProfile::rotaryAction(uint8_t num, int8_t delta) {
|
|||
showActivate();
|
||||
break;
|
||||
case MACRO_PRESS:
|
||||
scanOrExecuteMacro(m_mappedRotary[i].m_value, true);
|
||||
scanOrExecuteMacro(m_mappedRotary[i].m_value1, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -490,7 +555,7 @@ void CimditProfile::axisAction(uint8_t num, uint16_t state) {
|
|||
if (m_mappedAxis[i].m_number == num) {
|
||||
switch (m_mappedAxis[i].m_type) {
|
||||
case JOYSTICK_AXIS:
|
||||
switch (m_mappedAxis[i].m_value) {
|
||||
switch (m_mappedAxis[i].m_value1) {
|
||||
case 1:
|
||||
Gamepad.xAxis(map(state, 0, 1023, -32768, 32767));
|
||||
break;
|
||||
|
@ -514,9 +579,9 @@ void CimditProfile::axisAction(uint8_t num, uint16_t state) {
|
|||
case MOUSE_REL_X_AXIS: {
|
||||
int16_t pos = (int16_t)state - 512;
|
||||
if (pos > JOYSTICK_DEAD_ZONE_X) {
|
||||
m_mouseMoveX = map(pos, JOYSTICK_DEAD_ZONE_X, 511, 0, m_mappedAxis[i].m_value);
|
||||
m_mouseMoveX = map(pos, JOYSTICK_DEAD_ZONE_X, 511, 0, m_mappedAxis[i].m_value1);
|
||||
} else if (pos < -JOYSTICK_DEAD_ZONE_X) {
|
||||
m_mouseMoveX = map(pos, -512, -JOYSTICK_DEAD_ZONE_X, -m_mappedAxis[i].m_value, 0);
|
||||
m_mouseMoveX = map(pos, -512, -JOYSTICK_DEAD_ZONE_X, -m_mappedAxis[i].m_value1, 0);
|
||||
} else {
|
||||
m_mouseMoveX = 0;
|
||||
}
|
||||
|
@ -525,16 +590,46 @@ void CimditProfile::axisAction(uint8_t num, uint16_t state) {
|
|||
case MOUSE_REL_Y_AXIS: {
|
||||
int16_t pos = (int16_t)state - 512;
|
||||
if (pos > JOYSTICK_DEAD_ZONE_Y) {
|
||||
m_mouseMoveY = map(pos, JOYSTICK_DEAD_ZONE_Y, 511, 0, m_mappedAxis[i].m_value);
|
||||
m_mouseMoveY = map(pos, JOYSTICK_DEAD_ZONE_Y, 511, 0, m_mappedAxis[i].m_value1);
|
||||
} else if (pos < -JOYSTICK_DEAD_ZONE_Y) {
|
||||
m_mouseMoveY = map(pos, -512, -JOYSTICK_DEAD_ZONE_Y, -m_mappedAxis[i].m_value, 0);
|
||||
m_mouseMoveY = map(pos, -512, -JOYSTICK_DEAD_ZONE_Y, -m_mappedAxis[i].m_value1, 0);
|
||||
} else {
|
||||
m_mouseMoveY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
case MIDI_CTRL_AXIS:
|
||||
#ifdef HAVE_MIDI
|
||||
{
|
||||
midiEventPacket_t event = {0x0B, (uint8_t)(0xB0 | m_mappedAxis[i].m_value1), m_mappedAxis[i].m_value2, (uint8_t)(state/8)};
|
||||
MidiUSB.sendMIDI(event);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MIDI_PITCH_AXIS:
|
||||
#ifdef HAVE_MIDI
|
||||
{
|
||||
uint16_t val = (1023-state) * 16;
|
||||
midiEventPacket_t event = {0x0E, (uint8_t)(0xE0 | m_mappedAxis[i].m_value1), (unsigned char)(val&127), (uint8_t)(val>>7)};
|
||||
MidiUSB.sendMIDI(event);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MAPPING_NONE:
|
||||
case JOYSTICK_BUTTON:
|
||||
case MOUSE_BUTTON:
|
||||
case MOUSE_REL_WHEEL:
|
||||
case NEXT_PROFILE:
|
||||
case PREV_PROFILE:
|
||||
case SWITCH_PROFILE:
|
||||
case MACRO_PRESS:
|
||||
case MACRO_RELEASE:
|
||||
case KEYBOARD_BUTTON:
|
||||
case MIDI_NOTE:
|
||||
case MIDI_CTRL:
|
||||
case MIDI_PITCH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -550,27 +645,27 @@ void CimditProfile::buttonAction(uint8_t num, bool state) {
|
|||
switch (m_mappedButtons[i].m_type) {
|
||||
case JOYSTICK_BUTTON:
|
||||
if (state) {
|
||||
Gamepad.press(m_mappedButtons[i].m_value);
|
||||
Gamepad.press(m_mappedButtons[i].m_value1);
|
||||
} else {
|
||||
Gamepad.release(m_mappedButtons[i].m_value);
|
||||
Gamepad.release(m_mappedButtons[i].m_value1);
|
||||
}
|
||||
Gamepad.write();
|
||||
break;
|
||||
case MOUSE_BUTTON:
|
||||
if (state) {
|
||||
Mouse.press(m_mappedButtons[i].m_value);
|
||||
Mouse.press(m_mappedButtons[i].m_value1);
|
||||
} else {
|
||||
Mouse.release(m_mappedButtons[i].m_value);
|
||||
Mouse.release(m_mappedButtons[i].m_value1);
|
||||
}
|
||||
break;
|
||||
case MOUSE_REL_X_AXIS:
|
||||
Mouse.move(m_mappedButtons[i].m_value, 0, 0);
|
||||
Mouse.move(m_mappedButtons[i].m_value1, 0, 0);
|
||||
break;
|
||||
case MOUSE_REL_Y_AXIS:
|
||||
Mouse.move(0, m_mappedButtons[i].m_value, 0);
|
||||
Mouse.move(0, m_mappedButtons[i].m_value1, 0);
|
||||
break;
|
||||
case MOUSE_REL_WHEEL:
|
||||
Mouse.move(0, 0, m_mappedButtons[i].m_value);
|
||||
Mouse.move(0, 0, m_mappedButtons[i].m_value1);
|
||||
break;
|
||||
case NEXT_PROFILE:
|
||||
case PREV_PROFILE:
|
||||
|
@ -592,21 +687,57 @@ void CimditProfile::buttonAction(uint8_t num, bool state) {
|
|||
break;
|
||||
case MACRO_PRESS:
|
||||
if (state)
|
||||
scanOrExecuteMacro(m_mappedButtons[i].m_value, true);
|
||||
scanOrExecuteMacro(m_mappedButtons[i].m_value1, true);
|
||||
break;
|
||||
case MACRO_RELEASE:
|
||||
if (!state)
|
||||
scanOrExecuteMacro(m_mappedButtons[i].m_value, true);
|
||||
scanOrExecuteMacro(m_mappedButtons[i].m_value1, true);
|
||||
break;
|
||||
case KEYBOARD_BUTTON:
|
||||
if (state) {
|
||||
Keyboard.press((KeyboardKeycode)m_mappedButtons[i].m_value);
|
||||
Keyboard.press((KeyboardKeycode)m_mappedButtons[i].m_value1);
|
||||
} else {
|
||||
Keyboard.release((KeyboardKeycode)m_mappedButtons[i].m_value);
|
||||
Keyboard.release((KeyboardKeycode)m_mappedButtons[i].m_value1);
|
||||
}
|
||||
break;
|
||||
case MIDI_NOTE:
|
||||
#ifdef HAVE_MIDI
|
||||
if (state) {
|
||||
// send a midi note on message
|
||||
midiEventPacket_t noteOn = {0x09, (uint8_t)(0x90 | m_mappedButtons[i].m_value1), m_mappedButtons[i].m_value2, m_mappedButtons[i].m_value3};
|
||||
MidiUSB.sendMIDI(noteOn);
|
||||
} else {
|
||||
// send a midi note on message
|
||||
midiEventPacket_t noteOff = {0x08, (uint8_t)(0x80 | m_mappedButtons[i].m_value1), m_mappedButtons[i].m_value2, m_mappedButtons[i].m_value3};
|
||||
MidiUSB.sendMIDI(noteOff);
|
||||
}
|
||||
MidiUSB.flush();
|
||||
#endif
|
||||
break;
|
||||
case MIDI_CTRL:
|
||||
#ifdef HAVE_MIDI
|
||||
{
|
||||
// send a midi note on message
|
||||
midiEventPacket_t control = {0x0B, (uint8_t)(0xB0 | m_mappedButtons[i].m_value1), m_mappedButtons[i].m_value2, m_mappedButtons[i].m_value3};
|
||||
MidiUSB.sendMIDI(control);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MIDI_PITCH:
|
||||
#ifdef HAVE_MIDI
|
||||
{
|
||||
// send a midi note on message
|
||||
midiEventPacket_t event = {0x0E, (uint8_t)(0xE0 | m_mappedButtons[i].m_value1), m_mappedButtons[i].m_value2, m_mappedButtons[i].m_value3};
|
||||
MidiUSB.sendMIDI(event);
|
||||
MidiUSB.flush();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MAPPING_NONE:
|
||||
case JOYSTICK_AXIS:
|
||||
case MIDI_CTRL_AXIS:
|
||||
case MIDI_PITCH_AXIS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +867,6 @@ void CimditProfile::writeFlash() {
|
|||
}
|
||||
m_displayState = DISPLAY_BLANK; // to enforce a redraw
|
||||
showActiveProfile();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CimditProfile::setUserString(uint8_t timeout, const char* input) {
|
||||
|
@ -787,7 +917,7 @@ void CimditProfile::userDisplay() {
|
|||
buf = 0;
|
||||
uint16_t len = width * height;
|
||||
if (width != SCREEN_WIDTH || SCREEN_HEIGHT != 32) {
|
||||
for (uint8_t i = 0; i < width * height; ++i) {
|
||||
for (uint8_t i = 0; i < len; ++i) {
|
||||
buf = Serial.read();
|
||||
if (buf == '\n') buf = Serial.read();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,16 @@ class CimditProfile {
|
|||
MACRO_RELEASE,
|
||||
/// mapping as keyboard button
|
||||
KEYBOARD_BUTTON,
|
||||
/// mapping as MIDI note
|
||||
MIDI_NOTE,
|
||||
/// mapping as MIDI command
|
||||
MIDI_CTRL,
|
||||
/// mapping as MIDI pitch
|
||||
MIDI_PITCH,
|
||||
/// mapping axis as MIDI command
|
||||
MIDI_CTRL_AXIS,
|
||||
/// mapping axis as MIDI pitch
|
||||
MIDI_PITCH_AXIS
|
||||
};
|
||||
|
||||
/// enums for use in macros
|
||||
|
@ -134,6 +144,14 @@ class CimditProfile {
|
|||
MACRO_MOUSE_REL_X_AXIS, // 13
|
||||
/// move mouse Y according to an analog axis
|
||||
MACRO_MOUSE_REL_Y_AXIS, // 14
|
||||
/// MIDI note on
|
||||
MACRO_MIDI_NOTEON, // 15
|
||||
/// MIDI note off
|
||||
MACRO_MIDI_NOTEOFF, // 16
|
||||
/// MIDI send control message
|
||||
MACRO_MIDI_CTRL, // 17
|
||||
/// MIDI send pitch message
|
||||
MACRO_MIDI_PITCH, // 18
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -212,7 +230,13 @@ class CimditProfile {
|
|||
MappingType m_type;
|
||||
|
||||
/// optional value
|
||||
int8_t m_value;
|
||||
uint8_t m_value1;
|
||||
|
||||
/// optional value 2
|
||||
uint8_t m_value2;
|
||||
|
||||
/// optional value 2
|
||||
uint8_t m_value3;
|
||||
};
|
||||
|
||||
/// number of mapped buttons
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/// we have a display connected
|
||||
#define HAVE_DISPLAY
|
||||
|
||||
/// we want to create MIDI
|
||||
#define HAVE_MIDI
|
||||
|
||||
/// use a custom keyboard layout
|
||||
#define HID_CUSTOM_LAYOUT
|
||||
|
||||
|
|
|
@ -194,10 +194,143 @@
|
|||
"source": 1,
|
||||
"type": "NEXT_PROFILE"
|
||||
}
|
||||
],
|
||||
"macros": []
|
||||
},
|
||||
{
|
||||
"name": "MIDI",
|
||||
"mappedbuttons": [
|
||||
{
|
||||
"source": 62,
|
||||
"type": "SWITCH_PROFILE"
|
||||
},
|
||||
{
|
||||
"source": 61,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 48,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 53,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 49,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 45,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 50,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 37,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 51,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 46,
|
||||
"type": "MIDI_CTRL",
|
||||
"channel": 0,
|
||||
"control": 10,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"source": 38,
|
||||
"type": "MIDI_CTRL",
|
||||
"channel": 0,
|
||||
"control": 10,
|
||||
"value": 64
|
||||
},
|
||||
{
|
||||
"source": 49,
|
||||
"type": "MIDI_PITCH",
|
||||
"channel": 0,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"source": 41,
|
||||
"type": "MIDI_PITCH",
|
||||
"channel": 0,
|
||||
"value": 8192
|
||||
},
|
||||
{
|
||||
"source": 33,
|
||||
"type": "MACRO_PRESS",
|
||||
"macro": 0
|
||||
}
|
||||
],
|
||||
"mappedaxis": [
|
||||
{
|
||||
"source": 0,
|
||||
"type": "MIDI_CTRL_AXIS",
|
||||
"channel": 0,
|
||||
"control": 10
|
||||
},
|
||||
{
|
||||
"source": 1,
|
||||
"type": "MIDI_PITCH_AXIS",
|
||||
"channel": 0
|
||||
},
|
||||
{
|
||||
"source": 2,
|
||||
"type": "MIDI_CTRL_AXIS",
|
||||
"channel": 0,
|
||||
"control": 1
|
||||
}
|
||||
],
|
||||
"mappedrotary": [
|
||||
{
|
||||
"source": 0,
|
||||
"type": "PREV_PROFILE"
|
||||
},
|
||||
{
|
||||
"source": 1,
|
||||
"type": "NEXT_PROFILE"
|
||||
}
|
||||
],
|
||||
"macros": [
|
||||
[
|
||||
"MACRO_MIDI_NOTEON",
|
||||
0,
|
||||
60,
|
||||
64,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_CTRL",
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
"MACRO_DELAY",
|
||||
2000,
|
||||
"MACRO_MIDI_CTRL",
|
||||
0,
|
||||
10,
|
||||
64,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_PITCH",
|
||||
0,
|
||||
512,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_PITCH",
|
||||
0,
|
||||
8192,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_NOTEOFF",
|
||||
0,
|
||||
60,
|
||||
64
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
</textarea>
|
||||
]</textarea>
|
||||
<p><button id="generatestring" class="button">Generate String</button></p>
|
||||
<p id="error"></p>
|
||||
<textarea id="string"></textarea>
|
||||
|
|
|
@ -14,6 +14,10 @@ type EntityJson = {
|
|||
axis?: number;
|
||||
value?: number;
|
||||
macro?: number;
|
||||
channel?: number;
|
||||
note?: number;
|
||||
velocity?: number;
|
||||
control?: number;
|
||||
}
|
||||
|
||||
type EntityProfileString = {
|
||||
|
@ -48,6 +52,11 @@ class ProfileGenerator {
|
|||
"MACRO_PRESS",
|
||||
"MACRO_RELEASE",
|
||||
"KEYBOARD_BUTTON",
|
||||
"MIDI_NOTE",
|
||||
"MIDI_CTRL",
|
||||
"MIDI_PITCH",
|
||||
"MIDI_CTRL_AXIS",
|
||||
"MIDI_PITCH_AXIS",
|
||||
];
|
||||
private macroEnum: Array<string> = [
|
||||
"MACRO_NULL",
|
||||
|
@ -64,7 +73,11 @@ class ProfileGenerator {
|
|||
"MACRO_MOUSE_REL_X",
|
||||
"MACRO_MOUSE_REL_Y",
|
||||
"MACRO_MOUSE_REL_X_AXIS",
|
||||
"MACRO_MOUSE_REL_Y_AXIS"
|
||||
"MACRO_MOUSE_REL_Y_AXIS",
|
||||
"MACRO_MIDI_NOTEON",
|
||||
"MACRO_MIDI_NOTEOFF",
|
||||
"MACRO_MIDI_CTRL",
|
||||
"MACRO_MIDI_PITCH",
|
||||
];
|
||||
|
||||
private keyLookup = {
|
||||
|
@ -424,7 +437,6 @@ class ProfileGenerator {
|
|||
|
||||
map(entities: Array<EntityJson>) : EntityProfileString {
|
||||
var out ="";
|
||||
var bytes = 0
|
||||
var count = 0;
|
||||
for (var i = 0; i < entities.length; ++i) {
|
||||
var entity = entities[i];
|
||||
|
@ -437,8 +449,27 @@ class ProfileGenerator {
|
|||
} else {
|
||||
tmp += this.hexString(this.keyLookup[<string>entity.target]);
|
||||
}
|
||||
} else if (entity.channel !== undefined && entity.note !== undefined && entity.velocity !== undefined && entity.type === 'MIDI_NOTE') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.note);
|
||||
tmp += this.hexString(entity.velocity);
|
||||
} else if (entity.channel !== undefined && entity.control !== undefined && entity.value !== undefined && entity.type === 'MIDI_CTRL') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.control);
|
||||
tmp += this.hexString(entity.value);
|
||||
} else if (entity.channel !== undefined && entity.value !== undefined && entity.type === 'MIDI_PITCH') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.value >> 8);
|
||||
tmp += this.hexString(entity.value & 255);
|
||||
} else if (entity.channel !== undefined && entity.control !== undefined && entity.type === 'MIDI_CTRL_AXIS') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.control);
|
||||
} else if (entity.channel !== undefined && entity.type === 'MIDI_PITCH_AXIS') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
} else if (entity.axis !== undefined) {
|
||||
tmp += this.hexString(entity.axis);
|
||||
} else if (entity.control !== undefined) {
|
||||
tmp += this.hexString(entity.control);
|
||||
} else if (entity.value !== undefined) {
|
||||
tmp += this.hexString(entity.value);
|
||||
} else if (entity.macro !== undefined) {
|
||||
|
@ -447,14 +478,13 @@ class ProfileGenerator {
|
|||
tmp += "00";
|
||||
}
|
||||
out += tmp;
|
||||
bytes += 3;
|
||||
++count;
|
||||
} catch(e) {
|
||||
// print error
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
return {bytes: bytes, count: count, string: out};
|
||||
return {bytes: out.length / 2, count: count, string: out};
|
||||
}
|
||||
|
||||
createMacroString(macros: any[][]) : EntityProfileString {
|
||||
|
@ -512,6 +542,17 @@ class ProfileGenerator {
|
|||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]) + this.hexString(macro[++j]);
|
||||
bytes +=3;
|
||||
}
|
||||
} else if (token === "MACRO_MIDI_NOTEON" || token === "MACRO_MIDI_NOTEOFF") { // expect three integer values, channel, note and velocity
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]) + this.hexString(macro[++j]) + this.hexString(macro[++j]);
|
||||
bytes += 4;
|
||||
} else if (token === "MACRO_MIDI_CTRL") { // expect three integer values, channel, control and value
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]) + this.hexString(macro[++j]) + this.hexString(macro[++j]);
|
||||
bytes += 4;
|
||||
} else if (token === "MACRO_MIDI_PITCH") { // expect two integer values, channel and value (16 bit)
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]);
|
||||
const value = macro[++j]
|
||||
out += this.hexString(value >> 8) + this.hexString(value & 255);
|
||||
bytes += 4;
|
||||
} else {
|
||||
if (typeof(token) === "number") {
|
||||
out += this.hexString(token);
|
||||
|
@ -624,6 +665,22 @@ class ProfileGenerator {
|
|||
entity.value = this.fromHexS(tokens.shift());
|
||||
} else if (entity.type === 'MACRO_PRESS' || entity.type === 'MACRO_RELEASE') {
|
||||
entity.macro = this.fromHexU(tokens.shift());
|
||||
} else if (entity.type === 'MIDI_NOTE') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.note = this.fromHexU(tokens.shift());
|
||||
entity.velocity = this.fromHexU(tokens.shift());
|
||||
} else if (entity.type === 'MIDI_CTRL') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.control = this.fromHexU(tokens.shift());
|
||||
entity.value = this.fromHexU(tokens.shift());
|
||||
} else if (entity.type === 'MIDI_PITCH') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.value = this.fromHexU(tokens.shift())<<8 + this.fromHexU(tokens.shift());
|
||||
} else if (entity.type === 'MIDI_CTRL_AXIS') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.control = this.fromHexU(tokens.shift());
|
||||
} else if (entity.type === 'MIDI_PITCH_AXIS') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
} else {
|
||||
tokens.shift();
|
||||
}
|
||||
|
@ -691,6 +748,21 @@ class ProfileGenerator {
|
|||
macro.push(this.fromHexS(tokens.shift()));
|
||||
}
|
||||
break;
|
||||
case "MACRO_MIDI_NOTEON":
|
||||
case "MACRO_MIDI_NOTEOFF":
|
||||
macro.push(this.fromHexS(tokens.shift())); // channel
|
||||
macro.push(this.fromHexS(tokens.shift())); // note
|
||||
macro.push(this.fromHexS(tokens.shift())); // velocity
|
||||
break;
|
||||
case "MACRO_MIDI_CTRL":
|
||||
macro.push(this.fromHexS(tokens.shift())); // channel
|
||||
macro.push(this.fromHexS(tokens.shift())); // control
|
||||
macro.push(this.fromHexS(tokens.shift())); // value
|
||||
break;
|
||||
case "MACRO_MIDI_PITCH":
|
||||
macro.push(this.fromHexS(tokens.shift())); // channel
|
||||
macro.push(this.fromHexU(tokens.shift())<<8 + this.fromHexU(tokens.shift())); // value
|
||||
break;
|
||||
}
|
||||
} while (token !== "MACRO_NULL" && tokens.length > 0);
|
||||
return macro;
|
||||
|
|
|
@ -194,10 +194,143 @@ textarea{width:100%}#string{height:5vh}.codeEditor,.lineCounter{font-family:cour
|
|||
"source": 1,
|
||||
"type": "NEXT_PROFILE"
|
||||
}
|
||||
],
|
||||
"macros": []
|
||||
},
|
||||
{
|
||||
"name": "MIDI",
|
||||
"mappedbuttons": [
|
||||
{
|
||||
"source": 62,
|
||||
"type": "SWITCH_PROFILE"
|
||||
},
|
||||
{
|
||||
"source": 61,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 48,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 53,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 49,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 45,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 50,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 37,
|
||||
"type": "MIDI_NOTE",
|
||||
"channel": 0,
|
||||
"note": 51,
|
||||
"velocity": 64
|
||||
},
|
||||
{
|
||||
"source": 46,
|
||||
"type": "MIDI_CTRL",
|
||||
"channel": 0,
|
||||
"control": 10,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"source": 38,
|
||||
"type": "MIDI_CTRL",
|
||||
"channel": 0,
|
||||
"control": 10,
|
||||
"value": 64
|
||||
},
|
||||
{
|
||||
"source": 49,
|
||||
"type": "MIDI_PITCH",
|
||||
"channel": 0,
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"source": 41,
|
||||
"type": "MIDI_PITCH",
|
||||
"channel": 0,
|
||||
"value": 8192
|
||||
},
|
||||
{
|
||||
"source": 33,
|
||||
"type": "MACRO_PRESS",
|
||||
"macro": 0
|
||||
}
|
||||
],
|
||||
"mappedaxis": [
|
||||
{
|
||||
"source": 0,
|
||||
"type": "MIDI_CTRL_AXIS",
|
||||
"channel": 0,
|
||||
"control": 10
|
||||
},
|
||||
{
|
||||
"source": 1,
|
||||
"type": "MIDI_PITCH_AXIS",
|
||||
"channel": 0
|
||||
},
|
||||
{
|
||||
"source": 2,
|
||||
"type": "MIDI_CTRL_AXIS",
|
||||
"channel": 0,
|
||||
"control": 1
|
||||
}
|
||||
],
|
||||
"mappedrotary": [
|
||||
{
|
||||
"source": 0,
|
||||
"type": "PREV_PROFILE"
|
||||
},
|
||||
{
|
||||
"source": 1,
|
||||
"type": "NEXT_PROFILE"
|
||||
}
|
||||
],
|
||||
"macros": [
|
||||
[
|
||||
"MACRO_MIDI_NOTEON",
|
||||
0,
|
||||
60,
|
||||
64,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_CTRL",
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
"MACRO_DELAY",
|
||||
2000,
|
||||
"MACRO_MIDI_CTRL",
|
||||
0,
|
||||
10,
|
||||
64,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_PITCH",
|
||||
0,
|
||||
512,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_PITCH",
|
||||
0,
|
||||
8192,
|
||||
"MACRO_DELAY",
|
||||
1000,
|
||||
"MACRO_MIDI_NOTEOFF",
|
||||
0,
|
||||
60,
|
||||
64
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
</textarea>
|
||||
]</textarea>
|
||||
<p><button id="generatestring" class="button">Generate String</button></p>
|
||||
<p id="error"></p>
|
||||
<textarea id="string"></textarea>
|
||||
|
@ -227,6 +360,11 @@ var ProfileGenerator = (function () {
|
|||
"MACRO_PRESS",
|
||||
"MACRO_RELEASE",
|
||||
"KEYBOARD_BUTTON",
|
||||
"MIDI_NOTE",
|
||||
"MIDI_CTRL",
|
||||
"MIDI_PITCH",
|
||||
"MIDI_CTRL_AXIS",
|
||||
"MIDI_PITCH_AXIS",
|
||||
];
|
||||
this.macroEnum = [
|
||||
"MACRO_NULL",
|
||||
|
@ -243,7 +381,11 @@ var ProfileGenerator = (function () {
|
|||
"MACRO_MOUSE_REL_X",
|
||||
"MACRO_MOUSE_REL_Y",
|
||||
"MACRO_MOUSE_REL_X_AXIS",
|
||||
"MACRO_MOUSE_REL_Y_AXIS"
|
||||
"MACRO_MOUSE_REL_Y_AXIS",
|
||||
"MACRO_MIDI_NOTEON",
|
||||
"MACRO_MIDI_NOTEOFF",
|
||||
"MACRO_MIDI_CTRL",
|
||||
"MACRO_MIDI_PITCH",
|
||||
];
|
||||
this.keyLookup = {
|
||||
"KEY_RESERVED": 0,
|
||||
|
@ -597,7 +739,6 @@ var ProfileGenerator = (function () {
|
|||
};
|
||||
ProfileGenerator.prototype.map = function (entities) {
|
||||
var out = "";
|
||||
var bytes = 0;
|
||||
var count = 0;
|
||||
for (var i = 0; i < entities.length; ++i) {
|
||||
var entity = entities[i];
|
||||
|
@ -612,9 +753,34 @@ var ProfileGenerator = (function () {
|
|||
tmp += this.hexString(this.keyLookup[entity.target]);
|
||||
}
|
||||
}
|
||||
else if (entity.channel !== undefined && entity.note !== undefined && entity.velocity !== undefined && entity.type === 'MIDI_NOTE') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.note);
|
||||
tmp += this.hexString(entity.velocity);
|
||||
}
|
||||
else if (entity.channel !== undefined && entity.control !== undefined && entity.value !== undefined && entity.type === 'MIDI_CTRL') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.control);
|
||||
tmp += this.hexString(entity.value);
|
||||
}
|
||||
else if (entity.channel !== undefined && entity.value !== undefined && entity.type === 'MIDI_PITCH') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.value >> 8);
|
||||
tmp += this.hexString(entity.value & 255);
|
||||
}
|
||||
else if (entity.channel !== undefined && entity.control !== undefined && entity.type === 'MIDI_CTRL_AXIS') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
tmp += this.hexString(entity.control);
|
||||
}
|
||||
else if (entity.channel !== undefined && entity.type === 'MIDI_PITCH_AXIS') {
|
||||
tmp += this.hexString(entity.channel);
|
||||
}
|
||||
else if (entity.axis !== undefined) {
|
||||
tmp += this.hexString(entity.axis);
|
||||
}
|
||||
else if (entity.control !== undefined) {
|
||||
tmp += this.hexString(entity.control);
|
||||
}
|
||||
else if (entity.value !== undefined) {
|
||||
tmp += this.hexString(entity.value);
|
||||
}
|
||||
|
@ -625,14 +791,13 @@ var ProfileGenerator = (function () {
|
|||
tmp += "00";
|
||||
}
|
||||
out += tmp;
|
||||
bytes += 3;
|
||||
++count;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
return { bytes: bytes, count: count, string: out };
|
||||
return { bytes: out.length / 2, count: count, string: out };
|
||||
};
|
||||
ProfileGenerator.prototype.createMacroString = function (macros) {
|
||||
var bytes = 0;
|
||||
|
@ -695,6 +860,20 @@ var ProfileGenerator = (function () {
|
|||
bytes += 3;
|
||||
}
|
||||
}
|
||||
else if (token === "MACRO_MIDI_NOTEON" || token === "MACRO_MIDI_NOTEOFF") {
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]) + this.hexString(macro[++j]) + this.hexString(macro[++j]);
|
||||
bytes += 4;
|
||||
}
|
||||
else if (token === "MACRO_MIDI_CTRL") {
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]) + this.hexString(macro[++j]) + this.hexString(macro[++j]);
|
||||
bytes += 4;
|
||||
}
|
||||
else if (token === "MACRO_MIDI_PITCH") {
|
||||
out += this.hexString(this.macroEnum.indexOf(token)) + this.hexString(macro[++j]);
|
||||
const value = macro[++j];
|
||||
out += this.hexString(value >> 8) + this.hexString(value & 255);
|
||||
bytes += 4;
|
||||
}
|
||||
else {
|
||||
if (typeof (token) === "number") {
|
||||
out += this.hexString(token);
|
||||
|
@ -811,6 +990,27 @@ var ProfileGenerator = (function () {
|
|||
else if (entity.type === 'MACRO_PRESS' || entity.type === 'MACRO_RELEASE') {
|
||||
entity.macro = this.fromHexU(tokens.shift());
|
||||
}
|
||||
else if (entity.type === 'MIDI_NOTE') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.note = this.fromHexU(tokens.shift());
|
||||
entity.velocity = this.fromHexU(tokens.shift());
|
||||
}
|
||||
else if (entity.type === 'MIDI_CTRL') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.control = this.fromHexU(tokens.shift());
|
||||
entity.value = this.fromHexU(tokens.shift());
|
||||
}
|
||||
else if (entity.type === 'MIDI_PITCH') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.value = this.fromHexU(tokens.shift()) << 8 + this.fromHexU(tokens.shift());
|
||||
}
|
||||
else if (entity.type === 'MIDI_CTRL_AXIS') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
entity.control = this.fromHexU(tokens.shift());
|
||||
}
|
||||
else if (entity.type === 'MIDI_PITCH_AXIS') {
|
||||
entity.channel = this.fromHexU(tokens.shift());
|
||||
}
|
||||
else {
|
||||
tokens.shift();
|
||||
}
|
||||
|
@ -878,6 +1078,21 @@ var ProfileGenerator = (function () {
|
|||
macro.push(this.fromHexS(tokens.shift()));
|
||||
}
|
||||
break;
|
||||
case "MACRO_MIDI_NOTEON":
|
||||
case "MACRO_MIDI_NOTEOFF":
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
break;
|
||||
case "MACRO_MIDI_CTRL":
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
break;
|
||||
case "MACRO_MIDI_PITCH":
|
||||
macro.push(this.fromHexS(tokens.shift()));
|
||||
macro.push(this.fromHexU(tokens.shift()) << 8 + this.fromHexU(tokens.shift()));
|
||||
break;
|
||||
}
|
||||
} while (token !== "MACRO_NULL" && tokens.length > 0);
|
||||
return macro;
|
||||
|
|
Loading…
Reference in a new issue