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:
43
ChangeLog
43
ChangeLog
@@ -1,3 +1,46 @@
|
||||
2006-09-18 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/vestige/vestige.h:
|
||||
* plugins/vestige/vestige.cpp:
|
||||
* plugin/vestige/lvsl_client.h:
|
||||
* plugin/vestige/lvsl_client.cpp:
|
||||
take advantage of LMMS' new parallelizing-support - works indeed the
|
||||
way expected! all VST-servers are now balanced all over available CPUs
|
||||
|
||||
* plugins/audio_file_processor/audio_file_processor.h:
|
||||
* plugins/audio_file_processor/audio_file_processor.cpp:
|
||||
* plugins/bit_invader/bit_invader.h:
|
||||
* plugins/bit_invader/bit_invader.cpp:
|
||||
* plugins/organic/organic.h:
|
||||
* plugins/organic/organic.cpp:
|
||||
* plugins/plucked_string_synth/plucked_string_synth.h:
|
||||
* plugins/plucked_string_synth/plucked_string_synth.cpp:
|
||||
* plugins/mallets/mallets.h:
|
||||
* plugins/mallets/mallets.cpp:
|
||||
* plugins/vestige/vestige.h:
|
||||
* plugins/vestige/vestige.cpp:
|
||||
* plugins/vibed/vibed.h:
|
||||
* plugins/vibed/vibed.cpp:
|
||||
* include/instrument.h:
|
||||
* include/instrument_play_handle.h:
|
||||
* include/mixer.h:
|
||||
* include/note_play_handle.h:
|
||||
* include/play_handle.h:
|
||||
* include/plugin.h:
|
||||
* include/preset_preview_play_handle.h:
|
||||
* include/sample_play_handle.h:
|
||||
* include/setup_dialog.h:
|
||||
* include/track.h:
|
||||
* src/core/instrument.cpp:
|
||||
* src/core/mixer.cpp:
|
||||
* src/core/plugin.cpp:
|
||||
* src/core/preset_preview_play_handle.cpp:
|
||||
* src/core/sample_play_handle.cpp:
|
||||
* src/core/setup_dialog.cpp:
|
||||
* src/tracks/instrument_track.cpp:
|
||||
added first simple support for parallelizing sound-processing for
|
||||
using full power of SMP-systems (e.g. my new dual-core-notebook :-)
|
||||
|
||||
2006-09-17 Javier Serrano Polo <jasp00/at/terra/dot/es>
|
||||
|
||||
* include/tempo_sync_knob.h:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.2.1-cvs20060917, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.2.1-cvs20060917)
|
||||
AC_INIT(lmms, 0.2.1-cvs20060918, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.2.1-cvs20060918)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -392,7 +392,7 @@ void audioFileProcessor::setAudioFile( const QString & _audio_file, bool _rename
|
||||
|
||||
|
||||
|
||||
void audioFileProcessor::playNote( notePlayHandle * _n )
|
||||
void audioFileProcessor::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
const Uint32 frames = eng()->getMixer()->framesPerAudioBuffer();
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
|
||||
@@ -56,7 +56,8 @@ public:
|
||||
audioFileProcessor( instrumentTrack * _channel_track );
|
||||
virtual ~audioFileProcessor();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
|
||||
@@ -681,7 +681,7 @@ void bitInvader::smoothClicked( void )
|
||||
|
||||
|
||||
|
||||
void bitInvader::playNote( notePlayHandle * _n )
|
||||
void bitInvader::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
@@ -68,7 +68,8 @@ public:
|
||||
bitInvader(instrumentTrack * _channel_track );
|
||||
virtual ~bitInvader();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ QString organicInstrument::nodeName( void ) const
|
||||
|
||||
|
||||
|
||||
void organicInstrument::playNote( notePlayHandle * _n )
|
||||
void organicInstrument::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
if( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
@@ -47,7 +47,8 @@ public:
|
||||
organicInstrument( instrumentTrack * _channel_track );
|
||||
virtual ~organicInstrument();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ QString pluckedStringSynth::nodeName( void ) const
|
||||
|
||||
|
||||
|
||||
void pluckedStringSynth::playNote( notePlayHandle * _n )
|
||||
void pluckedStringSynth::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
@@ -197,7 +197,8 @@ public:
|
||||
pluckedStringSynth( instrumentTrack * _channel_track );
|
||||
virtual ~pluckedStringSynth();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -391,7 +391,7 @@ QString mallets::nodeName( void ) const
|
||||
|
||||
|
||||
|
||||
void mallets::playNote( notePlayHandle * _n )
|
||||
void mallets::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
int p = m_presets->value();
|
||||
|
||||
|
||||
@@ -126,7 +126,8 @@ public:
|
||||
mallets( instrumentTrack * _channel_track );
|
||||
virtual ~mallets();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -690,7 +690,7 @@ QString tripleOscillator::nodeName( void ) const
|
||||
|
||||
|
||||
|
||||
void tripleOscillator::playNote( notePlayHandle * _n )
|
||||
void tripleOscillator::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
if( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
@@ -48,7 +48,8 @@ public:
|
||||
tripleOscillator( instrumentTrack * _channel );
|
||||
virtual ~tripleOscillator();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ libvestige_la_SOURCES = vestige.cpp vestige.h lvsl_client.cpp lvsl_client.h
|
||||
$(libvestige_la_SOURCES): ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
CC = wineg++
|
||||
pkglib_PROGRAMS = lvsl_server
|
||||
lvsl_server_SOURCES = lvsl_server.c communication.h
|
||||
|
||||
@@ -107,12 +107,12 @@ struct vstParamProperties
|
||||
|
||||
enum hostLanguages
|
||||
{
|
||||
LVSL_LANG_ENGLISH = 1,
|
||||
LVSL_LANG_GERMAN,
|
||||
LVSL_LANG_FRENCH,
|
||||
LVSL_LANG_ITALIAN,
|
||||
LVSL_LANG_SPANISH,
|
||||
LVSL_LANG_JAPANESE
|
||||
LanguageEnglish = 1,
|
||||
LanguageGerman,
|
||||
LanguageFrench,
|
||||
LanguageItalian,
|
||||
LanguageSpanish,
|
||||
LanguageJapanese
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ remoteVSTPlugin::remoteVSTPlugin( const QString & _plugin, engine * _engine ) :
|
||||
m_outputCount( 0 ),
|
||||
m_shmID( -1 ),
|
||||
m_shm( NULL ),
|
||||
m_shmSize( 0 )
|
||||
m_shmSize( 0 ),
|
||||
m_initialized( FALSE )
|
||||
{
|
||||
pipe( m_pipes[0] );
|
||||
pipe( m_pipes[1] );
|
||||
@@ -139,14 +140,14 @@ remoteVSTPlugin::remoteVSTPlugin( const QString & _plugin, engine * _engine ) :
|
||||
lock();
|
||||
|
||||
writeValueS<Sint16>( VST_LANGUAGE );
|
||||
hostLanguages hlang = LVSL_LANG_ENGLISH;
|
||||
hostLanguages hlang = LanguageEnglish;
|
||||
switch( QLocale::system().language() )
|
||||
{
|
||||
case QLocale::German: hlang = LVSL_LANG_GERMAN; break;
|
||||
case QLocale::French: hlang = LVSL_LANG_FRENCH; break;
|
||||
case QLocale::Italian: hlang = LVSL_LANG_ITALIAN; break;
|
||||
case QLocale::Spanish: hlang = LVSL_LANG_SPANISH; break;
|
||||
case QLocale::Japanese: hlang = LVSL_LANG_JAPANESE; break;
|
||||
case QLocale::German: hlang = LanguageGerman; break;
|
||||
case QLocale::French: hlang = LanguageFrench; break;
|
||||
case QLocale::Italian: hlang = LanguageItalian; break;
|
||||
case QLocale::Spanish: hlang = LanguageSpanish; break;
|
||||
case QLocale::Japanese: hlang = LanguageJapanese; break;
|
||||
default: break;
|
||||
}
|
||||
writeValueS<hostLanguages>( hlang );
|
||||
@@ -276,8 +277,8 @@ void remoteVSTPlugin::hideEditor( void )
|
||||
|
||||
|
||||
|
||||
void remoteVSTPlugin::process( const sampleFrame * _in_buf,
|
||||
sampleFrame * _out_buf )
|
||||
bool remoteVSTPlugin::process( const sampleFrame * _in_buf,
|
||||
sampleFrame * _out_buf, bool _wait )
|
||||
{
|
||||
const fpab_t frames = eng()->getMixer()->framesPerAudioBuffer();
|
||||
|
||||
@@ -291,8 +292,11 @@ void remoteVSTPlugin::process( const sampleFrame * _in_buf,
|
||||
{
|
||||
(void) processNextMessage();
|
||||
}
|
||||
eng()->getMixer()->clearAudioBuffer( _out_buf, frames );
|
||||
return;
|
||||
if( _out_buf != NULL )
|
||||
{
|
||||
eng()->getMixer()->clearAudioBuffer( _out_buf, frames );
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
memset( m_shm, 0, m_shmSize );
|
||||
@@ -314,32 +318,50 @@ void remoteVSTPlugin::process( const sampleFrame * _in_buf,
|
||||
writeValueS<Sint16>( VST_PROCESS );
|
||||
unlock();
|
||||
|
||||
if( _out_buf != NULL && m_outputCount > 0 )
|
||||
if( _wait )
|
||||
{
|
||||
// wait until server signals that process()ing is done
|
||||
while( processNextMessage() != VST_PROCESS_DONE )
|
||||
{
|
||||
// hopefully scheduler gives process-time to plugin...
|
||||
usleep( 10 );
|
||||
}
|
||||
waitForProcessingFinished( _out_buf );
|
||||
}
|
||||
m_initialized = TRUE;
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
ch_cnt_t outputs = tMax<ch_cnt_t>( m_outputCount,
|
||||
|
||||
|
||||
|
||||
bool remoteVSTPlugin::waitForProcessingFinished( sampleFrame * _out_buf )
|
||||
{
|
||||
if( !m_initialized || _out_buf == NULL || m_outputCount == 0 )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// wait until server signals that process()ing is done
|
||||
while( processNextMessage() != VST_PROCESS_DONE )
|
||||
{
|
||||
// hopefully scheduler gives process-time to plugin...
|
||||
usleep( 10 );
|
||||
}
|
||||
|
||||
const fpab_t frames = eng()->getMixer()->framesPerAudioBuffer();
|
||||
const ch_cnt_t outputs = tMax<ch_cnt_t>( m_outputCount,
|
||||
DEFAULT_CHANNELS );
|
||||
if( outputs != DEFAULT_CHANNELS )
|
||||
{
|
||||
// clear buffer, if plugin didn't fill up both channels
|
||||
eng()->getMixer()->clearAudioBuffer( _out_buf, frames );
|
||||
}
|
||||
if( outputs != DEFAULT_CHANNELS )
|
||||
{
|
||||
// clear buffer, if plugin didn't fill up both channels
|
||||
eng()->getMixer()->clearAudioBuffer( _out_buf, frames );
|
||||
}
|
||||
|
||||
for( ch_cnt_t ch = 0; ch < outputs; ++ch )
|
||||
for( ch_cnt_t ch = 0; ch < outputs; ++ch )
|
||||
{
|
||||
for( fpab_t frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
for( fpab_t frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
_out_buf[frame][ch] = m_shm[(m_inputCount+ch)*
|
||||
_out_buf[frame][ch] = m_shm[(m_inputCount+ch)*
|
||||
frames+frame];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -77,8 +77,15 @@ public:
|
||||
return( m_productString );
|
||||
}
|
||||
|
||||
void FASTCALL process( const sampleFrame * _in_buf,
|
||||
sampleFrame * _out_buf );
|
||||
// if _wait == TRUE, process() calls waitForProcessingFinished()
|
||||
// immediately, otherwise, _out_buf can be zero and you've to call
|
||||
// waitForProcessingFinished() on your own
|
||||
bool FASTCALL process( const sampleFrame * _in_buf,
|
||||
sampleFrame * _out_buf,
|
||||
bool _wait );
|
||||
bool FASTCALL waitForProcessingFinished( sampleFrame * _out_buf );
|
||||
|
||||
|
||||
void FASTCALL enqueueMidiEvent( const midiEvent & _event,
|
||||
const f_cnt_t _frames_ahead );
|
||||
void FASTCALL setTempo( const bpm_t _bpm );
|
||||
@@ -174,6 +181,8 @@ private:
|
||||
float * m_shm;
|
||||
size_t m_shmSize;
|
||||
|
||||
bool m_initialized;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ static pthread_key_t ejmpbuf_key;
|
||||
#endif
|
||||
|
||||
|
||||
static hostLanguages hlang = LVSL_LANG_ENGLISH;
|
||||
static hostLanguages hlang = LanguageEnglish;
|
||||
|
||||
|
||||
class VSTPlugin;
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
{
|
||||
if( m_window != NULL )
|
||||
{
|
||||
PostThreadMessageA( m_guiThreadID, WM_USER, SHOW_EDITOR,
|
||||
PostThreadMessageA( m_guiThreadID, WM_USER, ShowEditor,
|
||||
0 );
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
private:
|
||||
enum guiThreadMessages
|
||||
{
|
||||
NONE, SHOW_EDITOR, CLOSE_PLUGIN
|
||||
None, ShowEditor, ClosePlugin
|
||||
} ;
|
||||
|
||||
// callback used by plugin for being able to communicate with it's host
|
||||
@@ -348,7 +348,7 @@ VSTPlugin::~VSTPlugin()
|
||||
{
|
||||
// notify GUI-thread
|
||||
if( !PostThreadMessageA( m_guiThreadID, WM_USER,
|
||||
CLOSE_PLUGIN, 0 ) )
|
||||
ClosePlugin, 0 ) )
|
||||
{
|
||||
//lvsMessage( "could not post message to gui thread" );
|
||||
}
|
||||
@@ -1077,9 +1077,12 @@ DWORD WINAPI VSTPlugin::guiEventLoop( LPVOID _param )
|
||||
_this->m_windowHeight = er->bottom - er->top;
|
||||
|
||||
SetWindowPos( _this->m_window, 0, 0, 0, _this->m_windowWidth + 8,
|
||||
_this->m_windowHeight + 26,
|
||||
_this->m_windowHeight + 26, 0
|
||||
#if 0
|
||||
SWP_NOACTIVATE /*| SWP_NOREDRAW*/ | SWP_NOMOVE |
|
||||
SWP_NOOWNERZORDER | SWP_NOZORDER );
|
||||
SWP_NOOWNERZORDER | SWP_NOZORDER
|
||||
#endif
|
||||
);
|
||||
#ifdef HAVE_TLS
|
||||
ejmpbuf_valid = false;
|
||||
#else
|
||||
@@ -1101,13 +1104,13 @@ DWORD WINAPI VSTPlugin::guiEventLoop( LPVOID _param )
|
||||
{
|
||||
switch( msg.wParam )
|
||||
{
|
||||
case SHOW_EDITOR:
|
||||
case ShowEditor:
|
||||
ShowWindow( _this->m_window,
|
||||
SW_SHOWNORMAL );
|
||||
UpdateWindow( _this->m_window );
|
||||
break;
|
||||
|
||||
case CLOSE_PLUGIN:
|
||||
case ClosePlugin:
|
||||
quit = true;
|
||||
break;
|
||||
|
||||
|
||||
@@ -324,20 +324,24 @@ void vestigeInstrument::setParameter( const QString & _param,
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::play( void )
|
||||
void vestigeInstrument::waitForWorkerThread( void )
|
||||
{
|
||||
QMutexLocker ml( &m_pluginMutex );
|
||||
m_pluginMutex.lock();
|
||||
if( m_plugin == NULL )
|
||||
{
|
||||
m_pluginMutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
const fpab_t frames = eng()->getMixer()->framesPerAudioBuffer();
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
|
||||
m_plugin->process( NULL, buf );
|
||||
|
||||
getInstrumentTrack()->processAudioBuffer( buf, frames, NULL );
|
||||
if( m_plugin->waitForProcessingFinished( buf ) )
|
||||
{
|
||||
getInstrumentTrack()->processAudioBuffer( buf, frames, NULL );
|
||||
}
|
||||
|
||||
m_pluginMutex.unlock();
|
||||
|
||||
bufferAllocator::free( buf );
|
||||
}
|
||||
@@ -345,9 +349,30 @@ void vestigeInstrument::play( void )
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::play( bool _try_parallelizing )
|
||||
{
|
||||
m_pluginMutex.lock();
|
||||
if( m_plugin == NULL )
|
||||
{
|
||||
m_pluginMutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
m_plugin->process( NULL, NULL, FALSE );
|
||||
m_pluginMutex.unlock();
|
||||
|
||||
if( !_try_parallelizing )
|
||||
{
|
||||
waitForWorkerThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vestigeInstrument::playNote( notePlayHandle * _n )
|
||||
|
||||
|
||||
|
||||
|
||||
void vestigeInstrument::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
m_pluginMutex.lock();
|
||||
if( _n->totalFramesPlayed() == 0 && m_plugin != NULL )
|
||||
|
||||
@@ -56,9 +56,10 @@ public:
|
||||
vestigeInstrument( instrumentTrack * _channel_track );
|
||||
virtual ~vestigeInstrument();
|
||||
|
||||
virtual void play( void );
|
||||
virtual void play( bool _try_parallelizing );
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
@@ -71,6 +72,18 @@ public:
|
||||
virtual void FASTCALL setParameter( const QString & _param,
|
||||
const QString & _value );
|
||||
|
||||
virtual bool supportsParallelizing( void ) const
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
virtual void waitForWorkerThread( void );
|
||||
|
||||
virtual bool notePlayHandleBased( void ) const
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
|
||||
protected slots:
|
||||
void openPlugin( void );
|
||||
|
||||
@@ -551,7 +551,7 @@ QString vibed::nodeName( void ) const
|
||||
|
||||
|
||||
|
||||
void vibed::playNote( notePlayHandle * _n )
|
||||
void vibed::playNote( notePlayHandle * _n, bool )
|
||||
{
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
@@ -48,7 +48,8 @@ public:
|
||||
vibed( instrumentTrack * _channel_track );
|
||||
virtual ~vibed();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n,
|
||||
bool _try_parallelizing );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
|
||||
@@ -51,14 +51,14 @@ instrument::~instrument()
|
||||
|
||||
|
||||
|
||||
void instrument::play( void )
|
||||
void instrument::play( bool )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrument::playNote( notePlayHandle * )
|
||||
void instrument::playNote( notePlayHandle *, bool )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ mixer::mixer( engine * _engine ) :
|
||||
m_readBuf( NULL ),
|
||||
m_writeBuf( NULL ),
|
||||
m_cpuLoad( 0 ),
|
||||
m_parallelizingLevel( 1 ),
|
||||
m_qualityLevel( DEFAULT_QUALITY_LEVEL ),
|
||||
m_masterGain( 1.0f ),
|
||||
m_audioDev( NULL ),
|
||||
@@ -88,6 +89,13 @@ mixer::mixer( engine * _engine ) :
|
||||
QString::number( m_framesPerAudioBuffer ) );
|
||||
}
|
||||
|
||||
if( configManager::inst()->value( "mixer", "parallelizinglevel"
|
||||
).toInt() > 0 )
|
||||
{
|
||||
m_parallelizingLevel =configManager::inst()->value( "mixer",
|
||||
"parallelizinglevel" ).toInt();
|
||||
}
|
||||
|
||||
for( Uint8 i = 0; i < 3; i++ )
|
||||
{
|
||||
m_readBuf = bufferAllocator::alloc<surroundSampleFrame>(
|
||||
@@ -258,22 +266,76 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
// if( criticalXRuns() == FALSE )
|
||||
{
|
||||
csize idx = 0;
|
||||
while( idx < m_playHandles.size() )
|
||||
if( m_parallelizingLevel > 1 )
|
||||
{
|
||||
register playHandle * n = m_playHandles[idx];
|
||||
// delete play-handle if it played completely
|
||||
if( n->done() )
|
||||
// TODO: if not enough play-handles are found which are capable of
|
||||
// parallelizing, create according worker-threads. each of this threads
|
||||
// processes a certain part of our m_playHandles-vector
|
||||
// the question is the queueing model which we can use:
|
||||
// 1) m_playHandles is divided into m_parallelizingLevel sub-vectors
|
||||
// each sub-vector is processed by a worker-thread
|
||||
// 2) create a stack with all play-handles that need to be processed,
|
||||
// save it via a mutex and then let all worker-threads "fetch jobs"
|
||||
// from the stack - this way it's guaranteed the work is
|
||||
// balanced across all worker-threads. this would avoid cases
|
||||
// where the sub-vector of a thread only contains notes that are
|
||||
// done and only need to be deleted.
|
||||
playHandleVector par_hndls;
|
||||
while( idx < m_playHandles.size() )
|
||||
{
|
||||
delete n;
|
||||
m_playHandles.erase( m_playHandles.begin() +
|
||||
idx );
|
||||
}
|
||||
else
|
||||
{
|
||||
// play all uncompletely-played play-handles...
|
||||
n->play();
|
||||
playHandle * n = m_playHandles[idx];
|
||||
if( !n->done() && n->supportsParallelizing() )
|
||||
{
|
||||
n->play( TRUE );
|
||||
par_hndls.push_back( n );
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
idx = 0;
|
||||
while( idx < m_playHandles.size() )
|
||||
{
|
||||
playHandle * n =m_playHandles[idx];
|
||||
if( n->supportsParallelizing() )
|
||||
{
|
||||
++idx;
|
||||
continue;
|
||||
}
|
||||
else if( n->done() )
|
||||
{
|
||||
delete n;
|
||||
m_playHandles.erase(
|
||||
m_playHandles.begin() + idx );
|
||||
}
|
||||
else
|
||||
{
|
||||
n->play();
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
for( playHandleVector::iterator it = par_hndls.begin();
|
||||
it != par_hndls.end(); ++it )
|
||||
{
|
||||
( *it )->waitForWorkerThread();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( idx < m_playHandles.size() )
|
||||
{
|
||||
register playHandle * n = m_playHandles[idx];
|
||||
// delete play-handle if it played completely
|
||||
if( n->done() )
|
||||
{
|
||||
delete n;
|
||||
m_playHandles.erase(
|
||||
m_playHandles.begin() + idx );
|
||||
}
|
||||
else
|
||||
{
|
||||
n->play();
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eng()->getSongEditor()->processNextBuffer();
|
||||
@@ -283,7 +345,8 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
it != m_audioPorts.end(); ++it )
|
||||
{
|
||||
more_effects = ( *it )->processEffects();
|
||||
if( ( *it )->m_bufferUsage != audioPort::NONE || more_effects )
|
||||
if( ( *it )->m_bufferUsage != audioPort::NONE ||
|
||||
more_effects )
|
||||
{
|
||||
processBuffer( ( *it )->firstBuffer(),
|
||||
( *it )->nextFxChannel() );
|
||||
@@ -324,7 +387,7 @@ void mixer::clear( bool _everything )
|
||||
// parameter _everything is true (which is the case when
|
||||
// clearing song for example)
|
||||
if( _everything == TRUE ||
|
||||
( *it )->type() != playHandle::INSTRUMENT_PLAY_HANDLE )
|
||||
( *it )->type() != playHandle::InstrumentPlayHandle )
|
||||
{
|
||||
m_playHandlesToRemove.push_back( *it );
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
|
||||
const f_cnt_t _frames,
|
||||
const note & _n,
|
||||
const bool _arp_note ) :
|
||||
playHandle( NOTE_PLAY_HANDLE ),
|
||||
playHandle( NotePlayHandle ),
|
||||
note( NULL, _n.length(), _n.pos(), _n.tone(), _n.octave(),
|
||||
_n.getVolume(), _n.getPanning() ),
|
||||
m_pluginData( NULL ),
|
||||
@@ -121,7 +121,7 @@ notePlayHandle::~notePlayHandle()
|
||||
|
||||
|
||||
|
||||
void notePlayHandle::play( void )
|
||||
void notePlayHandle::play( bool _try_parallelizing )
|
||||
{
|
||||
if( m_muted == TRUE || m_instrumentTrack == NULL )
|
||||
{
|
||||
@@ -137,7 +137,7 @@ void notePlayHandle::play( void )
|
||||
}
|
||||
|
||||
// play note!
|
||||
m_instrumentTrack->playNote( this );
|
||||
m_instrumentTrack->playNote( this, _try_parallelizing );
|
||||
|
||||
if( m_released == TRUE )
|
||||
{
|
||||
@@ -198,7 +198,7 @@ void notePlayHandle::play( void )
|
||||
for( notePlayHandleVector::iterator it = m_subNotes.begin();
|
||||
it != m_subNotes.end(); )
|
||||
{
|
||||
( *it )->play();
|
||||
( *it )->play( _try_parallelizing );
|
||||
if( ( *it )->done() )
|
||||
{
|
||||
delete *it;
|
||||
|
||||
@@ -139,6 +139,21 @@ plugin * plugin::instantiate( const QString & _plugin_name, void * _data )
|
||||
|
||||
|
||||
|
||||
bool plugin::supportsParallelizing( void ) const
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void plugin::waitForWorkerThread( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void plugin::getDescriptorsOfAvailPlugins( vvector<descriptor> & _plugin_descs )
|
||||
{
|
||||
QDir directory( configManager::inst()->pluginDir() );
|
||||
|
||||
@@ -127,7 +127,7 @@ QMap<const engine *, previewTrackContainer *>
|
||||
presetPreviewPlayHandle::presetPreviewPlayHandle(
|
||||
const QString & _preset_file,
|
||||
engine * _engine ) :
|
||||
playHandle( PRESET_PREVIEW_PLAY_HANDLE ),
|
||||
playHandle( PresetPreviewHandle ),
|
||||
engineObject( _engine ),
|
||||
m_previewNote( NULL )
|
||||
{
|
||||
@@ -192,9 +192,9 @@ presetPreviewPlayHandle::~presetPreviewPlayHandle()
|
||||
|
||||
|
||||
|
||||
void presetPreviewPlayHandle::play( void )
|
||||
void presetPreviewPlayHandle::play( bool _try_parallelizing )
|
||||
{
|
||||
m_previewNote->play();
|
||||
m_previewNote->play( _try_parallelizing );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
samplePlayHandle::samplePlayHandle( const QString & _sample_file,
|
||||
engine * _engine ) :
|
||||
playHandle( SAMPLE_PLAY_HANDLE ),
|
||||
playHandle( SamplePlayHandle ),
|
||||
engineObject( _engine ),
|
||||
m_sampleBuffer( new sampleBuffer( eng(), _sample_file ) ),
|
||||
m_doneMayReturnTrue( TRUE ),
|
||||
@@ -55,7 +55,7 @@ samplePlayHandle::samplePlayHandle( const QString & _sample_file,
|
||||
|
||||
|
||||
samplePlayHandle::samplePlayHandle( sampleBuffer * _sample_buffer ) :
|
||||
playHandle( SAMPLE_PLAY_HANDLE ),
|
||||
playHandle( SamplePlayHandle ),
|
||||
engineObject( _sample_buffer->eng() ),
|
||||
m_sampleBuffer( sharedObject::ref( _sample_buffer ) ),
|
||||
m_doneMayReturnTrue( TRUE ),
|
||||
@@ -72,7 +72,7 @@ samplePlayHandle::samplePlayHandle( sampleBuffer * _sample_buffer ) :
|
||||
|
||||
|
||||
samplePlayHandle::samplePlayHandle( sampleTCO * _tco ) :
|
||||
playHandle( SAMPLE_PLAY_HANDLE ),
|
||||
playHandle( SamplePlayHandle ),
|
||||
engineObject( _tco->eng() ),
|
||||
m_sampleBuffer( sharedObject::ref( _tco->getSampleBuffer() ) ),
|
||||
m_doneMayReturnTrue( TRUE ),
|
||||
@@ -89,7 +89,7 @@ samplePlayHandle::samplePlayHandle( sampleTCO * _tco ) :
|
||||
|
||||
|
||||
samplePlayHandle::samplePlayHandle( pattern * _pattern ) :
|
||||
playHandle( SAMPLE_PLAY_HANDLE ),
|
||||
playHandle( SamplePlayHandle ),
|
||||
engineObject( _pattern->eng() ),
|
||||
m_sampleBuffer( sharedObject::ref( _pattern->getFrozenPattern() ) ),
|
||||
m_doneMayReturnTrue( TRUE ),
|
||||
@@ -117,15 +117,15 @@ samplePlayHandle::~samplePlayHandle()
|
||||
|
||||
|
||||
|
||||
void samplePlayHandle::play( void )
|
||||
void samplePlayHandle::play( bool _try_parallelizing )
|
||||
{
|
||||
play( 0 );
|
||||
play( 0, _try_parallelizing );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void samplePlayHandle::play( const fpab_t _frame_base )
|
||||
void samplePlayHandle::play( const fpab_t _frame_base, bool )
|
||||
{
|
||||
if( framesDone() >= totalFrames() )
|
||||
{
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "debug.h"
|
||||
#include "tooltip.h"
|
||||
#include "led_checkbox.h"
|
||||
#include "lcd_spinbox.h"
|
||||
#include "ladspa_manager.h"
|
||||
|
||||
|
||||
@@ -126,7 +127,9 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
|
||||
m_disableChActInd( configManager::inst()->value( "ui",
|
||||
"disablechannelactivityindicators" ).toInt() ),
|
||||
m_manualChPiano( configManager::inst()->value( "ui",
|
||||
"manualchannelpiano" ).toInt() )
|
||||
"manualchannelpiano" ).toInt() ),
|
||||
m_parLevel( configManager::inst()->value( "mixer",
|
||||
"parallelizinglevel" ).toInt() )
|
||||
|
||||
{
|
||||
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
|
||||
@@ -453,8 +456,45 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
|
||||
|
||||
|
||||
|
||||
tabWidget * smp_supp_tw = new tabWidget( tr( "SMP support" ).toUpper(),
|
||||
performance );
|
||||
smp_supp_tw->setFixedHeight( 180 );
|
||||
|
||||
QLabel * par_level_lbl = new QLabel( tr( "Parallelizing level" ),
|
||||
smp_supp_tw );
|
||||
par_level_lbl->move( 10, 15 );
|
||||
lcdSpinBox * par_level = new lcdSpinBox( 1, 16, 2, smp_supp_tw,
|
||||
tr( "SMP-level" ),
|
||||
eng(), NULL );
|
||||
par_level->setValue( m_parLevel );
|
||||
connect( par_level, SIGNAL( valueChanged( int ) ),
|
||||
this, SLOT( setParallelizingLevel( int ) ) );
|
||||
|
||||
par_level->move( 120, 20 );
|
||||
|
||||
QLabel * smp_help = new QLabel(
|
||||
tr( "If you have a machine with more then one processor "
|
||||
"(e.g. dual-core systems) you should use a "
|
||||
"parallelizing-level above 1 which means that LMMS "
|
||||
"will try to split up sound-processing into several "
|
||||
"threads which should should be run on several cores "
|
||||
"by the underlaying operating-system.\n"
|
||||
"Please note that in some cases parallelizing won't "
|
||||
"work with small buffer-sizes. If you experience "
|
||||
"problems (i.e. lot of xruns), try to increase buffer-"
|
||||
"size." ), smp_supp_tw );
|
||||
smp_help->setFixedSize( performance->width() - 20, 110 );
|
||||
#ifndef QT3
|
||||
smp_help->setWordWrap( TRUE );
|
||||
#else
|
||||
smp_help->setAlignment( Qt::WordBreak );
|
||||
#endif
|
||||
smp_help->move( 10, 55 );
|
||||
|
||||
|
||||
perf_layout->addWidget( ui_fx_tw );
|
||||
perf_layout->addSpacing( 15 );
|
||||
perf_layout->addWidget( smp_supp_tw );
|
||||
perf_layout->addStretch();
|
||||
|
||||
|
||||
@@ -721,6 +761,8 @@ void setupDialog::accept( void )
|
||||
QString::number( m_disableChActInd ) );
|
||||
configManager::inst()->setValue( "ui", "manualchannelpiano",
|
||||
QString::number( m_manualChPiano ) );
|
||||
configManager::inst()->setValue( "mixer", "parallelizinglevel",
|
||||
QString::number( m_parLevel ) );
|
||||
|
||||
configManager::inst()->setWorkingDir( m_workingDir );
|
||||
configManager::inst()->setVSTDir( m_vstDir );
|
||||
@@ -878,6 +920,13 @@ void setupDialog::toggleManualChPiano( bool _enabled )
|
||||
|
||||
|
||||
|
||||
void setupDialog::setParallelizingLevel( int _level )
|
||||
{
|
||||
m_parLevel = _level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setupDialog::openWorkingDir( void )
|
||||
{
|
||||
|
||||
@@ -734,7 +734,7 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
|
||||
|
||||
|
||||
|
||||
void instrumentTrack::playNote( notePlayHandle * _n )
|
||||
void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing )
|
||||
{
|
||||
// arpeggio- and chord-widget has to do its work -> adding sub-notes
|
||||
// for chords/arpeggios
|
||||
@@ -743,7 +743,7 @@ void instrumentTrack::playNote( notePlayHandle * _n )
|
||||
if( _n->arpBaseNote() == FALSE && m_instrument != NULL )
|
||||
{
|
||||
// all is done, so now lets play the note!
|
||||
m_instrument->playNote( _n );
|
||||
m_instrument->playNote( _n, _try_parallelizing );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,7 +1031,7 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start,
|
||||
note_frames,
|
||||
*cur_note );
|
||||
note_play_handle->setBBTrack( bb_track );
|
||||
note_play_handle->play();
|
||||
note_play_handle->play( FALSE );
|
||||
// could we play all within current number of
|
||||
// frames per audio-buffer?
|
||||
if( note_play_handle->done() == FALSE )
|
||||
|
||||
Reference in New Issue
Block a user