refactor midi write into stream

This commit is contained in:
hathach 2021-04-02 14:26:55 +07:00
parent 6b04efd443
commit 08fe16840f
1 changed files with 37 additions and 40 deletions

View File

@ -67,11 +67,7 @@ typedef struct
// 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.
uint8_t write_buffer[4];
uint8_t write_buffer_length;
uint8_t write_target_length;
// midid_stream_t stream_write;
midid_stream_t stream_write;
uint8_t read_buffer[4];
uint8_t read_buffer_length;
@ -229,7 +225,7 @@ uint32_t tud_midi_n_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer,
midid_interface_t* midi = &_midid_itf[itf];
TU_VERIFY(midi->itf_num, 0);
// midid_stream_t* stream = &midi->stream_write;
midid_stream_t* stream = &midi->stream_write;
uint32_t written = 0;
uint32_t i = 0;
@ -237,93 +233,94 @@ uint32_t tud_midi_n_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer,
{
uint8_t const data = buffer[i];
if ( midi->write_buffer_length == 0 )
if ( stream->index == 0 )
{
// new packet
// new event packet
uint8_t const msg = data >> 4;
midi->write_buffer[1] = data;
midi->write_buffer_length = 2;
stream->index = 2;
stream->buffer[1] = data;
// Check to see if we're still in a SysEx transmit.
if ( midi->write_buffer[0] == MIDI_CIN_SYSEX_START )
if ( stream->buffer[0] == MIDI_CIN_SYSEX_START )
{
if ( data == MIDI_STATUS_SYSEX_END )
{
midi->write_buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
midi->write_target_length = 2;
stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
stream->total = 2;
}
else
{
midi->write_target_length = 4;
stream->total = 4;
}
}
else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE )
{
// Channel Voice Messages
midi->write_buffer[0] = (cable_num << 4) | msg;
midi->write_target_length = 4;
stream->buffer[0] = (cable_num << 4) | msg;
stream->total = 4;
}
else if ( msg == 0xf )
{
// System message
if ( data == MIDI_STATUS_SYSEX_START )
{
midi->write_buffer[0] = MIDI_CIN_SYSEX_START;
midi->write_target_length = 4;
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 )
{
midi->write_buffer[0] = MIDI_CIN_SYSCOM_2BYTE;
midi->write_target_length = 3;
stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE;
stream->total = 3;
}
else if ( data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER )
{
midi->write_buffer[0] = MIDI_CIN_SYSCOM_3BYTE;
midi->write_target_length = 4;
stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE;
stream->total = 4;
}
else
{
midi->write_buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
midi->write_target_length = 2;
stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
stream->total = 2;
}
}
else
{
// Pack individual bytes if we don't support packing them into words.
midi->write_buffer[0] = cable_num << 4 | 0xf;
midi->write_buffer[2] = 0;
midi->write_buffer[3] = 0;
midi->write_buffer_length = 2;
midi->write_target_length = 2;
stream->buffer[0] = cable_num << 4 | 0xf;
stream->buffer[2] = 0;
stream->buffer[3] = 0;
stream->index = 2;
stream->total = 2;
}
}
else
{
// On-going packet
// On-going (buffering) packet
TU_ASSERT(midi->write_buffer_length < 4, 0);
midi->write_buffer[midi->write_buffer_length] = data;
midi->write_buffer_length++;
TU_ASSERT(stream->index < 4, written);
stream->buffer[stream->index] = data;
stream->index++;
// See if this byte ends a SysEx.
if ( midi->write_buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END )
if ( stream->buffer[0] == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END )
{
midi->write_buffer[0] = MIDI_CIN_SYSEX_START + (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;
}
}
// Send out packet
if ( midi->write_buffer_length == midi->write_target_length )
if ( stream->index == stream->total )
{
// zeroes unused bytes
for(uint8_t idx = midi->write_target_length; idx < 4; idx++) midi->write_buffer[idx] = 0;
for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0;
uint16_t const count = tu_fifo_write_n(&midi->tx_ff, midi->write_buffer, 4);
uint16_t const count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4);
// reset buffer
midi->write_buffer_length = midi->write_target_length = 0;
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;