Merge pull request #766 from hathach/enhance-midi

Enhance midi
This commit is contained in:
Ha Thach 2021-04-02 15:47:40 +07:00 committed by GitHub
commit eb92986b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 299 additions and 164 deletions

View File

@ -172,7 +172,7 @@ void midi_task(void)
// regardless of these being used or not. Therefore incoming traffic should be read // regardless of these being used or not. Therefore incoming traffic should be read
// (possibly just discarded) to avoid the sender blocking in IO // (possibly just discarded) to avoid the sender blocking in IO
uint8_t packet[4]; uint8_t packet[4];
while(tud_midi_available()) tud_midi_receive(packet); while( tud_midi_available() ) tud_midi_packet_read(packet);
// send note every 1000 ms // send note every 1000 ms
if (board_millis() - start_ms < 286) return; // not enough time if (board_millis() - start_ms < 286) return; // not enough time
@ -186,10 +186,12 @@ void midi_task(void)
if (previous < 0) previous = sizeof(note_sequence) - 1; if (previous < 0) previous = sizeof(note_sequence) - 1;
// Send Note On for current position at full velocity (127) on channel 1. // Send Note On for current position at full velocity (127) on channel 1.
tud_midi_write24(cable_num, 0x90 | channel, note_sequence[note_pos], 127); uint8_t note_on[3] = { 0x90 | channel, note_sequence[note_pos], 127 };
tud_midi_stream_write(cable_num, note_on, 3);
// Send Note Off for previous note. // Send Note Off for previous note.
tud_midi_write24(cable_num, 0x80 | channel, note_sequence[previous], 0); uint8_t note_off[3] = { 0x80 | channel, note_sequence[previous], 0};
tud_midi_stream_write(cable_num, note_off, 3);
// Increment position // Increment position
note_pos++; note_pos++;

View File

@ -132,7 +132,7 @@ void midi_task(void)
// regardless of these being used or not. Therefore incoming traffic should be read // regardless of these being used or not. Therefore incoming traffic should be read
// (possibly just discarded) to avoid the sender blocking in IO // (possibly just discarded) to avoid the sender blocking in IO
uint8_t packet[4]; uint8_t packet[4];
while(tud_midi_available()) tud_midi_receive(packet); while ( tud_midi_available() ) tud_midi_packet_read(packet);
// send note every 1000 ms // send note every 1000 ms
if (board_millis() - start_ms < 286) return; // not enough time if (board_millis() - start_ms < 286) return; // not enough time
@ -146,10 +146,12 @@ void midi_task(void)
if (previous < 0) previous = sizeof(note_sequence) - 1; if (previous < 0) previous = sizeof(note_sequence) - 1;
// Send Note On for current position at full velocity (127) on channel 1. // Send Note On for current position at full velocity (127) on channel 1.
tud_midi_write24(cable_num, 0x90 | channel, note_sequence[note_pos], 127); uint8_t note_on[3] = { 0x90 | channel, note_sequence[note_pos], 127 };
tud_midi_stream_write(cable_num, note_on, 3);
// Send Note Off for previous note. // Send Note Off for previous note.
tud_midi_write24(cable_num, 0x80 | channel, note_sequence[previous], 0); uint8_t note_off[3] = { 0x80 | channel, note_sequence[previous], 0};
tud_midi_stream_write(cable_num, note_off, 3);
// Increment position // Increment position
note_pos++; note_pos++;

View File

@ -61,6 +61,51 @@ typedef enum
MIDI_JACK_EXTERNAL = 0x02 MIDI_JACK_EXTERNAL = 0x02
} midi_jack_type_t; } midi_jack_type_t;
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.0 status byte
enum
{
//------------- System Exclusive -------------//
MIDI_STATUS_SYSEX_START = 0xF0,
MIDI_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,
// F4, F5 is undefined
MIDI_STATUS_SYSCOM_TUNE_REQUEST = 0xF6,
//------------- System RealTime -------------//
MIDI_STATUS_SYSREAL_TIMING_CLOCK = 0xF8,
// 0xF9 is undefined
MIDI_STATUS_SYSREAL_START = 0xFA,
MIDI_STATUS_SYSREAL_CONTINUE = 0xFB,
MIDI_STATUS_SYSREAL_STOP = 0xFC,
// 0xFD is undefined
MIDI_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE,
MIDI_STATUS_SYSREAL_SYSTEM_RESET = 0xFF,
};
/// MIDI Interface Header Descriptor /// MIDI Interface Header Descriptor
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {

View File

@ -38,12 +38,26 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF // MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
typedef struct
{
uint8_t buffer[4];
uint8_t index;
uint8_t total;
}midid_stream_t;
typedef struct typedef struct
{ {
uint8_t itf_num; uint8_t itf_num;
uint8_t ep_in; uint8_t ep_in;
uint8_t ep_out; uint8_t ep_out;
// For Stream read()/write() API
// Messages are always 4 bytes long, queue them for reading and writing so the
// callers can use the Stream interface with single-byte read/write calls.
midid_stream_t stream_write;
midid_stream_t stream_read;
/*------------- From this point, data is not cleared by bus reset -------------*/ /*------------- From this point, data is not cleared by bus reset -------------*/
// FIFO // FIFO
tu_fifo_t rx_ff; tu_fifo_t rx_ff;
@ -56,16 +70,6 @@ typedef struct
osal_mutex_def_t tx_ff_mutex; osal_mutex_def_t tx_ff_mutex;
#endif #endif
// Messages are always 4 bytes long, queue them for reading and writing so the
// callers can use the Stream interface with single-byte read/write calls.
uint8_t write_buffer[4];
uint8_t write_buffer_length;
uint8_t write_target_length;
uint8_t read_buffer[4];
uint8_t read_buffer_length;
uint8_t read_target_length;
// Endpoint Transfer buffer // Endpoint Transfer buffer
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EP_BUFSIZE];
@ -120,53 +124,77 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num)
return tu_fifo_count(&_midid_itf[itf].rx_ff); return tu_fifo_count(&_midid_itf[itf].rx_ff);
} }
uint32_t tud_midi_n_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize)
{ {
(void) cable_num; (void) cable_num;
TU_VERIFY(bufsize, 0);
uint8_t* buf8 = (uint8_t*) buffer;
midid_interface_t* midi = &_midid_itf[itf]; midid_interface_t* midi = &_midid_itf[itf];
midid_stream_t* stream = &midi->stream_read;
// Fill empty buffer uint32_t total_read = 0;
if (midi->read_buffer_length == 0) { while( bufsize )
if (!tud_midi_n_receive(itf, midi->read_buffer)) return 0; {
// Get new packet from fifo, then set packet expected bytes
if ( stream->total == 0 )
{
// return if there is no more data from fifo
if ( !tud_midi_n_packet_read(itf, stream->buffer) ) return total_read;
uint8_t code_index = midi->read_buffer[0] & 0x0f; uint8_t const code_index = stream->buffer[0] & 0x0f;
// We always copy over the first byte.
uint8_t count = 1; // MIDI 1.0 Table 4-1: Code Index Number Classifications
// Ignore subsequent bytes based on the code. switch(code_index)
if (code_index != 0x5 && code_index != 0xf) { {
count = 2; case MIDI_CIN_MISC:
if (code_index != 0x2 && code_index != 0x6 && code_index != 0xc && code_index != 0xd) { case MIDI_CIN_CABLE_EVENT:
count = 3; // These are reserved and unused, possibly issue somewhere, skip this packet
return 0;
break;
case MIDI_CIN_SYSEX_END_1BYTE:
case MIDI_CIN_1BYTE_DATA:
stream->total = 1;
break;
case MIDI_CIN_SYSCOM_2BYTE :
case MIDI_CIN_SYSEX_END_2BYTE :
case MIDI_CIN_PROGRAM_CHANGE :
case MIDI_CIN_CHANNEL_PRESSURE :
stream->total = 2;
break;
default:
stream->total = 3;
break;
} }
} }
midi->read_buffer_length = count; // Copy data up to bufsize
uint32_t const count = tu_min32(stream->total - stream->index, bufsize);
// Skip the header (1st byte) in the buffer
memcpy(buf8, stream->buffer + 1 + stream->index, count);
total_read += count;
stream->index += count;
buf8 += count;
bufsize -= count;
// complete current event packet, reset stream
if ( stream->total == stream->index )
{
stream->index = 0;
stream->total = 0;
}
} }
uint32_t n = midi->read_buffer_length - midi->read_target_length; return total_read;
if (bufsize < n) n = bufsize;
// Skip the header in the buffer
memcpy(buffer, midi->read_buffer + 1 + midi->read_target_length, n);
midi->read_target_length += n;
if (midi->read_target_length == midi->read_buffer_length) {
midi->read_buffer_length = 0;
midi->read_target_length = 0;
}
return n;
} }
void tud_midi_n_read_flush (uint8_t itf, uint8_t cable_num) bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4])
{
(void) cable_num;
midid_interface_t* p_midi = &_midid_itf[itf];
tu_fifo_clear(&p_midi->rx_ff);
_prep_out_transaction(p_midi);
}
bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4])
{ {
midid_interface_t* p_midi = &_midid_itf[itf]; midid_interface_t* p_midi = &_midid_itf[itf];
uint32_t num_read = tu_fifo_read_n(&p_midi->rx_ff, packet, 4); uint32_t num_read = tu_fifo_read_n(&p_midi->rx_ff, packet, 4);
@ -174,10 +202,6 @@ bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4])
return (num_read == 4); return (num_read == 4);
} }
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
tu_fifo_write_n(&midi->rx_ff, buffer, bufsize);
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// WRITE API // WRITE API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -193,7 +217,8 @@ static uint32_t write_flush(midid_interface_t* midi)
TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 );
uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EP_BUFSIZE);
if (count > 0)
if (count)
{ {
TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, midi->epin_buf, count), 0 ); TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, midi->epin_buf, count), 0 );
return count; return count;
@ -205,88 +230,131 @@ static uint32_t write_flush(midid_interface_t* midi)
} }
} }
uint32_t tud_midi_n_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
{ {
midid_interface_t* midi = &_midid_itf[itf]; midid_interface_t* midi = &_midid_itf[itf];
if (midi->itf_num == 0) { TU_VERIFY(midi->itf_num, 0);
return 0;
}
midid_stream_t* stream = &midi->stream_write;
uint32_t total_written = 0;
uint32_t i = 0; uint32_t i = 0;
while (i < bufsize) { while ( i < bufsize )
uint8_t data = buffer[i]; {
if (midi->write_buffer_length == 0) { uint8_t const data = buffer[i];
uint8_t msg = data >> 4;
midi->write_buffer[1] = data; if ( stream->index == 0 )
midi->write_buffer_length = 2; {
// new event packet
uint8_t const msg = data >> 4;
stream->index = 2;
stream->buffer[1] = data;
// Check to see if we're still in a SysEx transmit. // Check to see if we're still in a SysEx transmit.
if (midi->write_buffer[0] == 0x4) { if ( stream->buffer[0] == MIDI_CIN_SYSEX_START )
if (data == 0xf7) { {
midi->write_buffer[0] = 0x5; if ( data == MIDI_STATUS_SYSEX_END )
midi->write_target_length = 2; {
} else { stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
midi->write_target_length = 4; stream->total = 2;
} }
} else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) { else
midi->write_buffer[0] = cable_num << 4 | msg; {
midi->write_target_length = 4; stream->total = 4;
} else if (msg == 0xf) {
if (data == 0xf0) {
midi->write_buffer[0] = 0x4;
midi->write_target_length = 4;
} else if (data == 0xf1 || data == 0xf3) {
midi->write_buffer[0] = 0x2;
midi->write_target_length = 3;
} else if (data == 0xf2) {
midi->write_buffer[0] = 0x3;
midi->write_target_length = 4;
} else {
midi->write_buffer[0] = 0x5;
midi->write_target_length = 2;
} }
} else { }
else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE )
{
// Channel Voice Messages
stream->buffer[0] = (cable_num << 4) | msg;
stream->total = 4;
}
else if ( msg == 0xf )
{
// System message
if ( data == MIDI_STATUS_SYSEX_START )
{
stream->buffer[0] = MIDI_CIN_SYSEX_START;
stream->total = 4;
}
else if ( data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT )
{
stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE;
stream->total = 3;
}
else if ( data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER )
{
stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE;
stream->total = 4;
}
else
{
stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
stream->total = 2;
}
}
else
{
// Pack individual bytes if we don't support packing them into words. // Pack individual bytes if we don't support packing them into words.
midi->write_buffer[0] = cable_num << 4 | 0xf; stream->buffer[0] = cable_num << 4 | 0xf;
midi->write_buffer[2] = 0; stream->buffer[2] = 0;
midi->write_buffer[3] = 0; stream->buffer[3] = 0;
midi->write_buffer_length = 2; stream->index = 2;
midi->write_target_length = 2; stream->total = 2;
} }
} else { }
midi->write_buffer[midi->write_buffer_length] = data; else
midi->write_buffer_length += 1; {
// On-going (buffering) packet
TU_ASSERT(stream->index < 4, total_written);
stream->buffer[stream->index] = data;
stream->index++;
// See if this byte ends a SysEx. // See if this byte ends a SysEx.
if (midi->write_buffer[0] == 0x4 && data == 0xf7) { if ( stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END )
midi->write_buffer[0] = 0x4 + (midi->write_buffer_length - 1); {
midi->write_target_length = midi->write_buffer_length; stream->buffer[0] = MIDI_CIN_SYSEX_START + (stream->index - 1);
stream->total = stream->index;
} }
} }
if (midi->write_buffer_length == midi->write_target_length) { // Send out packet
uint16_t written = tu_fifo_write_n(&midi->tx_ff, midi->write_buffer, 4); if ( stream->index == stream->total )
if (written < 4) { {
TU_ASSERT( written == 0 ); // zeroes unused bytes
break; for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0;
}
midi->write_buffer_length = 0; uint16_t const count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4);
// complete current event packet, reset stream
stream->index = stream->total = 0;
// fifo overflow, here we assume FIFO is multiple of 4 and didn't check remaining before writing
if ( count != 4 ) break;
// updated written if succeeded
total_written = i;
} }
i++; i++;
} }
write_flush(midi); write_flush(midi);
return i; return total_written;
} }
bool tud_midi_n_send (uint8_t itf, uint8_t const packet[4]) bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4])
{ {
midid_interface_t* midi = &_midid_itf[itf]; midid_interface_t* midi = &_midid_itf[itf];
if (midi->itf_num == 0) { if (midi->itf_num == 0) {
return 0; return 0;
} }
if (tu_fifo_remaining(&midi->tx_ff) < 4) if (tu_fifo_remaining(&midi->tx_ff) < 4) return false;
return false;
tu_fifo_write_n(&midi->tx_ff, packet, 4); tu_fifo_write_n(&midi->tx_ff, packet, 4);
write_flush(midi); write_flush(midi);

View File

@ -59,29 +59,64 @@
// Application API (Multiple Interfaces) // Application API (Multiple Interfaces)
// CFG_TUD_MIDI > 1 // CFG_TUD_MIDI > 1
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Check if midi interface is mounted
bool tud_midi_n_mounted (uint8_t itf); bool tud_midi_n_mounted (uint8_t itf);
// Get the number of bytes available for reading
uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num); uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num);
uint32_t tud_midi_n_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize);
void tud_midi_n_read_flush (uint8_t itf, uint8_t cable_num);
uint32_t tud_midi_n_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
static inline // Read byte stream (legacy)
uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t cable_num, uint8_t b1, uint8_t b2, uint8_t b3); uint32_t tud_midi_n_stream_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize);
bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4]); // Write byte Stream (legacy)
bool tud_midi_n_send (uint8_t itf, uint8_t const packet[4]); uint32_t tud_midi_n_stream_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
// Read event packet (4 bytes)
bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]);
// Write event packet (4 bytes)
bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]);
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Application API (Single Interface) // Application API (Single Interface)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline bool tud_midi_mounted (void); static inline bool tud_midi_mounted (void);
static inline uint32_t tud_midi_available (void); static inline uint32_t tud_midi_available (void);
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize);
static inline void tud_midi_read_flush (void); static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize);
static inline uint32_t tud_midi_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize); static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
static inline uint32_t tud_midi_write24 (uint8_t cable_num, uint8_t b1, uint8_t b2, uint8_t b3);
static inline bool tud_midi_receive (uint8_t packet[4]); static inline bool tud_midi_packet_read (uint8_t packet[4]);
static inline bool tud_midi_send (uint8_t const packet[4]); static inline bool tud_midi_packet_write (uint8_t const packet[4]);
//------------- Deprecated API name -------------//
// TODO remove after 0.10.0 release
TU_ATTR_DEPRECATED("tud_midi_read() is renamed to tud_midi_stream_read()")
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize)
{
return tud_midi_stream_read(buffer, bufsize);
}
TU_ATTR_DEPRECATED("tud_midi_write() is renamed to tud_midi_stream_write()")
static inline uint32_t tud_midi_write(uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
{
return tud_midi_stream_write(cable_num, buffer, bufsize);
}
TU_ATTR_DEPRECATED("tud_midi_send() is renamed to tud_midi_packet_write()")
static inline bool tud_midi_send(uint8_t packet[4])
{
return tud_midi_packet_write(packet);
}
TU_ATTR_DEPRECATED("tud_midi_receive() is renamed to tud_midi_packet_read()")
static inline bool tud_midi_receive(uint8_t packet[4])
{
return tud_midi_packet_read(packet);
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Application Callback API (weak is optional) // Application Callback API (weak is optional)
@ -92,12 +127,6 @@ TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf);
// Inline Functions // Inline Functions
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t cable_num, uint8_t b1, uint8_t b2, uint8_t b3)
{
uint8_t msg[3] = { b1, b2, b3 };
return tud_midi_n_write(itf, cable_num, msg, 3);
}
static inline bool tud_midi_mounted (void) static inline bool tud_midi_mounted (void)
{ {
return tud_midi_n_mounted(0); return tud_midi_n_mounted(0);
@ -108,35 +137,24 @@ static inline uint32_t tud_midi_available (void)
return tud_midi_n_available(0, 0); return tud_midi_n_available(0, 0);
} }
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize)
{ {
return tud_midi_n_read(0, 0, buffer, bufsize); return tud_midi_n_stream_read(0, 0, buffer, bufsize);
} }
static inline void tud_midi_read_flush (void) static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
{ {
tud_midi_n_read_flush(0, 0); return tud_midi_n_stream_write(0, cable_num, buffer, bufsize);
} }
static inline uint32_t tud_midi_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) static inline bool tud_midi_packet_read (uint8_t packet[4])
{ {
return tud_midi_n_write(0, cable_num, buffer, bufsize); return tud_midi_n_packet_read(0, packet);
} }
static inline uint32_t tud_midi_write24 (uint8_t cable_num, uint8_t b1, uint8_t b2, uint8_t b3) static inline bool tud_midi_packet_write (uint8_t const packet[4])
{ {
uint8_t msg[3] = { b1, b2, b3 }; return tud_midi_n_packet_write(0, packet);
return tud_midi_write(cable_num, msg, 3);
}
static inline bool tud_midi_receive (uint8_t packet[4])
{
return tud_midi_n_receive(0, packet);
}
static inline bool tud_midi_send (uint8_t const packet[4])
{
return tud_midi_n_send(0, packet);
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+