98 lines
2.5 KiB
C++
98 lines
2.5 KiB
C++
// intellectual property is bullshit bgdc
|
|
|
|
#ifndef MIDI_H
|
|
#define MIDI_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <inttypes.h>
|
|
|
|
class midix;
|
|
|
|
// == MIDI COMMANDS ===========================================================
|
|
|
|
// All midi commands use values >= 0x80 as the high bit marks the start of a
|
|
// packet. We use values < 0x80 as internal events so all may share the same
|
|
// queue.
|
|
|
|
struct midi_message {
|
|
midix * source;
|
|
uint8_t command;
|
|
union {
|
|
uint8_t arguments[2];
|
|
uint8_t * content;
|
|
};
|
|
};
|
|
|
|
#define MIDI_CMD_HAS_CHAN(cmd) ((cmd) >= 0x80 && (cmd) <= 0xEF)
|
|
#define MIDI_CMD_CHAN(cmd) ((cmd) & 0x0F)
|
|
#define MIDI_CMD(cmd) (MIDI_CMD_HAS_CHAN(cmd) ? ((cmd) & 0xF0) : (cmd))
|
|
|
|
// Internal command events
|
|
|
|
#define MIDI_ICMD_NOP 0x00
|
|
#define MIDI_ICMD_SYSEX 0x01 // sysex text via midi_message.content,
|
|
// NUL-terminated
|
|
#define MIDI_ICMD_SYSEX_OVERFLOW 0x02
|
|
|
|
// MIDI events
|
|
|
|
#define MIDI_CMD_NOTE_OFF 0x80 // key velocity
|
|
#define MIDI_CMD_NOTE_ON 0x90 // key velocity
|
|
#define MIDI_CMD_AFTERTOUCH 0xA0 // key touch
|
|
#define MIDI_CMD_CC 0xB0 // cc# value
|
|
#define MIDI_CMD_PATCH 0xC0 // inst# ?
|
|
#define MIDI_CMD_PRESSURE 0xD0 // pres -n/a-
|
|
#define MIDI_CMD_PITCHBEND 0xE0 // lsb msb
|
|
|
|
|
|
#define MIDI_CMD_START_SYSEX 0xF0
|
|
#define MIDI_CMD_TIMECODE_QFRM 0xF1
|
|
#define MIDI_CMD_SONG_POS_PTR 0xF2
|
|
#define MIDI_CMD_SONG_SELECT 0xF3
|
|
#define MIDI_CMD_TUNE_REQ 0xF6
|
|
#define MIDI_CMD_END_SYSEX 0xF7
|
|
#define MIDI_CMD_TIMING_CLK 0xF8
|
|
#define MIDI_CMD_START 0xFA
|
|
#define MIDI_CMD_CONTINUE 0xFB
|
|
#define MIDI_CMD_STOP 0xFC
|
|
#define MIDI_CMD_ACTIVESENSE 0xFE
|
|
#define MIDI_CMD_SYSRESET 0xFF
|
|
|
|
// Convert a single MIDI argument to a signed int
|
|
static inline int midi_signed(uint8_t arg)
|
|
{
|
|
uint16_t v = arg;
|
|
if (arg & 0x40)
|
|
v |= 0xFF80;
|
|
return (int16_t) v;
|
|
}
|
|
|
|
// Convert two MIDI arguments to a signed int
|
|
static inline int midi_double_signed(uint8_t lsb, uint8_t msb)
|
|
{
|
|
uint16_t v = lsb | (msb << 7);
|
|
if (v & 0x2000)
|
|
v |= 0xC000;
|
|
return (int16_t) v;
|
|
}
|
|
|
|
// Return the number of arguments expected for a command
|
|
static inline int midi_num_args(uint8_t cmd)
|
|
{
|
|
cmd = MIDI_CMD(cmd);
|
|
switch (cmd)
|
|
{
|
|
case MIDI_CMD_NOTE_OFF: return 2;
|
|
case MIDI_CMD_NOTE_ON: return 2;
|
|
case MIDI_CMD_AFTERTOUCH: return 2;
|
|
case MIDI_CMD_CC: return 2;
|
|
case MIDI_CMD_PATCH: return 2;
|
|
case MIDI_CMD_PRESSURE: return 1;
|
|
case MIDI_CMD_PITCHBEND: return 2;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
#endif // !defined(MIDI_H)
|