MIDI: Fix Standard MIDI track truncation issues
This commit is contained in:
parent
10856e6928
commit
9dd8dbe2f3
3 changed files with 21 additions and 10 deletions
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -146,7 +154,7 @@ void midi_processor::process_standard_midi_track( std::vector<uint8_t>::const_it
|
||||||
buffer[ 1 ] = meta_type;
|
buffer[ 1 ] = meta_type;
|
||||||
std::copy( it, it + data_count, buffer.begin() + 2 );
|
std::copy( it, it + data_count, buffer.begin() + 2 );
|
||||||
it += data_count;
|
it += data_count;
|
||||||
if (meta_type == 0x2F)
|
if ( meta_type == 0x2F )
|
||||||
current_timestamp = last_event_timestamp;
|
current_timestamp = last_event_timestamp;
|
||||||
else
|
else
|
||||||
last_event_timestamp = current_timestamp;
|
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();
|
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();
|
||||||
|
|
Loading…
Reference in a new issue