Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 46 additions & 46 deletions ump.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,24 @@

typedef enum
{
MIDI_CS_INTERFACE_HEADER = 0x01,
MIDI_CS_INTERFACE_IN_JACK = 0x02,
MIDI_CS_INTERFACE_OUT_JACK = 0x03,
MIDI_CS_INTERFACE_ELEMENT = 0x04,
MIDI_CS_INTERFACE_GR_TRM_BLOCK = 0x26,
} midi_cs_interface_subtype_t;
MIDI_1_CS_INTERFACE_HEADER = 0x01,
MIDI_1_CS_INTERFACE_IN_JACK = 0x02,
MIDI_1_CS_INTERFACE_OUT_JACK = 0x03,
MIDI_1_CS_INTERFACE_ELEMENT = 0x04,
MIDI_1_CS_INTERFACE_GR_TRM_BLOCK = 0x26,
} midi_1_cs_interface_subtype_t;

typedef enum
{
MIDI_CS_ENDPOINT_GENERAL = 0x01,
MIDI_1_CS_ENDPOINT_GENERAL = 0x01,
MIDI20_CS_ENDPOINT_GENERAL = 0x02,
} midi_cs_endpoint_subtype_t;
} midi_1_cs_endpoint_subtype_t;

typedef enum
{
MIDI_JACK_EMBEDDED = 0x01,
MIDI_JACK_EXTERNAL = 0x02
} midi_jack_type_t;
MIDI_1_JACK_EMBEDDED = 0x01,
MIDI_1_JACK_EXTERNAL = 0x02
} midi_1_jack_type_t;

typedef enum
{
Expand All @@ -122,47 +122,47 @@ typedef enum

typedef enum
{
MIDI_CIN_MISC = 0,
MIDI_CIN_CABLE_EVENT = 1,
MIDI_CIN_SYSCOM_2BYTE = 2, // 2 byte system common message e.g MTC, SongSelect
MIDI_CIN_SYSCOM_3BYTE = 3, // 3 byte system common message e.g SPP
MIDI_CIN_SYSEX_START = 4, // SysEx starts or continue
MIDI_CIN_SYSEX_END_1BYTE = 5, // SysEx ends with 1 data, or 1 byte system common message
MIDI_CIN_SYSEX_END_2BYTE = 6, // SysEx ends with 2 data
MIDI_CIN_SYSEX_END_3BYTE = 7, // SysEx ends with 3 data
MIDI_CIN_NOTE_ON = 8,
MIDI_CIN_NOTE_OFF = 9,
MIDI_CIN_POLY_KEYPRESS = 10,
MIDI_CIN_CONTROL_CHANGE = 11,
MIDI_CIN_PROGRAM_CHANGE = 12,
MIDI_CIN_CHANNEL_PRESSURE = 13,
MIDI_CIN_PITCH_BEND_CHANGE = 14,
MIDI_CIN_1BYTE_DATA = 15
} midi_code_index_number_t;
MIDI_1_CIN_MISC = 0,
MIDI_1_CIN_CABLE_EVENT = 1,
MIDI_1_CIN_SYSCOM_2BYTE = 2, // 2 byte system common message e.g MTC, SongSelect
MIDI_1_CIN_SYSCOM_3BYTE = 3, // 3 byte system common message e.g SPP
MIDI_1_CIN_SYSEX_START = 4, // SysEx starts or continue
MIDI_1_CIN_SYSEX_END_1BYTE = 5, // SysEx ends with 1 data, or 1 byte system common message
MIDI_1_CIN_SYSEX_END_2BYTE = 6, // SysEx ends with 2 data
MIDI_1_CIN_SYSEX_END_3BYTE = 7, // SysEx ends with 3 data
MIDI_1_CIN_NOTE_ON = 8,
MIDI_1_CIN_NOTE_OFF = 9,
MIDI_1_CIN_POLY_KEYPRESS = 10,
MIDI_1_CIN_CONTROL_CHANGE = 11,
MIDI_1_CIN_PROGRAM_CHANGE = 12,
MIDI_1_CIN_CHANNEL_PRESSURE = 13,
MIDI_1_CIN_PITCH_BEND_CHANGE = 14,
MIDI_1_CIN_1BYTE_DATA = 15
} midi_1_code_index_number_t;

// MIDI 1.0 status byte
enum
{
//------------- System Exclusive -------------//
MIDI_STATUS_SYSEX_START = 0xF0,
MIDI_STATUS_SYSEX_END = 0xF7,
MIDI_1_STATUS_SYSEX_START = 0xF0,
MIDI_1_STATUS_SYSEX_END = 0xF7,

//------------- System Common -------------//
MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME = 0xF1,
MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER = 0xF2,
MIDI_STATUS_SYSCOM_SONG_SELECT = 0xF3,
MIDI_1_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME = 0xF1,
MIDI_1_STATUS_SYSCOM_SONG_POSITION_POINTER = 0xF2,
MIDI_1_STATUS_SYSCOM_SONG_SELECT = 0xF3,
// F4, F5 is undefined
MIDI_STATUS_SYSCOM_TUNE_REQUEST = 0xF6,
MIDI_1_STATUS_SYSCOM_TUNE_REQUEST = 0xF6,

//------------- System RealTime -------------//
MIDI_STATUS_SYSREAL_TIMING_CLOCK = 0xF8,
MIDI_1_STATUS_SYSREAL_TIMING_CLOCK = 0xF8,
// 0xF9 is undefined
MIDI_STATUS_SYSREAL_START = 0xFA,
MIDI_STATUS_SYSREAL_CONTINUE = 0xFB,
MIDI_STATUS_SYSREAL_STOP = 0xFC,
MIDI_1_STATUS_SYSREAL_START = 0xFA,
MIDI_1_STATUS_SYSREAL_CONTINUE = 0xFB,
MIDI_1_STATUS_SYSREAL_STOP = 0xFC,
// 0xFD is undefined
MIDI_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE,
MIDI_STATUS_SYSREAL_SYSTEM_RESET = 0xFF,
MIDI_1_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE,
MIDI_1_STATUS_SYSREAL_SYSTEM_RESET = 0xFF,
};

/// MIDI Interface Header Descriptor
Expand All @@ -173,7 +173,7 @@ typedef struct TU_ATTR_PACKED
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
uint16_t wTotalLength ;
} midi_desc_header_t;
} midi_1_desc_header_t;

/// MIDI In Jack Descriptor
typedef struct TU_ATTR_PACKED
Expand All @@ -184,7 +184,7 @@ typedef struct TU_ATTR_PACKED
uint8_t bJackType ; ///< Embedded or External
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
uint8_t iJack ; ///< string descriptor
} midi_desc_in_jack_t;
} midi_1_desc_in_jack_t;


/// MIDI Out Jack Descriptor with single pin
Expand All @@ -201,7 +201,7 @@ typedef struct TU_ATTR_PACKED
uint8_t baSourcePin;

uint8_t iJack ; ///< string descriptor
} midi_desc_out_jack_t ;
} midi_1_desc_out_jack_t ;

/// MIDI Out Jack Descriptor with multiple pins
#define midi_desc_out_jack_n_t(input_num) \
Expand Down Expand Up @@ -238,7 +238,7 @@ typedef struct TU_ATTR_PACKED

uint16_t bmElementCaps;
uint8_t iElement;
} midi_desc_element_t;
} midi_1_desc_element_t;

/// MIDI Element Descriptor with multiple pins
#define midi_desc_element_n_t(input_num) \
Expand Down Expand Up @@ -285,7 +285,7 @@ typedef struct TU_ATTR_PACKED
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes: 5
uint8_t bDescriptorType ; ///< Descriptor Type: MIDI_CS_INTERFACE_GR_TRM_BLOCK
uint8_t bDescriptorType ; ///< Descriptor Type: MIDI_1_CS_INTERFACE_GR_TRM_BLOCK
uint8_t bDescriptorSubType ; ///< Descriptor SubType: MIDI_GR_TRM_BLOCK_HEADER
uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific Group Terminal Block descriptors. Includes the combined length of this header descriptor and all Group Terminal Block descriptors.
} midi2_desc_group_terminal_block_header_t;
Expand All @@ -294,7 +294,7 @@ typedef struct TU_ATTR_PACKED
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes: 13
uint8_t bDescriptorType ; ///< Descriptor Type: MIDI_CS_INTERFACE_GR_TRM_BLOCK
uint8_t bDescriptorType ; ///< Descriptor Type: MIDI_1_CS_INTERFACE_GR_TRM_BLOCK
uint8_t bDescriptorSubType ; ///< Descriptor SubType: MIDI_GR_TRM_BLOCK
uint8_t bGrpTrmBlkID ; ///< ID of this Group Terminal Block
uint8_t bGrpTrmBlkType ; ///< Group Terminal Block Type
Expand Down
70 changes: 35 additions & 35 deletions ump_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ static uint8_t default_ump_group_terminal_blk_desc[] =
{
// header
5, // bLength
MIDI_CS_INTERFACE_GR_TRM_BLOCK,
MIDI_1_CS_INTERFACE_GR_TRM_BLOCK,
MIDI_GR_TRM_BLOCK_HEADER,
U16_TO_U8S_LE(sizeof(midi2_cs_interface_desc_group_terminal_blocks_t)), // wTotalLength

// block
13, // bLength
MIDI_CS_INTERFACE_GR_TRM_BLOCK,
MIDI_1_CS_INTERFACE_GR_TRM_BLOCK,
MIDI_GR_TRM_BLOCK,
1, // bGrpTrmBlkID
0x00, // bGrpTrmBlkType: bi-directional
Expand Down Expand Up @@ -466,16 +466,16 @@ uint16_t tud_ump_write( uint8_t itf, uint32_t *words, uint16_t numWords )
case UMP_SYSTEM_UNDEFINED_F5:
case UMP_SYSTEM_UNDEFINED_F9:
case UMP_SYSTEM_UNDEFINED_FD:
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_CIN_SYSEX_END_1BYTE;
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_1_CIN_SYSEX_END_1BYTE;
break;

case UMP_SYSTEM_MTC:
case UMP_SYSTEM_SONG_SELECT:
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_CIN_SYSCOM_2BYTE;
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_1_CIN_SYSCOM_2BYTE;
break;

case UMP_SYSTEM_SONG_POS_PTR:
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_CIN_SYSCOM_3BYTE;
umpWritePacket.umpData.umpBytes[0] = (cbl_num << 4) | MIDI_1_CIN_SYSCOM_3BYTE;
break;

default:
Expand Down Expand Up @@ -543,7 +543,7 @@ uint16_t tud_ump_write( uint8_t itf, uint32_t *words, uint16_t numWords )

if (sysexStatus <= 1 && numberBytes < SYSEX_BS_RB_SIZE)
{
byteStream[numberBytes++] = MIDI_STATUS_SYSEX_START;
byteStream[numberBytes++] = MIDI_1_STATUS_SYSEX_START;
}
for (uint8_t count = 0; count < (umpPacket.umpData.umpBytes[1] & 0xf); count++)
{
Expand All @@ -554,7 +554,7 @@ uint16_t tud_ump_write( uint8_t itf, uint32_t *words, uint16_t numWords )
}
if ((sysexStatus == 0 || sysexStatus == 3) && numberBytes < SYSEX_BS_RB_SIZE)
{
byteStream[numberBytes++] = MIDI_STATUS_SYSEX_END;
byteStream[numberBytes++] = MIDI_1_STATUS_SYSEX_END;
}

// Move into sysex circular buffer queue
Expand Down Expand Up @@ -587,11 +587,11 @@ uint16_t tud_ump_write( uint8_t itf, uint32_t *words, uint16_t numWords )
// Mark cable number and CIN for start / continue SYSEX in USB MIDI 1.0 format
if (bEndSysex && !numberBytes)
{
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_CIN_SYSEX_END_3BYTE;
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_1_CIN_SYSEX_END_3BYTE;
}
else
{
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_CIN_SYSEX_START;
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_1_CIN_SYSEX_START;
}
}
else
Expand All @@ -613,12 +613,12 @@ uint16_t tud_ump_write( uint8_t itf, uint32_t *words, uint16_t numWords )
switch (count)
{
case 1:
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_CIN_SYSEX_END_1BYTE;
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_1_CIN_SYSEX_END_1BYTE;
break;

case 2:
default:
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_CIN_SYSEX_END_2BYTE;
pumpBytes[0] = (uint8_t)(cbl_num << 4) | MIDI_1_CIN_SYSEX_END_2BYTE;
break;
}
}
Expand Down Expand Up @@ -979,7 +979,7 @@ Return Value:
uint8_t code_index = pBuffer[0] & 0x0f;

// Handle special case of single byte data
if (code_index == MIDI_CIN_1BYTE_DATA && (pBuffer[1] & 0x80))
if (code_index == MIDI_1_CIN_1BYTE_DATA && (pBuffer[1] & 0x80))
{
switch (pBuffer[1])
{
Expand All @@ -994,7 +994,7 @@ Return Value:
case UMP_SYSTEM_UNDEFINED_F5:
case UMP_SYSTEM_UNDEFINED_F9:
case UMP_SYSTEM_UNDEFINED_FD:
code_index = MIDI_CIN_SYSEX_END_1BYTE;
code_index = MIDI_1_CIN_SYSEX_END_1BYTE;
break;

default:
Expand All @@ -1008,17 +1008,17 @@ Return Value:

switch (code_index)
{
case MIDI_CIN_SYSEX_START: // or continue
case MIDI_1_CIN_SYSEX_START: // or continue

if (!*pbIsInSysex)
{
// SYSEX Start means first byte should be SYSEX start
if (pBuffer[1] != MIDI_STATUS_SYSEX_START) return false;
if (pBuffer[1] != MIDI_1_STATUS_SYSEX_START) return false;
firstByte = 2;
lastByte = 4;

// As this is start of SYSEX, need to set status to indicate so and copy 2 bytes of data
// as first byte of MIDI_STATUS_SYSEX_START
// as first byte of MIDI_1_STATUS_SYSEX_START
umpPkt->umpData.umpBytes[1] = UMP_SYSEX7_START | 2;

// Set that in SYSEX
Expand Down Expand Up @@ -1046,10 +1046,10 @@ Return Value:
}
break;

case MIDI_CIN_SYSEX_END_1BYTE: // or single byte System Common
case MIDI_1_CIN_SYSEX_END_1BYTE: // or single byte System Common
// Determine if a system common
if ( (pBuffer[1] & 0x80) // most significant bit set and not sysex ending
&& (pBuffer[1] != MIDI_STATUS_SYSEX_END))
&& (pBuffer[1] != MIDI_1_STATUS_SYSEX_END))
{
umpPkt->umpData.umpBytes[0] = UMP_MT_SYSTEM | cbl_num;
umpPkt->umpData.umpBytes[1] = pBuffer[1];
Expand All @@ -1063,7 +1063,7 @@ Return Value:
// Determine if complete based on if currently in SYSEX
if (*pbIsInSysex)
{
if (pBuffer[1] != MIDI_STATUS_SYSEX_END) return false;
if (pBuffer[1] != MIDI_1_STATUS_SYSEX_END) return false;
umpPkt->umpData.umpBytes[1] = UMP_SYSEX7_END | 0;
*pbIsInSysex = false; // we are done with SYSEX
firstByte = 1;
Expand All @@ -1086,13 +1086,13 @@ Return Value:
}
break;

case MIDI_CIN_SYSEX_END_2BYTE:
case MIDI_1_CIN_SYSEX_END_2BYTE:
umpPkt->umpData.umpBytes[0] = UMP_MT_DATA_64 | cbl_num;

// Determine if complete based on if currently in SYSEX
if (*pbIsInSysex)
{
if (pBuffer[2] != MIDI_STATUS_SYSEX_END) return false;
if (pBuffer[2] != MIDI_1_STATUS_SYSEX_END) return false;
umpPkt->umpData.umpBytes[1] = UMP_SYSEX7_END | 1;
*pbIsInSysex = false; // we are done with SYSEX
firstByte = 1;
Expand All @@ -1116,21 +1116,21 @@ Return Value:
}
break;

case MIDI_CIN_SYSEX_END_3BYTE:
case MIDI_1_CIN_SYSEX_END_3BYTE:
umpPkt->umpData.umpBytes[0] = UMP_MT_DATA_64 | cbl_num;

// Determine if complete based on if currently in SYSEX
if (*pbIsInSysex)
{
if (pBuffer[3] != MIDI_STATUS_SYSEX_END) return false;
if (pBuffer[3] != MIDI_1_STATUS_SYSEX_END) return false;
umpPkt->umpData.umpBytes[1] = UMP_SYSEX7_END | 2;
*pbIsInSysex = false; // we are done with SYSEX
firstByte = 1;
lastByte = 3;
}
else
{
if (pBuffer[1] != MIDI_STATUS_SYSEX_START || pBuffer[3] != MIDI_STATUS_SYSEX_END) return false;
if (pBuffer[1] != MIDI_1_STATUS_SYSEX_START || pBuffer[3] != MIDI_1_STATUS_SYSEX_END) return false;
umpPkt->umpData.umpBytes[1] = UMP_SYSEX7_COMPLETE | 1;
*pbIsInSysex = false; // we are done with SYSEX
firstByte = 2;
Expand All @@ -1148,13 +1148,13 @@ Return Value:
break;

// MIDI1 Channel Voice Messages
case MIDI_CIN_NOTE_ON:
case MIDI_CIN_NOTE_OFF:
case MIDI_CIN_POLY_KEYPRESS:
case MIDI_CIN_CONTROL_CHANGE:
case MIDI_CIN_PROGRAM_CHANGE:
case MIDI_CIN_CHANNEL_PRESSURE:
case MIDI_CIN_PITCH_BEND_CHANGE:
case MIDI_1_CIN_NOTE_ON:
case MIDI_1_CIN_NOTE_OFF:
case MIDI_1_CIN_POLY_KEYPRESS:
case MIDI_1_CIN_CONTROL_CHANGE:
case MIDI_1_CIN_PROGRAM_CHANGE:
case MIDI_1_CIN_CHANNEL_PRESSURE:
case MIDI_1_CIN_PITCH_BEND_CHANGE:
umpPkt->umpData.umpBytes[0] = UMP_MT_MIDI1_CV | cbl_num; // message type 2
*pbIsInSysex = false; // ensure we end any current sysex packets, other layers need to handle error

Expand All @@ -1167,8 +1167,8 @@ Return Value:
umpPkt->wordCount = 1;
break;

case MIDI_CIN_SYSCOM_2BYTE:
case MIDI_CIN_SYSCOM_3BYTE:
case MIDI_1_CIN_SYSCOM_2BYTE:
case MIDI_1_CIN_SYSCOM_3BYTE:
umpPkt->umpData.umpBytes[0] = UMP_MT_SYSTEM | cbl_num;
for (int count = 1; count < 4; count++)
{
Expand All @@ -1177,8 +1177,8 @@ Return Value:
umpPkt->wordCount = 1;
break;

case MIDI_CIN_MISC:
case MIDI_CIN_CABLE_EVENT:
case MIDI_1_CIN_MISC:
case MIDI_1_CIN_CABLE_EVENT:
// These are reserved for future use and will not be translated, drop data with no processing
default:
// Not valid USB MIDI 1.0 transfer or NULL, skip
Expand Down