From a8211873b56ae5decd23e6894d437038120f0325 Mon Sep 17 00:00:00 2001 From: Vesa Date: Sun, 24 Aug 2014 15:44:36 +0300 Subject: [PATCH] Fix arpeggio to work better with the new way to handle note offsets Ok, not really related to memory management, but was something that needed doing and it's easier to test things when things work properly --- include/NotePlayHandle.h | 2 ++ src/core/InstrumentFunctions.cpp | 16 ++++++++++------ src/core/NotePlayHandle.cpp | 27 +++++++++++---------------- 3 files changed, 23 insertions(+), 22 deletions(-) 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(); }