Replace NotePlayHandleManager implementation with MemoryPool

This commit is contained in:
Lukas W
2018-04-17 16:52:32 +02:00
parent 1cd8e15942
commit 3e1a96693d
7 changed files with 15 additions and 110 deletions

View File

@@ -32,7 +32,7 @@
#include "Note.h"
#include "PlayHandle.h"
#include "Track.h"
#include "Memory.h"
#include "MemoryPool.h"
class QReadWriteLock;
class InstrumentTrack;
@@ -44,7 +44,6 @@ typedef QList<const NotePlayHandle *> ConstNotePlayHandleList;
class LMMS_EXPORT NotePlayHandle : public PlayHandle, public Note
{
MM_OPERATORS
public:
void * m_pluginData;
std::unique_ptr<BasicFilters<>> m_filter;
@@ -328,31 +327,6 @@ private:
bool m_frequencyNeedsUpdate; // used to update pitch
} ;
const int INITIAL_NPH_CACHE = 256;
const int NPH_CACHE_INCREMENT = 16;
class NotePlayHandleManager
{
MM_OPERATORS
public:
static void init();
static NotePlayHandle * acquire( InstrumentTrack* instrumentTrack,
const f_cnt_t offset,
const f_cnt_t frames,
const Note& noteToPlay,
NotePlayHandle* parent = NULL,
int midiEventChannel = -1,
NotePlayHandle::Origin origin = NotePlayHandle::OriginPattern );
static void release( NotePlayHandle * nph );
static void extend( int i );
private:
static NotePlayHandle ** s_available;
static QReadWriteLock s_mutex;
static std::atomic_int s_availableIndex;
static int s_size;
};
extern MemoryPool<NotePlayHandle> NotePlayHandlePool;
#endif

View File

@@ -32,7 +32,6 @@
#include "PresetPreviewPlayHandle.h"
#include "stdshims.h"
InstrumentFunctionNoteStacking::ChordTable::Init InstrumentFunctionNoteStacking::ChordTable::s_initTable[] =
{
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "octave" ), { 0, -1 } },
@@ -263,7 +262,7 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n )
// create sub-note-play-handle, only note is
// different
Engine::mixer()->addPlayHandle(
NotePlayHandleManager::acquire( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy,
NotePlayHandlePool.construct( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy,
_n, -1, NotePlayHandle::OriginNoteStacking )
);
}
@@ -502,7 +501,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
// create sub-note-play-handle, only ptr to note is different
// and is_arp_note=true
Engine::mixer()->addPlayHandle(
NotePlayHandleManager::acquire( _n->instrumentTrack(),
NotePlayHandlePool.construct( _n->instrumentTrack(),
frames_processed,
gated_frames,
Note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, _n->getVolume(),

View File

@@ -400,7 +400,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
( *it )->audioPort()->removePlayHandle( ( *it ) );
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) *it );
NotePlayHandlePool.destroy( (NotePlayHandle*) *it );
}
else delete *it;
m_playHandles.erase( it );
@@ -454,7 +454,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
( *it )->audioPort()->removePlayHandle( ( *it ) );
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) *it );
NotePlayHandlePool.destroy( (NotePlayHandle*) *it );
}
else delete *it;
it = m_playHandles.erase( it );
@@ -689,7 +689,7 @@ bool Mixer::addPlayHandle( PlayHandle* handle )
if( handle->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*)handle );
NotePlayHandlePool.destroy( (NotePlayHandle*)handle );
}
else delete handle;
@@ -742,7 +742,7 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
{
if( _ph->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) _ph );
NotePlayHandlePool.destroy( (NotePlayHandle*) _ph );
}
else delete _ph;
}
@@ -768,7 +768,7 @@ void Mixer::removePlayHandlesOfTypes( Track * _track, const quint8 types )
( *it )->audioPort()->removePlayHandle( ( *it ) );
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) *it );
NotePlayHandlePool.destroy( (NotePlayHandle*) *it );
}
else delete *it;
it = m_playHandles.erase( it );

View File

@@ -32,7 +32,6 @@
#include "Mixer.h"
#include "Song.h"
NotePlayHandle::BaseDetuning::BaseDetuning( DetuningHelper *detuning ) :
m_value( detuning ? detuning->automationPattern()->valueAt( 0 ) : 0 )
{
@@ -543,69 +542,5 @@ void NotePlayHandle::resize( const bpm_t _new_tempo )
}
}
NotePlayHandle ** NotePlayHandleManager::s_available;
QReadWriteLock NotePlayHandleManager::s_mutex;
std::atomic_int NotePlayHandleManager::s_availableIndex;
int NotePlayHandleManager::s_size;
void NotePlayHandleManager::init()
{
s_available = MM_ALLOC( NotePlayHandle*, INITIAL_NPH_CACHE );
NotePlayHandle * n = MM_ALLOC( NotePlayHandle, INITIAL_NPH_CACHE );
for( int i=0; i < INITIAL_NPH_CACHE; ++i )
{
s_available[ i ] = n;
++n;
}
s_availableIndex = INITIAL_NPH_CACHE - 1;
s_size = INITIAL_NPH_CACHE;
}
NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrack,
const f_cnt_t offset,
const f_cnt_t frames,
const Note& noteToPlay,
NotePlayHandle* parent,
int midiEventChannel,
NotePlayHandle::Origin origin )
{
// TODO: use some lockless data structures
s_mutex.lockForWrite();
if (s_availableIndex < 0) { extend(NPH_CACHE_INCREMENT); }
NotePlayHandle * nph = s_available[s_availableIndex--];
s_mutex.unlock();
new( (void*)nph ) NotePlayHandle( instrumentTrack, offset, frames, noteToPlay, parent, midiEventChannel, origin );
return nph;
}
void NotePlayHandleManager::release( NotePlayHandle * nph )
{
nph->NotePlayHandle::~NotePlayHandle();
s_mutex.lockForRead();
s_available[++s_availableIndex] = nph;
s_mutex.unlock();
}
void NotePlayHandleManager::extend( int c )
{
s_size += c;
NotePlayHandle ** tmp = MM_ALLOC( NotePlayHandle*, s_size );
MM_FREE( s_available );
s_available = tmp;
NotePlayHandle * n = MM_ALLOC( NotePlayHandle, c );
for( int i=0; i < c; ++i )
{
s_available[++s_availableIndex] = n;
++n;
}
}
const int INITIAL_NPH_CACHE = 256;
MemoryPool<NotePlayHandle> NotePlayHandlePool{INITIAL_NPH_CACHE};

View File

@@ -182,7 +182,7 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file,
Engine::mixer()->requestChangeInModel();
// create note-play-handle for it
m_previewNote = NotePlayHandleManager::acquire(
m_previewNote = NotePlayHandlePool.construct(
s_previewTC->previewInstrumentTrack(), 0,
typeInfo<f_cnt_t>::max() / 2,
Note( 0, 0, DefaultKey, 100 ) );

View File

@@ -286,9 +286,6 @@ int main( int argc, char * * argv )
qInstallMessageHandler(consoleMessageHandler);
#endif
// initialize memory managers
NotePlayHandleManager::init();
// intialize RNG
srand( getpid() + time( 0 ) );

View File

@@ -261,11 +261,11 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti
if( m_notes[event.key()] == NULL )
{
NotePlayHandle* nph =
NotePlayHandleManager::acquire(
NotePlayHandlePool.construct(
this, offset,
typeInfo<f_cnt_t>::max() / 2,
Note( MidiTime(), MidiTime(), event.key(), event.volume( midiPort()->baseVelocity() ) ),
NULL, event.channel(),
nullptr, event.channel(),
NotePlayHandle::OriginMidiInput );
m_notes[event.key()] = nph;
if( ! Engine::mixer()->addPlayHandle( nph ) )
@@ -691,7 +691,7 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames,
const f_cnt_t note_frames =
cur_note->length().frames( frames_per_tick );
NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note );
NotePlayHandle* notePlayHandle = NotePlayHandlePool.construct( this, _offset, note_frames, *cur_note );
notePlayHandle->setBBTrack( bb_track );
// are we playing global song?
if( _tco_num < 0 )