Fixed some MIDI looping issues, and added support for RPG Maker loops

This commit is contained in:
Chris Moeller 2013-12-14 19:56:59 -08:00
parent a87312b2da
commit 142a144b08
3 changed files with 59 additions and 22 deletions

View file

@ -555,9 +555,7 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
{
const midi_event & event = track[ j ];
if ( event.m_type == midi_event::control_change &&
( event.m_data[ 0 ] == 110 || event.m_data[ 0 ] == 111 ) )
{
if ( event.m_data[ 0 ] == 110 )
event.m_data[ 0 ] == 110 )
{
if ( event.m_data[ 1 ] != 0 && event.m_data[ 1 ] != 1 && event.m_data[ 1 ] != 127 )
{
@ -565,15 +563,6 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
break;
}
}
else
{
if ( event.m_data[ 1 ] == 0 || event.m_data[ 1 ] == 1 )
{
skip_track = true;
break;
}
}
}
}
if ( skip_track )
{
@ -1041,7 +1030,7 @@ void midi_container::get_meta_data( unsigned long subsong, midi_meta_data & p_ou
p_out.append( m_extra_meta_data );
}
void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops )
void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops, bool p_rpgmaker_loops )
{
std::vector<uint8_t> data;
@ -1056,6 +1045,54 @@ void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops )
m_timestamp_loop_end[ i ] = ~0UL;
}
if ( p_rpgmaker_loops )
{
bool emidi_commands_found = false;
for ( unsigned long i = 0; i < m_tracks.size(); ++i )
{
unsigned long subsong = 0;
if ( m_form == 2 ) subsong = i;
const midi_track & track = m_tracks[ i ];
for ( unsigned long j = 0; j < track.get_count(); ++j )
{
const midi_event & event = track[ j ];
if ( event.m_type == midi_event::control_change &&
( event.m_data[ 0 ] == 110 || event.m_data[ 0 ] == 111 ) )
{
if ( event.m_data[ 0 ] == 110 ||
( event.m_data[ 0 ] == 111 && event.m_data[ 1 ] > 1 ) )
{
emidi_commands_found = true;
break;
}
if ( event.m_data[ 1 ] == 0 )
{
if ( m_timestamp_loop_start[ subsong ] == ~0UL || m_timestamp_loop_start[ subsong ] > event.m_timestamp )
{
m_timestamp_loop_start[ subsong ] = event.m_timestamp;
}
}
else
{
if ( m_timestamp_loop_end[ subsong ] == ~0UL || m_timestamp_loop_end[ subsong ] < event.m_timestamp )
{
m_timestamp_loop_end[ subsong ] = event.m_timestamp;
}
}
}
}
if ( emidi_commands_found )
{
m_timestamp_loop_start[ subsong ] = ~0UL;
m_timestamp_loop_end[ subsong ] = ~0UL;
break;
}
}
}
if ( p_xmi_loops )
{
for ( unsigned long i = 0; i < m_tracks.size(); ++i )
@ -1072,14 +1109,14 @@ void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops )
{
if ( event.m_data[ 0 ] == 0x74 )
{
if ( m_timestamp_loop_start[ subsong ] == ~0u || m_timestamp_loop_start[ subsong ] > event.m_timestamp )
if ( m_timestamp_loop_start[ subsong ] == ~0UL || m_timestamp_loop_start[ subsong ] > event.m_timestamp )
{
m_timestamp_loop_start[ subsong ] = event.m_timestamp;
}
}
else
{
if ( m_timestamp_loop_end[ subsong ] == ~0u || m_timestamp_loop_end[ subsong ] < event.m_timestamp )
if ( m_timestamp_loop_end[ subsong ] == ~0UL || m_timestamp_loop_end[ subsong ] < event.m_timestamp )
{
m_timestamp_loop_end[ subsong ] = event.m_timestamp;
}
@ -1110,14 +1147,14 @@ void midi_container::scan_for_loops( bool p_xmi_loops, bool p_marker_loops )
if ( data_count == 9 && !strncasecmp( (const char *) &data[0], "loopStart", 9 ) )
{
if ( m_timestamp_loop_start[ subsong ] == ~0u || m_timestamp_loop_start[ subsong ] > event.m_timestamp )
if ( m_timestamp_loop_start[ subsong ] == ~0UL || m_timestamp_loop_start[ subsong ] > event.m_timestamp )
{
m_timestamp_loop_start[ subsong ] = event.m_timestamp;
}
}
else if ( data_count == 7 && !strncasecmp( (const char *) &data[0], "loopEnd", 7 ) )
{
if ( m_timestamp_loop_end[ subsong ] == ~0u || m_timestamp_loop_end[ subsong ] < event.m_timestamp )
if ( m_timestamp_loop_end[ subsong ] == ~0UL || m_timestamp_loop_end[ subsong ] < event.m_timestamp )
{
m_timestamp_loop_end[ subsong ] = event.m_timestamp;
}

View file

@ -241,7 +241,7 @@ public:
void get_meta_data( unsigned long subsong, midi_meta_data & p_out );
void scan_for_loops( bool p_xmi_loops, bool p_marker_loops );
void scan_for_loops( bool p_xmi_loops, bool p_marker_loops, bool p_rpgmaker_loops );
static void encode_delta( std::vector<uint8_t> & p_out, unsigned long delta );
};

View file

@ -48,7 +48,7 @@
int track_num = [[[s url] fragment] intValue]; //What if theres no fragment? Assuming we get 0.
midi_file.scan_for_loops( true, true );
midi_file.scan_for_loops( true, true, true );
framesLength = midi_file.get_timestamp_end( track_num, true );