MIDI: Fix Standard MIDI track truncation issues

CQTexperiment
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_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_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;
process_standard_midi_track( it, p_file.end(), p_out, false );
process_standard_midi_track( it, p_file.end(), p_out, true );
return true;
}

View File

@ -30,8 +30,10 @@ bool midi_processor::process_standard_midi_count( std::vector<uint8_t> const& p_
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;
unsigned current_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 )
{
needs_end_marker = false;
break;
}
current_timestamp += delta;
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;
if ( !needs_end_marker && ( event_code & 0xF0 ) == 0xE0 ) continue;
if ( is_gmf && ( event_code & 0xF0 ) == 0xE0 ) continue;
if ( data_bytes_read < 1 )
{
if ( it == end ) break;
buffer[ 0 ] = *it++;
++data_bytes_read;
}
bool command_valid = true;
switch ( event_code & 0xF0 )
{
case 0xC0:
case 0xD0:
break;
default:
if ( it == end ) break;
if ( it == end )
{
command_valid = false;
break;
}
buffer[ data_bytes_read ] = *it++;
++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 ) );
}
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;
}
if ( it == end ) break;
int data_count = decode_delta( it, end );
if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid System Exclusive message" );*/
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
{
if ( !last_sysex_length ) break;
if ( it == end ) break;
int data_count = decode_delta( it, end );
if ( data_count < 0 ) 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;
unsigned char meta_type = *it++;
if ( it == end ) break;
int data_count = decode_delta( it, end );
if ( data_count < 0 ) break; /*throw exception_io_data( "Invalid meta message" );*/
if ( end - it < data_count ) break;
@ -146,7 +154,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
buffer[ 1 ] = meta_type;
std::copy( it, it + data_count, buffer.begin() + 2 );
it += data_count;
if (meta_type == 0x2F)
if ( meta_type == 0x2F )
current_timestamp = last_event_timestamp;
else
last_event_timestamp = current_timestamp;
@ -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();
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;
size_t messup_offset = it - p_file.begin();