MIDI: Fix Standard MIDI track truncation issues

This commit is contained in:
Christopher Snowhill 2021-04-10 00:22:27 -07:00
parent 10856e6928
commit 9dd8dbe2f3
3 changed files with 21 additions and 10 deletions

View file

@ -39,7 +39,7 @@ class midi_processor
static bool is_gmf( std::vector<uint8_t> const& p_file ); static bool is_gmf( std::vector<uint8_t> const& p_file );
static bool is_syx( std::vector<uint8_t> const& p_file ); static bool is_syx( std::vector<uint8_t> const& p_file );
static void process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool needs_end_marker ); static void process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool is_gmf );
static bool process_standard_midi( std::vector<uint8_t> const& p_file, midi_container & p_out ); static bool process_standard_midi( std::vector<uint8_t> const& p_file, midi_container & p_out );
static bool process_riff_midi( std::vector<uint8_t> const& p_file, midi_container & p_out ); static bool process_riff_midi( std::vector<uint8_t> const& p_file, midi_container & p_out );

View file

@ -48,7 +48,7 @@ bool midi_processor::process_gmf( std::vector<uint8_t> const& p_file, midi_conta
std::vector<uint8_t>::const_iterator it = p_file.begin() + 7; std::vector<uint8_t>::const_iterator it = p_file.begin() + 7;
process_standard_midi_track( it, p_file.end(), p_out, false ); process_standard_midi_track( it, p_file.end(), p_out, true );
return true; return true;
} }

View file

@ -30,8 +30,10 @@ bool midi_processor::process_standard_midi_count( std::vector<uint8_t> const& p_
return true; return true;
} }
void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool needs_end_marker ) void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_iterator & it, std::vector<uint8_t>::const_iterator end, midi_container & p_out, bool is_gmf )
{ {
bool needs_end_marker = false;
midi_track track; midi_track track;
unsigned current_timestamp = 0; unsigned current_timestamp = 0;
unsigned last_event_timestamp = 0; unsigned last_event_timestamp = 0;
@ -56,10 +58,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
} }
if ( delta > 1000000 ) if ( delta > 1000000 )
{
needs_end_marker = false;
break; break;
}
current_timestamp += delta; current_timestamp += delta;
if ( it == end ) break; if ( it == end ) break;
@ -80,23 +79,29 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
} }
last_event_code = event_code; last_event_code = event_code;
if ( !needs_end_marker && ( event_code & 0xF0 ) == 0xE0 ) continue; if ( is_gmf && ( event_code & 0xF0 ) == 0xE0 ) continue;
if ( data_bytes_read < 1 ) if ( data_bytes_read < 1 )
{ {
if ( it == end ) break; if ( it == end ) break;
buffer[ 0 ] = *it++; buffer[ 0 ] = *it++;
++data_bytes_read; ++data_bytes_read;
} }
bool command_valid = true;
switch ( event_code & 0xF0 ) switch ( event_code & 0xF0 )
{ {
case 0xC0: case 0xC0:
case 0xD0: case 0xD0:
break; break;
default: default:
if ( it == end ) break; if ( it == end )
{
command_valid = false;
break;
}
buffer[ data_bytes_read ] = *it++; buffer[ data_bytes_read ] = *it++;
++data_bytes_read; ++data_bytes_read;
} }
if ( !command_valid ) break;
track.add_event( midi_event( last_event_timestamp = current_timestamp, (midi_event::event_type)(( event_code >> 4 ) - 8), event_code & 0x0F, &buffer[0], data_bytes_read ) ); track.add_event( midi_event( last_event_timestamp = current_timestamp, (midi_event::event_type)(( event_code >> 4 ) - 8), event_code & 0x0F, &buffer[0], data_bytes_read ) );
} }
else if ( event_code == 0xF0 ) else if ( event_code == 0xF0 )
@ -107,6 +112,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
last_sysex_length = 0; last_sysex_length = 0;
} }
if ( it == end ) break;
int data_count = decode_delta( it, end ); int data_count = decode_delta( it, end );
if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid System Exclusive message" );*/ if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid System Exclusive message" );*/
if ( end - it < data_count ) break; if ( end - it < data_count ) break;
@ -120,6 +126,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
else if ( event_code == 0xF7 ) // SysEx continuation else if ( event_code == 0xF7 ) // SysEx continuation
{ {
if ( !last_sysex_length ) break; if ( !last_sysex_length ) break;
if ( it == end ) break;
int data_count = decode_delta( it, end ); int data_count = decode_delta( it, end );
if ( data_count < 0 ) break; if ( data_count < 0 ) break;
if ( end - it < data_count ) break; if ( end - it < data_count ) break;
@ -138,6 +145,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
if ( it == end ) break; if ( it == end ) break;
unsigned char meta_type = *it++; unsigned char meta_type = *it++;
if ( it == end ) break;
int data_count = decode_delta( it, end ); int data_count = decode_delta( it, end );
if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid meta message" );*/ if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid meta message" );*/
if ( end - it < data_count ) break; if ( end - it < data_count ) break;
@ -219,7 +227,10 @@ bool midi_processor::process_standard_midi( std::vector<uint8_t> const& p_file,
intptr_t track_data_offset = it - p_file.begin(); intptr_t track_data_offset = it - p_file.begin();
process_standard_midi_track( it, it + track_size, p_out, true ); if ( (unsigned long)(end - it) < track_size )
track_size = (uint32_t)(end - it);
process_standard_midi_track( it, it + track_size, p_out, false );
track_data_offset += track_size; track_data_offset += track_size;
size_t messup_offset = it - p_file.begin(); size_t messup_offset = it - p_file.begin();