/** * used by the getAudioEvents-method of the sequencer, this validates * the present AudioEvents against the requested position * and updates and flushes the removal queue * * @param instrument {BaseInstrument*} instrument to gather events from * @param bufferPosition {int} the current buffers start pointer * @param bufferEnd {int} the current buffers end pointer */ void collectSequencedEvents( BaseInstrument* instrument, int bufferPosition, int bufferEnd ) { if ( !instrument->hasEvents() ) return; AudioChannel* channel = instrument->audioChannel; std::vector<BaseAudioEvent*>* audioEvents = instrument->getEvents(); // removal queue std::vector<BaseAudioEvent*> removes; // channel has an internal loop (e.g. drum machine) ? recalculate requested // buffer position by subtracting all measures above the first if ( channel->maxBufferPosition > 0 ) { int samplesPerBar = AudioEngine::samples_per_bar; while ( bufferPosition >= channel->maxBufferPosition ) { bufferPosition -= samplesPerBar; bufferEnd -= samplesPerBar; } } int i = 0, amount = audioEvents->size(); for ( i; i < amount; i++ ) { BaseAudioEvent* audioEvent = audioEvents->at( i ); if ( audioEvent->isEnabled() ) { int sampleStart = audioEvent->getSampleStart(); int sampleEnd = audioEvent->getSampleEnd(); if ( audioEvent->isLoopeable() || ( sampleStart >= bufferPosition && sampleStart <= bufferEnd ) || ( sampleStart < bufferPosition && sampleEnd >= bufferPosition )) { if ( !audioEvent->isDeletable()) channel->addEvent( audioEvent ); else removes.push_back( audioEvent ); } } } // removal queue filled ? process it so we can safely // remove "deleted" AudioEvents without errors occurring if ( removes.size() > 0 ) { int i = 0; for ( i; i < removes.size(); i++ ) { BaseAudioEvent* audioEvent = removes[ i ]; instrument->removeEvent( audioEvent, false ); } } }
TEST( BaseAudioEvent, LoopeableState ) { BaseAudioEvent* audioEvent = new BaseAudioEvent(); ASSERT_FALSE( audioEvent->isLoopeable() ) << "expected audio event not to be loopeable after construction"; audioEvent->setLoopeable( true ); ASSERT_TRUE( audioEvent->isLoopeable() ) << "expected audio event to be loopeable after enabling loop"; audioEvent->setLoopeable( false ); ASSERT_FALSE( audioEvent->isLoopeable() ) << "expected audio event not to be loopeable after disabling loop"; deleteAudioEvent( audioEvent ); }