lock audioPort-buffers before writing them
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms-mv@725 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -27,6 +27,8 @@
|
||||
#define _AUDIO_PORT_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QMutexLocker>
|
||||
|
||||
#include "effect_chain.h"
|
||||
|
||||
@@ -46,6 +48,26 @@ public:
|
||||
return( m_secondBuffer );
|
||||
}
|
||||
|
||||
inline void lockFirstBuffer( void )
|
||||
{
|
||||
m_firstBufferLock.lock();
|
||||
}
|
||||
|
||||
inline void lockSecondBuffer( void )
|
||||
{
|
||||
m_secondBufferLock.lock();
|
||||
}
|
||||
|
||||
inline void unlockFirstBuffer( void )
|
||||
{
|
||||
m_firstBufferLock.unlock();
|
||||
}
|
||||
|
||||
inline void unlockSecondBuffer( void )
|
||||
{
|
||||
m_secondBufferLock.unlock();
|
||||
}
|
||||
|
||||
void nextPeriod( void );
|
||||
|
||||
|
||||
@@ -85,11 +107,14 @@ public:
|
||||
|
||||
enum bufferUsages
|
||||
{
|
||||
NONE, FIRST, BOTH
|
||||
NoUsage,
|
||||
FirstBuffer,
|
||||
BothBuffers
|
||||
} m_bufferUsage;
|
||||
|
||||
inline bool processEffects( void )
|
||||
{
|
||||
QMutexLocker m( &m_firstBufferLock );
|
||||
return( m_effects.processAudioBuffer( m_firstBuffer,
|
||||
m_frames ) );
|
||||
}
|
||||
@@ -97,6 +122,9 @@ public:
|
||||
private:
|
||||
surroundSampleFrame * m_firstBuffer;
|
||||
surroundSampleFrame * m_secondBuffer;
|
||||
QMutex m_firstBufferLock;
|
||||
QMutex m_secondBufferLock;
|
||||
|
||||
bool m_extOutputEnabled;
|
||||
fx_ch_t m_nextFxChannel;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
audioPort::audioPort( const QString & _name, track * _track ) :
|
||||
m_bufferUsage( NONE ),
|
||||
m_bufferUsage( NoUsage ),
|
||||
m_firstBuffer( new surroundSampleFrame[
|
||||
engine::getMixer()->framesPerPeriod()] ),
|
||||
m_secondBuffer( new surroundSampleFrame[
|
||||
@@ -70,12 +70,15 @@ audioPort::~audioPort()
|
||||
|
||||
void audioPort::nextPeriod( void )
|
||||
{
|
||||
m_firstBufferLock.lock();
|
||||
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 != NONE ) ?
|
||||
( ( m_bufferUsage == FIRST ) ? NONE : FIRST ) : NONE;
|
||||
m_bufferUsage = ( m_bufferUsage != NoUsage ) ?
|
||||
( ( m_bufferUsage == FirstBuffer ) ?
|
||||
NoUsage : FirstBuffer ) : NoUsage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
{
|
||||
audioPort * a = (audioPort *) it->job;
|
||||
bool me = a->processEffects();
|
||||
if( a->m_bufferUsage != audioPort::NONE || me )
|
||||
if( a->m_bufferUsage != audioPort::NoUsage || me )
|
||||
{
|
||||
m_mixer->processBuffer(
|
||||
a->firstBuffer(),
|
||||
@@ -567,7 +567,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
it != m_audioPorts.end(); ++it )
|
||||
{
|
||||
more_effects = ( *it )->processEffects();
|
||||
if( ( *it )->m_bufferUsage != audioPort::NONE ||
|
||||
if( ( *it )->m_bufferUsage != audioPort::NoUsage ||
|
||||
more_effects )
|
||||
{
|
||||
processBuffer( ( *it )->firstBuffer(),
|
||||
@@ -648,6 +648,7 @@ void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
|
||||
fpp_t end_frame = start_frame + _frames;
|
||||
const fpp_t loop1_frame = tMin( end_frame, m_framesPerPeriod );
|
||||
|
||||
_port->lockFirstBuffer();
|
||||
for( fpp_t frame = start_frame; frame < loop1_frame; ++frame )
|
||||
{
|
||||
for( ch_cnt_t chnl = 0; chnl < m_audioDev->channels(); ++chnl )
|
||||
@@ -658,7 +659,9 @@ void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
|
||||
_volume_vector.vol[chnl];
|
||||
}
|
||||
}
|
||||
_port->unlockFirstBuffer();
|
||||
|
||||
_port->lockSecondBuffer();
|
||||
if( end_frame > m_framesPerPeriod )
|
||||
{
|
||||
fpp_t frames_done = m_framesPerPeriod - start_frame;
|
||||
@@ -676,14 +679,14 @@ void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
|
||||
}
|
||||
}
|
||||
// we used both buffers so set flags
|
||||
_port->m_bufferUsage = audioPort::BOTH;
|
||||
_port->m_bufferUsage = audioPort::BothBuffers;
|
||||
}
|
||||
else if( _port->m_bufferUsage == audioPort::NONE )
|
||||
else if( _port->m_bufferUsage == audioPort::NoUsage )
|
||||
{
|
||||
// only first buffer touched
|
||||
_port->m_bufferUsage = audioPort::FIRST;
|
||||
_port->m_bufferUsage = audioPort::FirstBuffer;
|
||||
}
|
||||
|
||||
_port->unlockSecondBuffer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user