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:
@@ -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 );
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user