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:
Tobias Doerffel
2008-02-27 17:49:35 +00:00
parent c043eed2d6
commit a7b14c6660
3 changed files with 44 additions and 10 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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();
}