diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index 15efb82aa..9c4c1d2b4 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -31,6 +31,7 @@ #include "PlayHandle.h" #include "track.h" #include "MemoryManager.h" +#include class InstrumentTrack; class NotePlayHandle; @@ -335,6 +336,7 @@ private: static NotePlayHandleList s_nphCache; static NotePlayHandleList s_available; static QMutex s_mutex; + static QAtomicInt s_availableIndex; }; diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 3d1149c01..1afc1cb23 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -260,8 +260,10 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n ) // create sub-note-play-handle, only note is // different - NotePlayHandleManager::acquire( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy, - _n, -1, NotePlayHandle::OriginNoteStacking ); + engine::mixer()->addPlayHandle( + NotePlayHandleManager::acquire( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy, + _n, -1, NotePlayHandle::OriginNoteStacking ) + ); } } } @@ -377,7 +379,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) cnphv.first()->totalFramesPlayed() : _n->totalFramesPlayed() ) + arp_frames - 1; // used for loop - f_cnt_t frames_processed = 0; + f_cnt_t frames_processed = ( m_arpModeModel.value() != FreeMode ) ? cnphv.first()->noteOffset() : _n->noteOffset(); while( frames_processed < engine::mixer()->framesPerPeriod() ) { @@ -471,12 +473,14 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) // create sub-note-play-handle, only ptr to note is different // and is_arp_note=true - NotePlayHandleManager::acquire( _n->instrumentTrack(), - ( ( m_arpModeModel.value() != FreeMode ) ? cnphv.first()->offset() : _n->offset() ) + frames_processed, + engine::mixer()->addPlayHandle( + NotePlayHandleManager::acquire( _n->instrumentTrack(), + frames_processed, gated_frames, note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, (volume_t) qRound( _n->getVolume() * vol_level ), _n->getPanning(), _n->detuning() ), - _n, -1, NotePlayHandle::OriginArpeggio ); + _n, -1, NotePlayHandle::OriginArpeggio ) + ); // update counters frames_processed += arp_frames; diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index fc8e33f4c..2be424f72 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -145,10 +145,6 @@ void NotePlayHandle::done() m_instrumentTrack->m_notes[key()] = NULL; } - foreach( NotePlayHandle * n, m_subNotes ) - { - NotePlayHandleManager::release( n ); - } m_subNotes.clear(); delete m_filter; @@ -295,14 +291,15 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) } // play sub-notes (e.g. chords) - foreach( NotePlayHandle * n, m_subNotes ) + // handled by mixer now +/* foreach( NotePlayHandle * n, m_subNotes ) { n->play( _working_buffer ); if( n->isFinished() ) { NotePlayHandleManager::release( n ); } - } + }*/ // update internal data m_totalFramesPlayed += framesThisPeriod; @@ -363,7 +360,9 @@ void NotePlayHandle::noteOff( const f_cnt_t _s ) // first note-off all sub-notes foreach( NotePlayHandle * n, m_subNotes ) { + n->lock(); n->noteOff( _s ); + n->unlock(); } // then set some variables indicating release-state @@ -549,7 +548,7 @@ void NotePlayHandle::resize( const bpm_t _new_tempo ) NotePlayHandleList NotePlayHandleManager::s_nphCache; NotePlayHandleList NotePlayHandleManager::s_available; QMutex NotePlayHandleManager::s_mutex; - +QAtomicInt NotePlayHandleManager::s_availableIndex; void NotePlayHandleManager::init() { @@ -565,6 +564,7 @@ void NotePlayHandleManager::init() s_available += n; ++n; } + s_availableIndex = INITIAL_NPH_CACHE - 1; } @@ -576,14 +576,12 @@ NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrac int midiEventChannel, NotePlayHandle::Origin origin ) { - if( s_available.isEmpty() ) + if( s_availableIndex < 0 ) { extend( NPH_CACHE_INCREMENT ); } - s_mutex.lock(); - NotePlayHandle * nph = s_available.takeFirst(); - s_mutex.unlock(); + NotePlayHandle * nph = s_available.at( s_availableIndex.fetchAndAddOrdered( -1 ) ); new( (void*)nph ) NotePlayHandle( instrumentTrack, offset, frames, noteToPlay, parent, midiEventChannel, origin ); return nph; @@ -593,9 +591,7 @@ NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrac void NotePlayHandleManager::release( NotePlayHandle * nph ) { nph->done(); - s_mutex.lock(); - s_available += nph; - s_mutex.unlock(); + s_available[ s_availableIndex.fetchAndAddOrdered( 1 ) + 1 ] = nph; } @@ -603,12 +599,11 @@ void NotePlayHandleManager::extend( int i ) { NotePlayHandle * n = MM_ALLOC( NotePlayHandle, i ); - s_mutex.lock(); for( int j=0; j < i; ++j ) { s_nphCache += n; s_available += n; + s_availableIndex.ref(); ++n; } - s_mutex.unlock(); }