poly-1-fw/midi.hpp

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)