Fixed some MIDI looping issues, and added support for RPG Maker loops
This commit is contained in:
parent
a87312b2da
commit
142a144b08
3 changed files with 59 additions and 22 deletions
|
@ -555,23 +555,12 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
|
||||||
{
|
{
|
||||||
const midi_event & event = track[ j ];
|
const midi_event & event = track[ j ];
|
||||||
if ( event.m_type == midi_event::control_change &&
|
if ( event.m_type == midi_event::control_change &&
|
||||||
( event.m_data[ 0 ] == 110 || event.m_data[ 0 ] == 111 ) )
|
event.m_data[ 0 ] == 110 )
|
||||||
{
|
{
|
||||||
if ( event.m_data[ 0 ] == 110 )
|
if ( event.m_data[ 1 ] != 0 && event.m_data[ 1 ] != 1 && event.m_data[ 1 ] != 127 )
|
||||||
{
|
{
|
||||||
if ( event.m_data[ 1 ] != 0 && event.m_data[ 1 ] != 1 && event.m_data[ 1 ] != 127 )
|
skip_track = true;
|
||||||
{
|
break;
|
||||||
skip_track = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( event.m_data[ 1 ] == 0 || event.m_data[ 1 ] == 1 )
|
|
||||||
{
|
|
||||||
skip_track = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 );
|
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;
|
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;
|
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 )
|
if ( p_xmi_loops )
|
||||||
{
|
{
|
||||||
for ( unsigned long i = 0; i < m_tracks.size(); ++i )
|
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 ( 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;
|
m_timestamp_loop_start[ subsong ] = event.m_timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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;
|
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 ( 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;
|
m_timestamp_loop_start[ subsong ] = event.m_timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( data_count == 7 && !strncasecmp( (const char *) &data[0], "loopEnd", 7 ) )
|
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;
|
m_timestamp_loop_end[ subsong ] = event.m_timestamp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ public:
|
||||||
|
|
||||||
void get_meta_data( unsigned long subsong, midi_meta_data & p_out );
|
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 );
|
static void encode_delta( std::vector<uint8_t> & p_out, unsigned long delta );
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
int track_num = [[[s url] fragment] intValue]; //What if theres no fragment? Assuming we get 0.
|
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 );
|
framesLength = midi_file.get_timestamp_end( track_num, true );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue