From 142a144b08f77e1eb73bab5bc801c7b3c9122ef4 Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Sat, 14 Dec 2013 19:56:59 -0800 Subject: [PATCH] Fixed some MIDI looping issues, and added support for RPG Maker loops --- .../midi_processing/midi_container.cpp | 77 ++++++++++++++----- .../midi_processing/midi_container.h | 2 +- Plugins/MIDI/MIDI/MIDIDecoder.mm | 2 +- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Frameworks/midi_processing/midi_processing/midi_container.cpp b/Frameworks/midi_processing/midi_processing/midi_container.cpp index fa8d75c7c..f8be45d38 100644 --- a/Frameworks/midi_processing/midi_processing/midi_container.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_container.cpp @@ -555,23 +555,12 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector 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; } diff --git a/Frameworks/midi_processing/midi_processing/midi_container.h b/Frameworks/midi_processing/midi_processing/midi_container.h index 95ac0da20..b613d001a 100644 --- a/Frameworks/midi_processing/midi_processing/midi_container.h +++ b/Frameworks/midi_processing/midi_processing/midi_container.h @@ -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 & p_out, unsigned long delta ); }; diff --git a/Plugins/MIDI/MIDI/MIDIDecoder.mm b/Plugins/MIDI/MIDI/MIDIDecoder.mm index a2c534b84..077a55f10 100755 --- a/Plugins/MIDI/MIDI/MIDIDecoder.mm +++ b/Plugins/MIDI/MIDI/MIDIDecoder.mm @@ -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 );