mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2026-09-18 17:21:30 +00:00
Reorg, added more sources
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define SYSEX_BUFFER_LEN 16
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "message.h"
|
||||
|
||||
/** Returns the data within the MidiEvent as a NoteOffEvent struct */
|
||||
NoteOffEvent AsNoteOff(MidiEvent* event) {
|
||||
NoteOffEvent m;
|
||||
m.channel = event->channel;
|
||||
m.note = event->data[0];
|
||||
m.velocity = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a NoteOnEvent struct */
|
||||
NoteOnEvent AsNoteOn(MidiEvent* event) {
|
||||
NoteOnEvent m;
|
||||
m.channel = event->channel;
|
||||
m.note = event->data[0];
|
||||
m.velocity = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a PolyphonicKeyPressureEvent struct */
|
||||
PolyphonicKeyPressureEvent AsPolyphonicKeyPressure(MidiEvent* event) {
|
||||
PolyphonicKeyPressureEvent m;
|
||||
m.channel = event->channel;
|
||||
m.note = event->data[0];
|
||||
m.pressure = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a ControlChangeEvent struct.*/
|
||||
ControlChangeEvent AsControlChange(MidiEvent* event) {
|
||||
ControlChangeEvent m;
|
||||
m.channel = event->channel;
|
||||
m.control_number = event->data[0];
|
||||
m.value = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/
|
||||
ProgramChangeEvent AsProgramChange(MidiEvent* event) {
|
||||
ProgramChangeEvent m;
|
||||
m.channel = event->channel;
|
||||
m.program = event->data[0];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/
|
||||
ChannelPressureEvent AsChannelPressure(MidiEvent* event) {
|
||||
ChannelPressureEvent m;
|
||||
m.channel = event->channel;
|
||||
m.pressure = event->data[0];
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Returns the data within the MidiEvent as a PitchBendEvent struct.*/
|
||||
PitchBendEvent AsPitchBend(MidiEvent* event) {
|
||||
PitchBendEvent m;
|
||||
m.channel = event->channel;
|
||||
m.value = ((uint16_t)(event->data[1]) << 7) + (event->data[0] - 8192);
|
||||
return m;
|
||||
}
|
||||
|
||||
SystemExclusiveEvent AsSystemExclusive(MidiEvent* event) {
|
||||
SystemExclusiveEvent m;
|
||||
m.length = event->sysex_message_len;
|
||||
for(int i = 0; i < SYSEX_BUFFER_LEN; i++) {
|
||||
m.data[i] = 0;
|
||||
if(i < m.length) {
|
||||
m.data[i] = event->sysex_data[i];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
MTCQuarterFrameEvent AsMTCQuarterFrame(MidiEvent* event) {
|
||||
MTCQuarterFrameEvent m;
|
||||
m.message_type = (event->data[0] & 0x70) >> 4;
|
||||
m.value = (event->data[0]) & 0x0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
SongPositionPointerEvent AsSongPositionPointer(MidiEvent* event) {
|
||||
SongPositionPointerEvent m;
|
||||
m.position = ((uint16_t)(event->data[1]) << 7) | (event->data[0]);
|
||||
return m;
|
||||
}
|
||||
|
||||
SongSelectEvent AsSongSelect(MidiEvent* event) {
|
||||
SongSelectEvent m;
|
||||
m.song = event->data[0];
|
||||
return m;
|
||||
}
|
||||
|
||||
AllSoundOffEvent AsAllSoundOff(MidiEvent* event) {
|
||||
AllSoundOffEvent m;
|
||||
m.channel = event->channel;
|
||||
return m;
|
||||
}
|
||||
|
||||
ResetAllControllersEvent AsResetAllControllers(MidiEvent* event) {
|
||||
ResetAllControllersEvent m;
|
||||
m.channel = event->channel;
|
||||
m.value = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
LocalControlEvent AsLocalControl(MidiEvent* event) {
|
||||
LocalControlEvent m;
|
||||
m.channel = event->channel;
|
||||
m.local_control_off = (event->data[1] == 0);
|
||||
m.local_control_on = (event->data[1] == 127);
|
||||
return m;
|
||||
}
|
||||
|
||||
AllNotesOffEvent AsAllNotesOff(MidiEvent* event) {
|
||||
AllNotesOffEvent m;
|
||||
m.channel = event->channel;
|
||||
return m;
|
||||
}
|
||||
|
||||
OmniModeOffEvent AsOmniModeOff(MidiEvent* event) {
|
||||
OmniModeOffEvent m;
|
||||
m.channel = event->channel;
|
||||
return m;
|
||||
}
|
||||
|
||||
OmniModeOnEvent AsOmniModeOn(MidiEvent* event) {
|
||||
OmniModeOnEvent m;
|
||||
m.channel = event->channel;
|
||||
return m;
|
||||
}
|
||||
|
||||
MonoModeOnEvent AsMonoModeOn(MidiEvent* event) {
|
||||
MonoModeOnEvent m;
|
||||
m.channel = event->channel;
|
||||
m.num_channels = event->data[1];
|
||||
return m;
|
||||
}
|
||||
|
||||
PolyModeOnEvent AsPolyModeOn(MidiEvent* event) {
|
||||
PolyModeOnEvent m;
|
||||
m.channel = event->channel;
|
||||
return m;
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
typedef enum {
|
||||
NoteOff, /**< & */
|
||||
NoteOn, /**< & */
|
||||
PolyphonicKeyPressure, /**< & */
|
||||
ControlChange, /**< & */
|
||||
ProgramChange, /**< & */
|
||||
ChannelPressure, /**< & */
|
||||
PitchBend, /**< & */
|
||||
SystemCommon, /**< & */
|
||||
SystemRealTime, /**< & */
|
||||
ChannelMode, /**< & */
|
||||
MessageLast, /**< & */
|
||||
} MidiMessageType;
|
||||
|
||||
typedef enum {
|
||||
SystemExclusive, /**< & */
|
||||
MTCQuarterFrame, /**< & */
|
||||
SongPositionPointer, /**< & */
|
||||
SongSelect, /**< & */
|
||||
SCUndefined0, /**< & */
|
||||
SCUndefined1, /**< & */
|
||||
TuneRequest, /**< & */
|
||||
SysExEnd, /**< & */
|
||||
SystemCommonLast, /**< & */
|
||||
} SystemCommonType;
|
||||
|
||||
typedef enum {
|
||||
TimingClock, /**< & */
|
||||
SRTUndefined0, /**< & */
|
||||
Start, /**< & */
|
||||
Continue, /**< & */
|
||||
Stop, /**< & */
|
||||
SRTUndefined1, /**< & */
|
||||
ActiveSensing, /**< & */
|
||||
Reset, /**< & */
|
||||
SystemRealTimeLast, /**< & */
|
||||
} SystemRealTimeType;
|
||||
|
||||
typedef enum {
|
||||
AllSoundOff, /**< & */
|
||||
ResetAllControllers, /**< & */
|
||||
LocalControl, /**< & */
|
||||
AllNotesOff, /**< & */
|
||||
OmniModeOff, /**< & */
|
||||
OmniModeOn, /**< & */
|
||||
MonoModeOn, /**< & */
|
||||
PolyModeOn, /**< & */
|
||||
ChannelModeLast, /**< & */
|
||||
} ChannelModeType;
|
||||
|
||||
/** Struct containing note, and velocity data for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t note; /**< & */
|
||||
uint8_t velocity; /**< & */
|
||||
} NoteOffEvent;
|
||||
|
||||
/** Struct containing note, and velocity data for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t note; /**< & */
|
||||
uint8_t velocity; /**< & */
|
||||
} NoteOnEvent;
|
||||
|
||||
/** Struct containing note, and pressure data for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel;
|
||||
uint8_t note;
|
||||
uint8_t pressure;
|
||||
} PolyphonicKeyPressureEvent;
|
||||
|
||||
/** Struct containing control number, and value for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t control_number; /**< & */
|
||||
uint8_t value; /**< & */
|
||||
} ControlChangeEvent;
|
||||
|
||||
/** Struct containing new program number, for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t program; /**< & */
|
||||
} ProgramChangeEvent;
|
||||
|
||||
/** Struct containing pressure (aftertouch), for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t pressure; /**< & */
|
||||
} ChannelPressureEvent;
|
||||
|
||||
/** Struct containing pitch bend value for a given channel.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
int16_t value; /**< & */
|
||||
} PitchBendEvent;
|
||||
|
||||
/** Struct containing sysex data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int length;
|
||||
uint8_t data[SYSEX_BUFFER_LEN]; /**< & */
|
||||
} SystemExclusiveEvent;
|
||||
|
||||
/** Struct containing QuarterFrame data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t message_type; /**< & */
|
||||
uint8_t value; /**< & */
|
||||
} MTCQuarterFrameEvent;
|
||||
|
||||
/** Struct containing song position data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t position; /**< & */
|
||||
} SongPositionPointerEvent;
|
||||
|
||||
/** Struct containing song select data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t song; /**< & */
|
||||
} SongSelectEvent;
|
||||
|
||||
/** Struct containing sound off data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
} AllSoundOffEvent;
|
||||
|
||||
/** Struct containing ResetAllControllersEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t value; /**< & */
|
||||
} ResetAllControllersEvent;
|
||||
|
||||
/** Struct containing LocalControlEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
bool local_control_off; /**< & */
|
||||
bool local_control_on; /**< & */
|
||||
} LocalControlEvent;
|
||||
|
||||
/** Struct containing AllNotesOffEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
} AllNotesOffEvent;
|
||||
|
||||
/** Struct containing OmniModeOffEvent data.
|
||||
* Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
} OmniModeOffEvent;
|
||||
|
||||
/** Struct containing OmniModeOnEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
} OmniModeOnEvent;
|
||||
|
||||
/** Struct containing MonoModeOnEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
uint8_t num_channels; /**< & */
|
||||
} MonoModeOnEvent;
|
||||
|
||||
/** Struct containing PolyModeOnEvent data.
|
||||
Can be made from MidiEvent
|
||||
*/
|
||||
typedef struct {
|
||||
int channel; /**< & */
|
||||
} PolyModeOnEvent;
|
||||
|
||||
/** Simple MidiEvent with message type, channel, and data[2] members.
|
||||
*/
|
||||
typedef struct {
|
||||
MidiMessageType type;
|
||||
int channel;
|
||||
uint8_t data[2];
|
||||
uint8_t sysex_data[SYSEX_BUFFER_LEN];
|
||||
uint8_t sysex_message_len;
|
||||
SystemCommonType sc_type;
|
||||
SystemRealTimeType srt_type;
|
||||
ChannelModeType cm_type;
|
||||
} MidiEvent;
|
||||
|
||||
/** Returns the data within the MidiEvent as a NoteOffEvent struct */
|
||||
NoteOffEvent AsNoteOff(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a NoteOnEvent struct */
|
||||
NoteOnEvent AsNoteOn(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a PolyphonicKeyPressureEvent struct */
|
||||
PolyphonicKeyPressureEvent AsPolyphonicKeyPressure(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a ControlChangeEvent struct.*/
|
||||
ControlChangeEvent AsControlChange(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/
|
||||
ProgramChangeEvent AsProgramChange(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/
|
||||
ChannelPressureEvent AsChannelPressure(MidiEvent* event);
|
||||
|
||||
/** Returns the data within the MidiEvent as a PitchBendEvent struct.*/
|
||||
PitchBendEvent AsPitchBend(MidiEvent* event);
|
||||
|
||||
SystemExclusiveEvent AsSystemExclusive(MidiEvent* event);
|
||||
MTCQuarterFrameEvent AsMTCQuarterFrame(MidiEvent* event);
|
||||
SongPositionPointerEvent AsSongPositionPointer(MidiEvent* event);
|
||||
SongSelectEvent AsSongSelect(MidiEvent* event);
|
||||
AllSoundOffEvent AsAllSoundOff(MidiEvent* event);
|
||||
ResetAllControllersEvent AsResetAllControllers(MidiEvent* event);
|
||||
LocalControlEvent AsLocalControl(MidiEvent* event);
|
||||
AllNotesOffEvent AsAllNotesOff(MidiEvent* event);
|
||||
OmniModeOffEvent AsOmniModeOff(MidiEvent* event);
|
||||
OmniModeOnEvent AsOmniModeOn(MidiEvent* event);
|
||||
MonoModeOnEvent AsMonoModeOn(MidiEvent* event);
|
||||
PolyModeOnEvent AsPolyModeOn(MidiEvent* event);
|
||||
@@ -0,0 +1,149 @@
|
||||
#include <stdlib.h>
|
||||
#include "parser.h"
|
||||
|
||||
typedef enum {
|
||||
ParserEmpty,
|
||||
ParserHasStatus,
|
||||
ParserHasData0,
|
||||
ParserSysEx,
|
||||
} ParserState;
|
||||
|
||||
const uint8_t kStatusByteMask = 0x80;
|
||||
const uint8_t kMessageMask = 0x70;
|
||||
const uint8_t kDataByteMask = 0x7F;
|
||||
const uint8_t kSystemCommonMask = 0xF0;
|
||||
const uint8_t kChannelMask = 0x0F;
|
||||
const uint8_t kRealTimeMask = 0xF8;
|
||||
const uint8_t kSystemRealTimeMask = 0x07;
|
||||
|
||||
struct MidiParser {
|
||||
MidiMessageType status;
|
||||
ParserState state;
|
||||
MidiEvent incoming_message;
|
||||
};
|
||||
|
||||
MidiParser* midi_parser_alloc(void) {
|
||||
MidiParser* parser = malloc(sizeof(MidiParser));
|
||||
parser->incoming_message.type = MessageLast;
|
||||
parser->state = ParserEmpty;
|
||||
return parser;
|
||||
}
|
||||
|
||||
void midi_parser_free(MidiParser* parser) {
|
||||
free(parser);
|
||||
}
|
||||
|
||||
bool midi_parser_parse(MidiParser* parser, uint8_t byte) {
|
||||
bool parsed = false;
|
||||
MidiEvent* event = &parser->incoming_message;
|
||||
|
||||
switch(parser->state) {
|
||||
case ParserEmpty:
|
||||
// check byte for valid Status Byte
|
||||
if(byte & kStatusByteMask) {
|
||||
// Get MessageType, and Channel
|
||||
event->channel = byte & kChannelMask;
|
||||
event->type = (MidiMessageType)((byte & kMessageMask) >> 4);
|
||||
|
||||
// Validate, and move on.
|
||||
if(event->type < MessageLast) {
|
||||
parser->state = ParserHasStatus;
|
||||
// Mark this status byte as running_status
|
||||
parser->status = event->type;
|
||||
|
||||
if(parser->status == SystemCommon) {
|
||||
event->channel = 0;
|
||||
//system real time = 1111 1xxx
|
||||
if(byte & 0x08) {
|
||||
event->type = SystemRealTime;
|
||||
parser->status = SystemRealTime;
|
||||
event->srt_type = (SystemRealTimeType)(byte & kSystemRealTimeMask);
|
||||
|
||||
//short circuit to start
|
||||
parser->state = ParserEmpty;
|
||||
//queue_.push(incoming_message_);
|
||||
parsed = true;
|
||||
}
|
||||
//system common
|
||||
else {
|
||||
event->sc_type = (SystemCommonType)(byte & 0x07);
|
||||
//sysex
|
||||
if(event->sc_type == SystemExclusive) {
|
||||
parser->state = ParserSysEx;
|
||||
event->sysex_message_len = 0;
|
||||
}
|
||||
//short circuit
|
||||
else if(event->sc_type > SongSelect) {
|
||||
parser->state = ParserEmpty;
|
||||
//queue_.push(incoming_message_);
|
||||
parsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Else we'll keep waiting for a valid incoming status byte
|
||||
} else {
|
||||
// Handle as running status
|
||||
event->type = parser->status;
|
||||
event->data[0] = byte & kDataByteMask;
|
||||
parser->state = ParserHasData0;
|
||||
}
|
||||
break;
|
||||
case ParserHasStatus:
|
||||
if((byte & kStatusByteMask) == 0) {
|
||||
event->data[0] = byte & kDataByteMask;
|
||||
if(parser->status == ChannelPressure || parser->status == ProgramChange ||
|
||||
event->sc_type == MTCQuarterFrame || event->sc_type == SongSelect) {
|
||||
//these are just one data byte, so we short circuit back to start
|
||||
parser->state = ParserEmpty;
|
||||
//queue_.push(incoming_message_);
|
||||
parsed = true;
|
||||
} else {
|
||||
parser->state = ParserHasData0;
|
||||
}
|
||||
|
||||
//ChannelModeMessages (reserved Control Changes)
|
||||
if(parser->status == ControlChange && event->data[0] > 119) {
|
||||
event->type = ChannelMode;
|
||||
parser->status = ChannelMode;
|
||||
event->cm_type = (ChannelModeType)(event->data[0] - 120);
|
||||
}
|
||||
} else {
|
||||
// invalid message go back to start ;p
|
||||
parser->state = ParserEmpty;
|
||||
}
|
||||
break;
|
||||
case ParserHasData0:
|
||||
if((byte & kStatusByteMask) == 0) {
|
||||
event->data[1] = byte & kDataByteMask;
|
||||
// At this point the message is valid, and we can add this MidiEvent to the queue
|
||||
//queue_.push(incoming_message_);
|
||||
parsed = true;
|
||||
}
|
||||
// Regardless, of whether the data was valid or not we go back to empty
|
||||
// because either the message is queued for handling or its not.
|
||||
parser->state = ParserEmpty;
|
||||
break;
|
||||
case ParserSysEx:
|
||||
// end of sysex
|
||||
if(byte == 0xf7) {
|
||||
parser->state = ParserEmpty;
|
||||
//queue_.push(incoming_message_);
|
||||
parsed = true;
|
||||
} else {
|
||||
if(event->sysex_message_len < SYSEX_BUFFER_LEN) {
|
||||
event->sysex_data[event->sysex_message_len] = byte;
|
||||
event->sysex_message_len++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
MidiEvent* midi_parser_get_message(MidiParser* parser) {
|
||||
return &parser->incoming_message;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "message.h"
|
||||
|
||||
typedef struct MidiParser MidiParser;
|
||||
|
||||
MidiParser* midi_parser_alloc(void);
|
||||
|
||||
void midi_parser_free(MidiParser* parser);
|
||||
|
||||
bool midi_parser_parse(MidiParser* parser, uint8_t data);
|
||||
|
||||
MidiEvent* midi_parser_get_message(MidiParser* parser);
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "usb_message.h"
|
||||
|
||||
CodeIndex code_index_from_data(uint8_t data) {
|
||||
return (CodeIndex)(data & 0b00001111);
|
||||
}
|
||||
|
||||
uint8_t cable_id_from_data(uint8_t data) {
|
||||
return (data >> 4) & 0b00001111;
|
||||
}
|
||||
|
||||
uint8_t usb_message_data_size(CodeIndex code_index) {
|
||||
uint8_t data_size = 0;
|
||||
switch(code_index) {
|
||||
case CodeIndexCommon1Byte:
|
||||
/* case CodeIndexSysExEnd1Byte: */
|
||||
case CodeIndexSingleByte:
|
||||
data_size = 1;
|
||||
break;
|
||||
case CodeIndexSysEx2Byte:
|
||||
case CodeIndexSysExEnd2Byte:
|
||||
case CodeIndexProgramChange:
|
||||
case CodeIndexChannelPressure:
|
||||
data_size = 2;
|
||||
break;
|
||||
case CodeIndexSysEx3Byte:
|
||||
case CodeIndexSysExStart:
|
||||
case CodeIndexSysExEnd3Byte:
|
||||
case CodeIndexNoteOff:
|
||||
case CodeIndexNoteOn:
|
||||
case CodeIndexPolyKeyPress:
|
||||
case CodeIndexControlChange:
|
||||
case CodeIndexPitchBendChange:
|
||||
data_size = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return data_size;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
CodeIndexMisc = 0x0, /**< Reserved, MIDI Size: 1, 2, 3 */
|
||||
CodeIndexCableEvent = 0x1, /**< Reserved, MIDI Size: 1, 2, 3 */
|
||||
CodeIndexSysEx2Byte = 0x2, /**< MIDI Size: 2 */
|
||||
CodeIndexSysEx3Byte = 0x3, /**< MIDI Size: 3 */
|
||||
CodeIndexSysExStart = 0x4, /**< MIDI Size: 3 */
|
||||
CodeIndexCommon1Byte = 0x5, /**< MIDI Size: 1 */
|
||||
CodeIndexSysExEnd1Byte = 0x5, /**< MIDI Size: 1 */
|
||||
CodeIndexSysExEnd2Byte = 0x6, /**< MIDI Size: 2 */
|
||||
CodeIndexSysExEnd3Byte = 0x7, /**< MIDI Size: 3 */
|
||||
CodeIndexNoteOff = 0x8, /**< MIDI Size: 3 */
|
||||
CodeIndexNoteOn = 0x9, /**< MIDI Size: 3 */
|
||||
CodeIndexPolyKeyPress = 0xA, /**< MIDI Size: 3 */
|
||||
CodeIndexControlChange = 0xB, /**< MIDI Size: 3 */
|
||||
CodeIndexProgramChange = 0xC, /**< MIDI Size: 2 */
|
||||
CodeIndexChannelPressure = 0xD, /**< MIDI Size: 2 */
|
||||
CodeIndexPitchBendChange = 0xE, /**< MIDI Size: 3 */
|
||||
CodeIndexSingleByte = 0xF, /**< MIDI Size: 1 */
|
||||
} CodeIndex;
|
||||
|
||||
CodeIndex code_index_from_data(uint8_t data);
|
||||
|
||||
uint8_t cable_id_from_data(uint8_t data);
|
||||
|
||||
uint8_t usb_message_data_size(CodeIndex code_index);
|
||||
Reference in New Issue
Block a user