Improved loop handling
parent
2e553c7186
commit
c3a4189ef4
|
@ -512,13 +512,18 @@ void midi_container::apply_hackfix( unsigned hack )
|
|||
}
|
||||
}
|
||||
|
||||
void midi_container::serialize_as_stream( unsigned long subsong, std::vector<midi_stream_event> & p_stream, system_exclusive_table & p_system_exclusive, unsigned clean_flags ) const
|
||||
void midi_container::serialize_as_stream( unsigned long subsong, std::vector<midi_stream_event> & p_stream, system_exclusive_table & p_system_exclusive, unsigned long & loop_start, unsigned long & loop_end, unsigned clean_flags ) const
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
std::vector<std::size_t> track_positions;
|
||||
std::vector<uint8_t> port_numbers;
|
||||
std::vector<std::string> 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<mid
|
|||
if ( m_form == 2 && subsong ) tempo_track = subsong;
|
||||
|
||||
const midi_event & event = m_tracks[ next_track ][ track_positions[ next_track ] ];
|
||||
|
||||
if ( local_loop_start == ~0UL && event.m_timestamp >= 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<mid
|
|||
|
||||
track_positions[ next_track ]++;
|
||||
}
|
||||
|
||||
loop_start = local_loop_start;
|
||||
loop_end = local_loop_end;
|
||||
}
|
||||
|
||||
void midi_container::serialize_as_standard_midi_file( std::vector<uint8_t> & p_midi_file ) const
|
||||
|
|
|
@ -216,7 +216,7 @@ public:
|
|||
*/
|
||||
void apply_hackfix( unsigned hack );
|
||||
|
||||
void serialize_as_stream( unsigned long subsong, std::vector<midi_stream_event> & p_stream, system_exclusive_table & p_system_exclusive, unsigned clean_flags ) const;
|
||||
void serialize_as_stream( unsigned long subsong, std::vector<midi_stream_event> & 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<uint8_t> & p_midi_file ) const;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
|
||||
unsigned long uStreamLoopStart;
|
||||
unsigned long uTimeLoopStart;
|
||||
unsigned long uStreamEnd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue