diff --git a/Frameworks/midi_processing/midi_processing/midi_container.cpp b/Frameworks/midi_processing/midi_processing/midi_container.cpp index a5912b141..42674cb9c 100644 --- a/Frameworks/midi_processing/midi_processing/midi_container.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_container.cpp @@ -512,13 +512,18 @@ void midi_container::apply_hackfix( unsigned hack ) } } -void midi_container::serialize_as_stream( unsigned long subsong, std::vector & p_stream, system_exclusive_table & p_system_exclusive, unsigned clean_flags ) const +void midi_container::serialize_as_stream( unsigned long subsong, std::vector & p_stream, system_exclusive_table & p_system_exclusive, unsigned long & loop_start, unsigned long & loop_end, unsigned clean_flags ) const { std::vector data; std::vector track_positions; std::vector port_numbers; std::vector device_names; std::size_t track_count = m_tracks.size(); + + unsigned long tick_loop_start = get_timestamp_loop_start(subsong); + unsigned long tick_loop_end = get_timestamp_loop_end(subsong); + unsigned long local_loop_start = ~0UL; + unsigned long local_loop_end = ~0UL; track_positions.resize( track_count, 0 ); port_numbers.resize( track_count, 0 ); @@ -604,6 +609,12 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector= tick_loop_start ) + local_loop_start = p_stream.size(); + if ( local_loop_end == ~0UL && event.m_timestamp > tick_loop_end ) + local_loop_end = p_stream.size(); + unsigned long timestamp_ms = timestamp_to_ms( event.m_timestamp, tempo_track ); if ( event.m_type != midi_event::extended ) { @@ -673,6 +684,9 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector & p_midi_file ) const diff --git a/Frameworks/midi_processing/midi_processing/midi_container.h b/Frameworks/midi_processing/midi_processing/midi_container.h index a44bd0ab1..2385f45e9 100644 --- a/Frameworks/midi_processing/midi_processing/midi_container.h +++ b/Frameworks/midi_processing/midi_processing/midi_container.h @@ -216,7 +216,7 @@ public: */ void apply_hackfix( unsigned hack ); - void serialize_as_stream( unsigned long subsong, std::vector & p_stream, system_exclusive_table & p_system_exclusive, unsigned clean_flags ) const; + void serialize_as_stream( unsigned long subsong, std::vector & p_stream, system_exclusive_table & p_system_exclusive, unsigned long & loop_start, unsigned long & loop_end, unsigned clean_flags ) const; void serialize_as_standard_midi_file( std::vector & p_midi_file ) const; diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.cpp b/Plugins/MIDI/MIDI/MIDIPlayer.cpp index d753f3472..cae2b3950 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.cpp +++ b/Plugins/MIDI/MIDI/MIDIPlayer.cpp @@ -45,7 +45,7 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign { assert(!mStream.size()); - midi_file.serialize_as_stream( subsong, mStream, mSysexMap, clean_flags ); + midi_file.serialize_as_stream( subsong, mStream, mSysexMap, uStreamLoopStart, uStreamEnd, clean_flags ); if (mStream.size()) { @@ -53,45 +53,26 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign uTimeCurrent = 0; uLoopMode = loop_mode; + + uTimeEnd = midi_file.get_timestamp_end( subsong ) + 1000; if (uLoopMode & loop_mode_enable) { uTimeLoopStart = midi_file.get_timestamp_loop_start( subsong, true ); unsigned long uTimeLoopEnd = midi_file.get_timestamp_loop_end( subsong, true ); - uTimeEnd = midi_file.get_timestamp_end( subsong, true ); if ( uTimeLoopStart != ~0UL || uTimeLoopEnd != ~0UL ) { uLoopMode |= loop_mode_force; } - if ( uTimeLoopStart != ~0 ) - { - for ( unsigned i = 0; i < mStream.size(); ++i ) - { - if ( mStream[ i ].m_timestamp >= uTimeLoopStart ) - { - uStreamLoopStart = i; - break; - } - } - } - else uStreamLoopStart = ~0UL; - - if ( uTimeLoopEnd != ~0UL ) - { - uTimeEnd = uTimeLoopEnd; - } - - if (!(uLoopMode & loop_mode_force)) uTimeEnd += 1000; - else + if ((uLoopMode & loop_mode_force)) { unsigned long i; unsigned char note_on[128 * 16]; memset( note_on, 0, sizeof( note_on ) ); - for (i = 0; i < mStream.size(); i++) + for (i = 0; i < mStream.size() && i < uStreamEnd; i++) { - if (mStream[ i ].m_timestamp > uTimeEnd) break; uint32_t ev = mStream[ i ].m_event & 0x800000F0; if ( ev == 0x90 || ev == 0x80 ) { @@ -103,7 +84,9 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign note_on [ ch * 128 + note ] = ( note_on [ ch * 128 + note ] & ~bit ) | ( bit * on ); } } + unsigned long uSavedEndTime = ( i < mStream.size() ) ? mStream[ i ].m_timestamp : mStream[ mStream.size() - 1 ].m_timestamp + 1; mStream.resize( i ); + uTimeEnd = mStream[ i - 1 ].m_timestamp; for ( unsigned long j = 0; j < 128 * 16; j++ ) { if ( note_on[ j ] ) @@ -117,9 +100,9 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign } } } + uTimeEnd = uSavedEndTime; } } - else uTimeEnd = midi_file.get_timestamp_end( subsong, true ) + 1000; if (uSampleRate != 1000) { diff --git a/Plugins/MIDI/MIDI/MIDIPlayer.h b/Plugins/MIDI/MIDI/MIDIPlayer.h index 9332f63eb..3ecabfeb4 100644 --- a/Plugins/MIDI/MIDI/MIDIPlayer.h +++ b/Plugins/MIDI/MIDI/MIDIPlayer.h @@ -48,6 +48,7 @@ private: unsigned long uStreamLoopStart; unsigned long uTimeLoopStart; + unsigned long uStreamEnd; }; #endif