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,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

View File

@ -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;

View File

@ -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)
{

View File

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