* LADSPA-effect-plugin: improved handling of effects which only work at limited samplerates
* audio-port: small optimizations * mixer: removed obsolete idle-property of worker-threads * FX-mixer: protect individual buffers of FX-channels from being processed by more than one thread git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@979 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
17
ChangeLog
17
ChangeLog
@@ -1,3 +1,20 @@
|
||||
2008-05-17 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/ladspa_effect/ladspa_effect.cpp:
|
||||
* plugins/ladspa_effect/ladspa_effect.h:
|
||||
improved handling of effects which only work at limited samplerates
|
||||
|
||||
* include/audio_port.h:
|
||||
* src/core/audio/audio_port.cpp:
|
||||
small optimizations
|
||||
|
||||
* src/core/mixer.cpp:
|
||||
removed obsolete idle-property of worker-threads
|
||||
|
||||
* src/core/fx_mixer.cpp:
|
||||
protect individual buffers of FX-channels from being processed by more
|
||||
than one thread
|
||||
|
||||
2008-05-17 Paul Giblock <drfaygo/at/gmail/dot/com>
|
||||
|
||||
* plugins/stereo_matrix/stereomatrix_controls.cpp:
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
{
|
||||
return( m_firstBuffer );
|
||||
}
|
||||
|
||||
inline sampleFrame * secondBuffer( void )
|
||||
{
|
||||
return( m_secondBuffer );
|
||||
@@ -76,7 +77,8 @@ public:
|
||||
{
|
||||
return( m_extOutputEnabled );
|
||||
}
|
||||
void FASTCALL setExtOutputEnabled( bool _enabled );
|
||||
|
||||
void setExtOutputEnabled( bool _enabled );
|
||||
|
||||
|
||||
// next effect-channel after this audio-port
|
||||
@@ -105,21 +107,20 @@ public:
|
||||
void setName( const QString & _new_name );
|
||||
|
||||
|
||||
bool processEffects( void );
|
||||
|
||||
|
||||
enum bufferUsages
|
||||
{
|
||||
NoUsage,
|
||||
FirstBuffer,
|
||||
BothBuffers
|
||||
} m_bufferUsage;
|
||||
|
||||
inline bool processEffects( void )
|
||||
{
|
||||
QMutexLocker m( &m_firstBufferLock );
|
||||
return( m_effects.processAudioBuffer( m_firstBuffer,
|
||||
m_frames ) );
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
private:
|
||||
volatile bufferUsages m_bufferUsage;
|
||||
|
||||
sampleFrame * m_firstBuffer;
|
||||
sampleFrame * m_secondBuffer;
|
||||
QMutex m_firstBufferLock;
|
||||
@@ -131,7 +132,10 @@ private:
|
||||
QString m_name;
|
||||
|
||||
effectChain m_effects;
|
||||
fpp_t m_frames;
|
||||
|
||||
|
||||
friend class mixer;
|
||||
friend class mixerWorkerThread;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@ ladspaEffect::ladspaEffect( model * _parent,
|
||||
const descriptor::subPluginFeatures::key * _key ) :
|
||||
effect( &ladspaeffect_plugin_descriptor, _parent, _key ),
|
||||
m_controls( NULL ),
|
||||
m_effName( "none" ),
|
||||
m_publicName( "none" ),
|
||||
m_maxSampleRate( 0 ),
|
||||
m_key( ladspaSubPluginFeatures::subPluginKeyToLadspaKey( _key ) )
|
||||
{
|
||||
ladspa2LMMS * manager = engine::getLADSPAManager();
|
||||
@@ -76,7 +77,7 @@ ladspaEffect::ladspaEffect( model * _parent,
|
||||
setOkay( FALSE );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setPublicName( manager->getShortName( m_key ) );
|
||||
|
||||
pluginInstantiation();
|
||||
@@ -114,30 +115,200 @@ void ladspaEffect::changeSampleRate( void )
|
||||
|
||||
|
||||
|
||||
bool ladspaEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames )
|
||||
{
|
||||
m_pluginMutex.lock();
|
||||
if( !isOkay() || dontRun() || !isRunning() || !isEnabled() )
|
||||
{
|
||||
m_pluginMutex.unlock();
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
int frames = _frames;
|
||||
sampleFrame * o_buf = NULL;
|
||||
|
||||
int sr = m_maxSampleRate;
|
||||
if( sr < engine::getMixer()->processingSampleRate() )
|
||||
{
|
||||
o_buf = _buf;
|
||||
_buf = new sampleFrame[_frames];
|
||||
sampleDown( o_buf, _buf, sr );
|
||||
frames = _frames * sr /
|
||||
engine::getMixer()->processingSampleRate();
|
||||
}
|
||||
|
||||
// Copy the LMMS audio buffer to the LADSPA input buffer and initialize
|
||||
// the control ports. Need to change this to handle non-in-place-broken
|
||||
// plugins--would speed things up to use the same buffer for both
|
||||
// LMMS and LADSPA.
|
||||
ch_cnt_t channel = 0;
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); ++proc )
|
||||
{
|
||||
for( int port = 0; port < m_portCount; ++port )
|
||||
{
|
||||
switch( m_ports[proc][port]->rate )
|
||||
{
|
||||
case CHANNEL_IN:
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; ++frame )
|
||||
{
|
||||
m_ports[proc][port]->buffer[frame] =
|
||||
_buf[frame][channel];
|
||||
}
|
||||
++channel;
|
||||
break;
|
||||
case AUDIO_RATE_INPUT:
|
||||
m_ports[proc][port]->value =
|
||||
static_cast<LADSPA_Data>(
|
||||
m_ports[proc][port]->control->getValue() /
|
||||
m_ports[proc][port]->scale );
|
||||
// This only supports control rate ports, so the audio rates are
|
||||
// treated as though they were control rate by setting the
|
||||
// port buffer to all the same value.
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; ++frame )
|
||||
{
|
||||
m_ports[proc][port]->buffer[frame] =
|
||||
m_ports[proc][port]->value;
|
||||
}
|
||||
break;
|
||||
case CONTROL_RATE_INPUT:
|
||||
if( m_ports[proc][port]->control ==
|
||||
NULL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_ports[proc][port]->value =
|
||||
static_cast<LADSPA_Data>(
|
||||
m_ports[proc][port]->control->getValue() /
|
||||
m_ports[proc][port]->scale );
|
||||
m_ports[proc][port]->buffer[0] =
|
||||
m_ports[proc][port]->value;
|
||||
break;
|
||||
case CHANNEL_OUT:
|
||||
case AUDIO_RATE_OUTPUT:
|
||||
case CONTROL_RATE_OUTPUT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the buffers.
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); ++proc )
|
||||
{
|
||||
(m_descriptor->run)( m_handles[proc], frames );
|
||||
}
|
||||
|
||||
// Copy the LADSPA output buffers to the LMMS buffer.
|
||||
double out_sum = 0.0;
|
||||
channel = 0;
|
||||
const float d = getDryLevel();
|
||||
const float w = getWetLevel();
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); ++proc )
|
||||
{
|
||||
for( int port = 0; port < m_portCount; ++port )
|
||||
{
|
||||
switch( m_ports[proc][port]->rate )
|
||||
{
|
||||
case CHANNEL_IN:
|
||||
case AUDIO_RATE_INPUT:
|
||||
case CONTROL_RATE_INPUT:
|
||||
break;
|
||||
case CHANNEL_OUT:
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; ++frame )
|
||||
{
|
||||
_buf[frame][channel] =
|
||||
d *
|
||||
_buf[frame][channel] +
|
||||
w *
|
||||
m_ports[proc][port]->buffer[frame];
|
||||
out_sum +=
|
||||
_buf[frame][channel] *
|
||||
_buf[frame][channel];
|
||||
}
|
||||
++channel;
|
||||
break;
|
||||
case AUDIO_RATE_OUTPUT:
|
||||
case CONTROL_RATE_OUTPUT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( o_buf != NULL )
|
||||
{
|
||||
sampleBack( _buf, o_buf, sr );
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
// Check whether we need to continue processing input. Restart the
|
||||
// counter if the threshold has been exceeded.
|
||||
if( out_sum / frames <= getGate()+0.000001 )
|
||||
{
|
||||
incrementBufferCount();
|
||||
if( getBufferCount() > getTimeout() )
|
||||
{
|
||||
stopRunning();
|
||||
resetBufferCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetBufferCount();
|
||||
}
|
||||
|
||||
bool is_running = isRunning();
|
||||
m_pluginMutex.unlock();
|
||||
return( is_running );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ladspaEffect::setControl( int _control, LADSPA_Data _value )
|
||||
{
|
||||
if( !isOkay() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_portControls[_control]->value = _value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ladspaEffect::pluginInstantiation( void )
|
||||
{
|
||||
m_maxSampleRate = maxSamplerate( publicName() );
|
||||
|
||||
ladspa2LMMS * manager = engine::getLADSPAManager();
|
||||
|
||||
// Calculate how many processing units are needed.
|
||||
const ch_cnt_t lmms_chnls = engine::getMixer()->audioDev()->channels();
|
||||
m_effectChannels = manager->getDescription( m_key )->inputChannels;
|
||||
setProcessorCount( lmms_chnls / m_effectChannels );
|
||||
|
||||
int effect_channels = manager->getDescription( m_key )->inputChannels;
|
||||
setProcessorCount( lmms_chnls / effect_channels );
|
||||
|
||||
// Categorize the ports, and create the buffers.
|
||||
m_portCount = manager->getPortCount( m_key );
|
||||
|
||||
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
|
||||
{
|
||||
multi_proc_t ports;
|
||||
for( Uint16 port = 0; port < m_portCount; port++ )
|
||||
for( int port = 0; port < m_portCount; port++ )
|
||||
{
|
||||
port_desc_t * p = new portDescription;
|
||||
|
||||
|
||||
p->name = manager->getPortName( m_key, port );
|
||||
p->proc = proc;
|
||||
p->port_id = port;
|
||||
p->control = NULL;
|
||||
|
||||
|
||||
// Determine the port's category.
|
||||
if( manager->isPortAudio( m_key, port ) )
|
||||
{
|
||||
@@ -227,7 +398,7 @@ void ladspaEffect::pluginInstantiation( void )
|
||||
if( manager->areHintsSampleRateDependent(
|
||||
m_key, port ) )
|
||||
{
|
||||
p->max *= engine::getMixer()->processingSampleRate();
|
||||
p->max *= m_maxSampleRate;
|
||||
}
|
||||
|
||||
p->min = manager->getLowerBound( m_key, port );
|
||||
@@ -239,7 +410,7 @@ void ladspaEffect::pluginInstantiation( void )
|
||||
if( manager->areHintsSampleRateDependent(
|
||||
m_key, port ) )
|
||||
{
|
||||
p->min *= engine::getMixer()->processingSampleRate();
|
||||
p->min *= m_maxSampleRate;
|
||||
}
|
||||
|
||||
p->def = manager->getDefaultSetting( m_key, port );
|
||||
@@ -296,7 +467,7 @@ void ladspaEffect::pluginInstantiation( void )
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
|
||||
{
|
||||
LADSPA_Handle effect = manager->instantiate( m_key,
|
||||
engine::getMixer()->processingSampleRate() );
|
||||
m_maxSampleRate );
|
||||
if( effect == NULL )
|
||||
{
|
||||
QMessageBox::warning( 0, "Effect",
|
||||
@@ -311,7 +482,7 @@ void ladspaEffect::pluginInstantiation( void )
|
||||
// Connect the ports.
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
|
||||
{
|
||||
for( Uint16 port = 0; port < m_portCount; port++ )
|
||||
for( int port = 0; port < m_portCount; port++ )
|
||||
{
|
||||
if( !manager->connectPort( m_key,
|
||||
m_handles[proc],
|
||||
@@ -355,7 +526,7 @@ void ladspaEffect::pluginDestruction( void )
|
||||
ladspa2LMMS * manager = engine::getLADSPAManager();
|
||||
manager->deactivate( m_key, m_handles[proc] );
|
||||
manager->cleanup( m_key, m_handles[proc] );
|
||||
for( Uint16 port = 0; port < m_portCount; port++ )
|
||||
for( int port = 0; port < m_portCount; port++ )
|
||||
{
|
||||
free( m_ports[proc][port]->buffer );
|
||||
free( m_ports[proc][port] );
|
||||
@@ -370,171 +541,27 @@ void ladspaEffect::pluginDestruction( void )
|
||||
|
||||
|
||||
|
||||
bool ladspaEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames )
|
||||
|
||||
|
||||
static QMap<QString, int> __buggy_plugins;
|
||||
|
||||
int ladspaEffect::maxSamplerate( const QString & _name )
|
||||
{
|
||||
m_pluginMutex.lock();
|
||||
if( !isOkay() || dontRun() || !isRunning() || !isEnabled() )
|
||||
if( __buggy_plugins.isEmpty() )
|
||||
{
|
||||
m_pluginMutex.unlock();
|
||||
return( FALSE );
|
||||
__buggy_plugins["C * AmpVTS"] = 88200;
|
||||
__buggy_plugins["Chorus2"] = 44100;
|
||||
}
|
||||
|
||||
sampleFrame * o_buf = NULL;
|
||||
int frames = _frames;
|
||||
if( publicName().contains( "C* AmpVTS" ) &&
|
||||
engine::getMixer()->processingSampleRate() > 88200 )
|
||||
if( __buggy_plugins.contains( _name ) )
|
||||
{
|
||||
o_buf = _buf;
|
||||
_buf = new sampleFrame[_frames];
|
||||
sampleDown( o_buf, _buf, 88200 );
|
||||
frames = _frames * 88200 /
|
||||
engine::getMixer()->processingSampleRate();
|
||||
return( __buggy_plugins[_name] );
|
||||
}
|
||||
|
||||
// Copy the LMMS audio buffer to the LADSPA input buffer and initialize
|
||||
// the control ports. Need to change this to handle non-in-place-broken
|
||||
// plugins--would speed things up to use the same buffer for both
|
||||
// LMMS and LADSPA.
|
||||
ch_cnt_t channel = 0;
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++)
|
||||
{
|
||||
for( Uint16 port = 0; port < m_portCount; port++ )
|
||||
{
|
||||
switch( m_ports[proc][port]->rate )
|
||||
{
|
||||
case CHANNEL_IN:
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; frame++ )
|
||||
{
|
||||
m_ports[proc][port]->buffer[frame] =
|
||||
_buf[frame][channel];
|
||||
}
|
||||
channel++;
|
||||
break;
|
||||
case AUDIO_RATE_INPUT:
|
||||
m_ports[proc][port]->value =
|
||||
static_cast<LADSPA_Data>(
|
||||
m_ports[proc][port]->control->getValue() /
|
||||
m_ports[proc][port]->scale );
|
||||
// This only supports control rate ports, so the audio rates are
|
||||
// treated as though they were control rate by setting the
|
||||
// port buffer to all the same value.
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; frame++ )
|
||||
{
|
||||
m_ports[proc][port]->buffer[frame] =
|
||||
m_ports[proc][port]->value;
|
||||
}
|
||||
break;
|
||||
case CONTROL_RATE_INPUT:
|
||||
if( m_ports[proc][port]->control ==
|
||||
NULL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_ports[proc][port]->value =
|
||||
static_cast<LADSPA_Data>(
|
||||
m_ports[proc][port]->control->getValue() /
|
||||
m_ports[proc][port]->scale );
|
||||
m_ports[proc][port]->buffer[0] =
|
||||
m_ports[proc][port]->value;
|
||||
break;
|
||||
case CHANNEL_OUT:
|
||||
case AUDIO_RATE_OUTPUT:
|
||||
case CONTROL_RATE_OUTPUT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the buffers.
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++ )
|
||||
{
|
||||
(m_descriptor->run)(m_handles[proc], frames);
|
||||
}
|
||||
|
||||
// Copy the LADSPA output buffers to the LMMS buffer.
|
||||
double out_sum = 0.0;
|
||||
channel = 0;
|
||||
const float d = getDryLevel();
|
||||
const float w = getWetLevel();
|
||||
for( ch_cnt_t proc = 0; proc < getProcessorCount(); proc++)
|
||||
{
|
||||
for( Uint16 port = 0; port < m_portCount; port++ )
|
||||
{
|
||||
switch( m_ports[proc][port]->rate )
|
||||
{
|
||||
case CHANNEL_IN:
|
||||
case AUDIO_RATE_INPUT:
|
||||
case CONTROL_RATE_INPUT:
|
||||
break;
|
||||
case CHANNEL_OUT:
|
||||
for( fpp_t frame = 0;
|
||||
frame < frames; frame++ )
|
||||
{
|
||||
_buf[frame][channel] =
|
||||
d *
|
||||
_buf[frame][channel] +
|
||||
w *
|
||||
m_ports[proc][port]->buffer[frame];
|
||||
out_sum +=
|
||||
_buf[frame][channel] *
|
||||
_buf[frame][channel];
|
||||
}
|
||||
++channel;
|
||||
break;
|
||||
case AUDIO_RATE_OUTPUT:
|
||||
case CONTROL_RATE_OUTPUT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( o_buf != NULL )
|
||||
{
|
||||
sampleBack( _buf, o_buf, 88200 );
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
// Check whether we need to continue processing input. Restart the
|
||||
// counter if the threshold has been exceeded.
|
||||
if( out_sum / frames <= getGate()+0.000001 )
|
||||
{
|
||||
incrementBufferCount();
|
||||
if( getBufferCount() > getTimeout() )
|
||||
{
|
||||
stopRunning();
|
||||
resetBufferCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetBufferCount();
|
||||
}
|
||||
|
||||
bool is_running = isRunning();
|
||||
m_pluginMutex.unlock();
|
||||
return( is_running );
|
||||
return( engine::getMixer()->processingSampleRate() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ladspaEffect::setControl( Uint16 _control, LADSPA_Data _value )
|
||||
{
|
||||
if( !isOkay() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_portControls[_control]->value = _value;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
virtual bool processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames );
|
||||
|
||||
void setControl( Uint16 _control, LADSPA_Data _data );
|
||||
void setControl( int _control, LADSPA_Data _data );
|
||||
|
||||
virtual effectControls * getControls( void )
|
||||
{
|
||||
@@ -62,12 +62,12 @@ public:
|
||||
|
||||
virtual inline QString publicName( void ) const
|
||||
{
|
||||
return( m_effName );
|
||||
return( m_publicName );
|
||||
}
|
||||
|
||||
inline void setPublicName( const QString & _name )
|
||||
{
|
||||
m_effName = _name;
|
||||
m_publicName = _name;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,15 +79,16 @@ private:
|
||||
void pluginInstantiation( void );
|
||||
void pluginDestruction( void );
|
||||
|
||||
static int maxSamplerate( const QString & _name );
|
||||
|
||||
|
||||
QMutex m_pluginMutex;
|
||||
ladspaControls * m_controls;
|
||||
|
||||
QString m_effName;
|
||||
QString m_publicName;
|
||||
int m_maxSampleRate;
|
||||
ladspa_key_t m_key;
|
||||
Uint16 m_effectChannels;
|
||||
Uint16 m_portCount;
|
||||
fpp_t m_bufferSize;
|
||||
int m_portCount;
|
||||
|
||||
const LADSPA_Descriptor * m_descriptor;
|
||||
QVector<LADSPA_Handle> m_handles;
|
||||
|
||||
@@ -41,8 +41,7 @@ audioPort::audioPort( const QString & _name, track * _track ) :
|
||||
m_extOutputEnabled( FALSE ),
|
||||
m_nextFxChannel( 0 ),
|
||||
m_name( "unnamed port" ),
|
||||
m_effects( _track ),
|
||||
m_frames( engine::getMixer()->framesPerPeriod() )
|
||||
m_effects( _track )
|
||||
{
|
||||
engine::getMixer()->clearAudioBuffer( m_firstBuffer,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
@@ -72,11 +71,13 @@ void audioPort::nextPeriod( void )
|
||||
engine::getMixer()->clearAudioBuffer( m_firstBuffer,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
qSwap( m_firstBuffer, m_secondBuffer );
|
||||
m_firstBufferLock.unlock();
|
||||
|
||||
// this is how we decrease state of buffer-usage ;-)
|
||||
m_bufferUsage = ( m_bufferUsage != NoUsage ) ?
|
||||
( ( m_bufferUsage == FirstBuffer ) ?
|
||||
NoUsage : FirstBuffer ) : NoUsage;
|
||||
|
||||
m_firstBufferLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -108,4 +109,17 @@ void audioPort::setName( const QString & _name )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool audioPort::processEffects( void )
|
||||
{
|
||||
lockFirstBuffer();
|
||||
bool more = m_effects.processAudioBuffer( m_firstBuffer,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
unlockFirstBuffer();
|
||||
return( more );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -91,6 +91,7 @@ fxMixer::~fxMixer()
|
||||
|
||||
void fxMixer::mixToChannel( const sampleFrame * _buf, fx_ch_t _ch )
|
||||
{
|
||||
m_fxChannels[_ch]->m_lock.lock();
|
||||
sampleFrame * buf = m_fxChannels[_ch]->m_buffer;
|
||||
for( f_cnt_t f = 0; f < engine::getMixer()->framesPerPeriod(); ++f )
|
||||
{
|
||||
@@ -98,6 +99,7 @@ void fxMixer::mixToChannel( const sampleFrame * _buf, fx_ch_t _ch )
|
||||
buf[f][1] += _buf[f][1];
|
||||
}
|
||||
m_fxChannels[_ch]->m_used = TRUE;
|
||||
m_fxChannels[_ch]->m_lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -152,8 +152,7 @@ public:
|
||||
m_sem( &m_mixer->m_workerSem ),
|
||||
m_jobWait( 1 ),
|
||||
m_jobAccepted( 1 ),
|
||||
m_jobQueue( NULL ),
|
||||
m_idle( FALSE )
|
||||
m_jobQueue( NULL )
|
||||
{
|
||||
start( QThread::TimeCriticalPriority );
|
||||
}
|
||||
@@ -169,11 +168,6 @@ public:
|
||||
m_jobAccepted.acquire();
|
||||
}
|
||||
|
||||
inline bool idle( void )
|
||||
{
|
||||
return( m_idle );
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void run( void )
|
||||
@@ -183,11 +177,9 @@ private:
|
||||
sizeof( sampleFrame ) );
|
||||
m_jobWait.acquire();
|
||||
m_jobAccepted.acquire();
|
||||
m_idle = TRUE;
|
||||
while( 1 )
|
||||
{
|
||||
m_jobWait.acquire();
|
||||
m_idle = FALSE;
|
||||
m_sem->acquire();
|
||||
m_jobAccepted.release();
|
||||
for( jobQueueItems::iterator it =
|
||||
@@ -207,8 +199,8 @@ private:
|
||||
case AudioPortEffects:
|
||||
{
|
||||
audioPort * a = it->audioPortJob;
|
||||
bool me = a->processEffects();
|
||||
if( a->m_bufferUsage != audioPort::NoUsage || me )
|
||||
const bool me = a->processEffects();
|
||||
if( me || a->m_bufferUsage != audioPort::NoUsage )
|
||||
{
|
||||
engine::getFxMixer()->mixToChannel( a->firstBuffer(),
|
||||
a->nextFxChannel() );
|
||||
@@ -228,7 +220,6 @@ private:
|
||||
m_jobQueue->lock.unlock();
|
||||
}
|
||||
}
|
||||
m_idle = TRUE;
|
||||
m_sem->release();
|
||||
}
|
||||
aligned_free( working_buf );
|
||||
@@ -239,7 +230,6 @@ private:
|
||||
QSemaphore m_jobWait;
|
||||
QSemaphore m_jobAccepted;
|
||||
jobQueue * m_jobQueue;
|
||||
volatile bool m_idle;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user