parallelizing-support for SMP-systems

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@403 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2006-09-18 12:35:10 +00:00
parent d83e806188
commit 5a96f63533
41 changed files with 444 additions and 123 deletions

View File

@@ -67,10 +67,11 @@ public:
// if the plugin doesn't play each note, it can create an instrument-
// play-handle and re-implement this method, so that it mixes it's
// output buffer only once per mixer-period
virtual void play( void );
virtual void play( bool _try_parallelizing = FALSE );
// to be overloaded by actual plugin
virtual void FASTCALL playNote( notePlayHandle * note_to_play );
virtual void FASTCALL playNote( notePlayHandle * note_to_play,
bool _try_parallelizing );
// needed for deleting plugin-specific-data of a note - plugin has to
// cast void-ptr so that the plugin-data is deleted properly
@@ -92,6 +93,10 @@ public:
return( m_valid );
}
inline virtual bool notePlayHandleBased( void ) const
{
return( TRUE );
}
// instantiate instrument-plugin with given name or return NULL
// on failure

View File

@@ -34,7 +34,7 @@ class instrumentPlayHandle : public playHandle
{
public:
inline instrumentPlayHandle( instrument * _instrument ) :
playHandle( INSTRUMENT_PLAY_HANDLE ),
playHandle( InstrumentPlayHandle ),
m_instrument( _instrument )
{
}
@@ -44,11 +44,11 @@ public:
}
inline virtual void play( void )
inline virtual void play( bool _try_parallelizing )
{
if( m_instrument != NULL )
{
m_instrument->play();
m_instrument->play( _try_parallelizing );
}
}
@@ -65,6 +65,23 @@ public:
}
}
inline virtual bool supportsParallelizing( void ) const
{
if( m_instrument != NULL )
{
return( m_instrument->supportsParallelizing() );
}
return( FALSE );
}
inline virtual void waitForWorkerThread( void )
{
if( m_instrument != NULL )
{
m_instrument->waitForWorkerThread();
}
}
private:
instrument * m_instrument;

View File

@@ -54,6 +54,7 @@
#include "tab_widget.h"
#include "engine.h"
#include "volume_knob.h"
#include "instrument.h"
class QLineEdit;
class arpAndChordsTabWidget;
@@ -61,7 +62,6 @@ class audioPort;
class instrumentTrackButton;
class envelopeTabWidget;
class fadeButton;
class instrument;
class lcdSpinBox;
class midiPort;
class midiTabWidget;
@@ -96,6 +96,7 @@ public:
virtual void FASTCALL processOutEvent( const midiEvent & _me,
const midiTime & _time );
// returns the frequency of a given tone & octave.
// This function also includes base_tone & base_octave in
// its calculations
@@ -105,7 +106,7 @@ public:
// for capturing note-play-events -> need that for arpeggio,
// filter and so on
void FASTCALL playNote( notePlayHandle * _n );
void FASTCALL playNote( notePlayHandle * _n, bool _try_parallelizing );
QString instrumentName( void ) const;
void FASTCALL deleteNotePluginData( notePlayHandle * _n );

View File

@@ -328,7 +328,7 @@ private:
Uint8 m_writeBuffer;
Uint8 m_analBuffer;
Uint8 m_poolDepth;
bool m_scaleClip;
surroundSampleFrame m_maxClip;
surroundSampleFrame m_previousSample;
@@ -338,6 +338,7 @@ private:
bool m_newBuffer[SURROUND_CHANNELS];
Uint8 m_cpuLoad;
int m_parallelizingLevel;
playHandleVector m_playHandles;
playHandleVector m_playHandlesToRemove;

View File

@@ -33,9 +33,9 @@
#include "basic_filters.h"
#include "bb_track.h"
#include "note.h"
#include "instrument_track.h"
class instrumentTrack;
class notePlayHandle;
typedef vvector<notePlayHandle *> notePlayHandleVector;
@@ -51,13 +51,14 @@ public:
float m_frequency;
notePlayHandle( instrumentTrack * _chnl_trk, const f_cnt_t _frames_ahead,
notePlayHandle( instrumentTrack * _chnl_trk,
const f_cnt_t _frames_ahead,
const f_cnt_t _frames, const note & _n,
const bool _arp_note = FALSE );
virtual ~notePlayHandle();
virtual void play( void );
virtual void play( bool _try_parallelizing );
virtual inline bool done( void ) const
{
@@ -182,6 +183,26 @@ public:
}
virtual bool supportsParallelizing( void ) const
{
return( m_instrumentTrack->m_instrument->
supportsParallelizing()
&&
// we must not parallelize note-play-handles, which
// belong to instruments that are instrument-play-
// handle-driven, because then waitForWorkerThread()
// would be additionally called for each
// note-play-handle which results in hangups
m_instrumentTrack->m_instrument->
notePlayHandleBased() );
}
virtual void waitForWorkerThread( void )
{
m_instrumentTrack->m_instrument->waitForWorkerThread();
}
private:
instrumentTrack * m_instrumentTrack; // needed for calling
// instrumentTrack::playNote

View File

@@ -49,8 +49,10 @@ class playHandle
public:
enum types
{
NOTE_PLAY_HANDLE, INSTRUMENT_PLAY_HANDLE, SAMPLE_PLAY_HANDLE,
PRESET_PREVIEW_PLAY_HANDLE
NotePlayHandle,
InstrumentPlayHandle,
SamplePlayHandle,
PresetPreviewHandle
} ;
playHandle( const types _type ) :
@@ -67,7 +69,7 @@ public:
return( m_type );
}
virtual void play( void ) = 0;
virtual void play( bool _try_parallelizing = FALSE ) = 0;
virtual bool done( void ) const = 0;
// play-handles can invalidate themselves if an object they depend on
@@ -79,6 +81,15 @@ public:
{
}
virtual bool supportsParallelizing( void ) const
{
return( FALSE );
}
virtual void waitForWorkerThread( void )
{
}
private:
types m_type;

View File

@@ -70,6 +70,8 @@ public:
ImportFilter, // filter for importing a file
ExportFilter, // filter for exporting a file
AnalysisTools, // analysis-tools (level-meter etc)
Libary, // simple library holding a code-base for
// several other plugins (e.g. LADSPA-support)
Other,
Undefined = 255
} ;
@@ -187,7 +189,21 @@ public:
static plugin * FASTCALL instantiate( const QString & _plugin_name,
void * _data );
// fills given vector with descriptors for all available plugins
// some plugins run external programs for doing their actual work
// (e.g. LVSL-server) or can run in separate worker-threads, so the
// mixer can schedule processing for parallelizing work which is very
// important for at least trying to use the full power of SMP-systems,
// otherwise the mixer will create according threads on it's own which
// of course isn't that efficient
virtual bool supportsParallelizing( void ) const;
// plugins supporting parallelizing, should re-implement that as the
// mixer will call this at the end of processing according chain
// of plugins
virtual void waitForWorkerThread( void );
// fills given vector with descriptors of all available plugins
static void FASTCALL getDescriptorsOfAvailPlugins(
vvector<descriptor> & _plugin_descs );

View File

@@ -56,7 +56,7 @@ public:
engine * _engine );
virtual ~presetPreviewPlayHandle();
virtual void play( void );
virtual void play( bool _try_parallelizing );
virtual bool done( void ) const;
static void cleanUp( engine * _engine );

View File

@@ -50,8 +50,8 @@ public:
samplePlayHandle( pattern * _pattern );
virtual ~samplePlayHandle();
virtual void play( void );
void play( const fpab_t _frame_base );
virtual void play( bool _try_parallelizing );
void play( const fpab_t _frame_base, bool _try_parallelizing );
virtual bool done( void ) const;
f_cnt_t totalFrames( void ) const;

View File

@@ -112,6 +112,7 @@ private slots:
void toggleDisableChActInd( bool _disabled );
void toggleManualChPiano( bool _enabled );
void setParallelizingLevel( int _level );
private:
@@ -153,7 +154,7 @@ private:
bool m_disableChActInd;
bool m_manualChPiano;
int m_parLevel;
typedef QMap<QString, audioDevice::setupWidget *> aswMap;
typedef QMap<QString, midiClient::setupWidget *> mswMap;