Improved loop handling

CQTexperiment
Chris Moeller 2013-10-15 12:46:44 -07:00
parent 2e553c7186
commit c3a4189ef4
4 changed files with 25 additions and 27 deletions

View File

@ -512,7 +512,7 @@ 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<uint8_t> data;
std::vector<std::size_t> track_positions; std::vector<std::size_t> track_positions;
@ -520,6 +520,11 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
std::vector<std::string> device_names; std::vector<std::string> device_names;
std::size_t track_count = m_tracks.size(); 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 ); track_positions.resize( track_count, 0 );
port_numbers.resize( track_count, 0 ); port_numbers.resize( track_count, 0 );
device_names.resize( track_count ); device_names.resize( track_count );
@ -604,6 +609,12 @@ void midi_container::serialize_as_stream( unsigned long subsong, std::vector<mid
if ( m_form == 2 && subsong ) tempo_track = subsong; if ( m_form == 2 && subsong ) tempo_track = subsong;
const midi_event & event = m_tracks[ next_track ][ track_positions[ next_track ] ]; 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 ); unsigned long timestamp_ms = timestamp_to_ms( event.m_timestamp, tempo_track );
if ( event.m_type != midi_event::extended ) 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 ]++; 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 void midi_container::serialize_as_standard_midi_file( std::vector<uint8_t> & p_midi_file ) const

View File

@ -216,7 +216,7 @@ public:
*/ */
void apply_hackfix( unsigned hack ); 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; void serialize_as_standard_midi_file( std::vector<uint8_t> & p_midi_file ) const;

View File

@ -45,7 +45,7 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign
{ {
assert(!mStream.size()); 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()) if (mStream.size())
{ {
@ -54,44 +54,25 @@ bool MIDIPlayer::Load(const midi_container & midi_file, unsigned subsong, unsign
uLoopMode = loop_mode; uLoopMode = loop_mode;
uTimeEnd = midi_file.get_timestamp_end( subsong ) + 1000;
if (uLoopMode & loop_mode_enable) if (uLoopMode & loop_mode_enable)
{ {
uTimeLoopStart = midi_file.get_timestamp_loop_start( subsong, true ); uTimeLoopStart = midi_file.get_timestamp_loop_start( subsong, true );
unsigned long uTimeLoopEnd = midi_file.get_timestamp_loop_end( 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 ) if ( uTimeLoopStart != ~0UL || uTimeLoopEnd != ~0UL )
{ {
uLoopMode |= loop_mode_force; uLoopMode |= loop_mode_force;
} }
if ( uTimeLoopStart != ~0 ) if ((uLoopMode & loop_mode_force))
{
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
{ {
unsigned long i; unsigned long i;
unsigned char note_on[128 * 16]; unsigned char note_on[128 * 16];
memset( note_on, 0, sizeof( note_on ) ); 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; uint32_t ev = mStream[ i ].m_event & 0x800000F0;
if ( ev == 0x90 || ev == 0x80 ) 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 ); 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 ); mStream.resize( i );
uTimeEnd = mStream[ i - 1 ].m_timestamp;
for ( unsigned long j = 0; j < 128 * 16; j++ ) for ( unsigned long j = 0; j < 128 * 16; j++ )
{ {
if ( note_on[ 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) if (uSampleRate != 1000)
{ {

View File

@ -48,6 +48,7 @@ private:
unsigned long uStreamLoopStart; unsigned long uStreamLoopStart;
unsigned long uTimeLoopStart; unsigned long uTimeLoopStart;
unsigned long uStreamEnd;
}; };
#endif #endif