/** * used by the cacheAudioEventsForMeasure-method, this collects * all AudioEvents in the requested measure for entry into the BulkCacher * * @param bufferPosition {int} the desired measures buffers start pointer * @param bufferEnd {int} the desired measures buffers end pointer * * @return {std::vector<BaseCacheableAudioEvent*>} */ std::vector<BaseCacheableAudioEvent*>* Sequencer::collectCacheableSequencerEvents( int bufferPosition, int bufferEnd ) { std::vector<BaseCacheableAudioEvent*>* events = new std::vector<BaseCacheableAudioEvent*>(); for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i ) { std::vector<BaseAudioEvent*>* audioEvents = instruments.at( i )->getEvents(); int amount = ( int ) audioEvents->size(); for ( int j = 0; j < amount; j++ ) { BaseAudioEvent* audioEvent = audioEvents->at( j ); // if event is an instance of BaseCacheableAudioEvent add it to the list if ( dynamic_cast<BaseCacheableAudioEvent*>( audioEvent ) != nullptr ) { int eventStart = audioEvent->getEventStart(); int eventEnd = audioEvent->getEventEnd(); if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) || ( eventStart < bufferPosition && eventEnd >= bufferPosition )) { if ( !audioEvent->isDeletable()) events->push_back(( BaseCacheableAudioEvent* ) audioEvent ); } } } } return events; }
/** * 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 Sequencer::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 = ( int ) audioEvents->size(); for ( ; i < amount; i++ ) { BaseAudioEvent* audioEvent = audioEvents->at( i ); if ( audioEvent->isEnabled() ) { int eventStart = audioEvent->getEventStart(); int eventEnd = audioEvent->getEventEnd(); if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) || ( eventStart < bufferPosition && eventEnd >= 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 ) { for ( i = 0; i < removes.size(); i++ ) { BaseAudioEvent* audioEvent = removes[ i ]; instrument->removeEvent( audioEvent, false ); } } }