* 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:
@@ -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