removed fine-granular locking of various playHandle-vectors, just use one global big lock for everything now - prevents various deadlocks (e.g. when previewing samples in file browser)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1738 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
101
include/mixer.h
101
include/mixer.h
@@ -117,21 +117,21 @@ public:
|
||||
case Mode_Draft:
|
||||
interpolation = Interpolation_Linear;
|
||||
oversampling = Oversampling_None;
|
||||
sampleExactControllers = FALSE;
|
||||
aliasFreeOscillators = FALSE;
|
||||
sampleExactControllers = false;
|
||||
aliasFreeOscillators = false;
|
||||
break;
|
||||
case Mode_HighQuality:
|
||||
interpolation =
|
||||
Interpolation_SincFastest;
|
||||
oversampling = Oversampling_2x;
|
||||
sampleExactControllers = TRUE;
|
||||
aliasFreeOscillators = FALSE;
|
||||
sampleExactControllers = true;
|
||||
aliasFreeOscillators = false;
|
||||
break;
|
||||
case Mode_FinalMix:
|
||||
interpolation = Interpolation_SincBest;
|
||||
oversampling = Oversampling_8x;
|
||||
sampleExactControllers = TRUE;
|
||||
aliasFreeOscillators = TRUE;
|
||||
sampleExactControllers = true;
|
||||
aliasFreeOscillators = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
case Oversampling_4x: return 4;
|
||||
case Oversampling_8x: return 8;
|
||||
}
|
||||
return( 1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int libsrcInterpolation( void ) const
|
||||
@@ -162,15 +162,15 @@ public:
|
||||
switch( interpolation )
|
||||
{
|
||||
case Interpolation_Linear:
|
||||
return( SRC_ZERO_ORDER_HOLD );
|
||||
return SRC_ZERO_ORDER_HOLD;
|
||||
case Interpolation_SincFastest:
|
||||
return( SRC_SINC_FASTEST );
|
||||
return SRC_SINC_FASTEST;
|
||||
case Interpolation_SincMedium:
|
||||
return( SRC_SINC_MEDIUM_QUALITY );
|
||||
return SRC_SINC_MEDIUM_QUALITY;
|
||||
case Interpolation_SincBest:
|
||||
return( SRC_SINC_BEST_QUALITY );
|
||||
return SRC_SINC_BEST_QUALITY;
|
||||
}
|
||||
return( SRC_LINEAR );
|
||||
return SRC_LINEAR;
|
||||
}
|
||||
} ;
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
// audio-device-stuff
|
||||
inline const QString & audioDevName( void ) const
|
||||
{
|
||||
return( m_audioDevName );
|
||||
return m_audioDevName;
|
||||
}
|
||||
|
||||
void setAudioDevice( audioDevice * _dev );
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
void restoreAudioDevice( void );
|
||||
inline audioDevice * audioDev( void )
|
||||
{
|
||||
return( m_audioDev );
|
||||
return m_audioDev;
|
||||
}
|
||||
|
||||
|
||||
@@ -203,70 +203,59 @@ public:
|
||||
unlock();
|
||||
}
|
||||
|
||||
inline void removeAudioPort( audioPort * _port )
|
||||
{
|
||||
lock();
|
||||
QVector<audioPort *>::iterator it = qFind( m_audioPorts.begin(),
|
||||
m_audioPorts.end(),
|
||||
_port );
|
||||
if( it != m_audioPorts.end() )
|
||||
{
|
||||
m_audioPorts.erase( it );
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
void removeAudioPort( audioPort * _port );
|
||||
|
||||
|
||||
// MIDI-client-stuff
|
||||
inline const QString & midiClientName( void ) const
|
||||
{
|
||||
return( m_midiClientName );
|
||||
return m_midiClientName;
|
||||
}
|
||||
|
||||
inline midiClient * getMidiClient( void )
|
||||
{
|
||||
return( m_midiClient );
|
||||
return m_midiClient;
|
||||
}
|
||||
|
||||
|
||||
// play-handle stuff
|
||||
inline bool addPlayHandle( playHandle * _ph )
|
||||
{
|
||||
if( criticalXRuns() == FALSE )
|
||||
if( criticalXRuns() == false )
|
||||
{
|
||||
lockPlayHandles();
|
||||
lock();
|
||||
m_playHandles.push_back( _ph );
|
||||
unlockPlayHandles();
|
||||
return( TRUE );
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
delete _ph;
|
||||
return( FALSE );
|
||||
return false;
|
||||
}
|
||||
|
||||
void removePlayHandle( playHandle * _ph );
|
||||
|
||||
inline playHandleVector & playHandles( void )
|
||||
{
|
||||
return( m_playHandles );
|
||||
return m_playHandles;
|
||||
}
|
||||
|
||||
void removePlayHandles( track * _track );
|
||||
|
||||
inline bool hasPlayHandles( void ) const
|
||||
{
|
||||
return( !m_playHandles.empty() );
|
||||
return !m_playHandles.empty();
|
||||
}
|
||||
|
||||
|
||||
// methods providing information for other classes
|
||||
inline fpp_t framesPerPeriod( void ) const
|
||||
{
|
||||
return( m_framesPerPeriod );
|
||||
return m_framesPerPeriod;
|
||||
}
|
||||
|
||||
inline const surroundSampleFrame * currentReadBuffer( void ) const
|
||||
{
|
||||
return( m_readBuf );
|
||||
return m_readBuf;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +266,7 @@ public:
|
||||
|
||||
const qualitySettings & currentQualitySettings( void ) const
|
||||
{
|
||||
return( m_qualitySettings );
|
||||
return m_qualitySettings;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +278,7 @@ public:
|
||||
|
||||
inline float masterGain( void ) const
|
||||
{
|
||||
return( m_masterGain );
|
||||
return m_masterGain;
|
||||
}
|
||||
|
||||
inline void setMasterGain( const float _mo )
|
||||
@@ -302,13 +291,13 @@ public:
|
||||
{
|
||||
if( _s > 1.0f )
|
||||
{
|
||||
return( 1.0f );
|
||||
return 1.0f;
|
||||
}
|
||||
else if( _s < -1.0f )
|
||||
{
|
||||
return( -1.0f );
|
||||
return -1.0f;
|
||||
}
|
||||
return( _s );
|
||||
return _s;
|
||||
}
|
||||
|
||||
|
||||
@@ -323,26 +312,6 @@ public:
|
||||
m_globalMutex.unlock();
|
||||
}
|
||||
|
||||
void lockPlayHandles( void )
|
||||
{
|
||||
m_playHandlesMutex.lock();
|
||||
}
|
||||
|
||||
void unlockPlayHandles( void )
|
||||
{
|
||||
m_playHandlesMutex.unlock();
|
||||
}
|
||||
|
||||
void lockPlayHandlesToRemove( void )
|
||||
{
|
||||
m_playHandlesToRemoveMutex.lock();
|
||||
}
|
||||
|
||||
void unlockPlayHandlesToRemove( void )
|
||||
{
|
||||
m_playHandlesToRemoveMutex.unlock();
|
||||
}
|
||||
|
||||
void lockInputFrames( void )
|
||||
{
|
||||
m_inputFramesMutex.lock();
|
||||
@@ -377,7 +346,7 @@ public:
|
||||
|
||||
inline bool hasFifoWriter( void ) const
|
||||
{
|
||||
return( m_fifoWriter != NULL );
|
||||
return m_fifoWriter != NULL;
|
||||
}
|
||||
|
||||
void pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames );
|
||||
@@ -394,7 +363,7 @@ public:
|
||||
|
||||
inline const surroundSampleFrame * nextBuffer( void )
|
||||
{
|
||||
return( hasFifoWriter() ? m_fifo->read() : renderNextBuffer() );
|
||||
return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
|
||||
}
|
||||
|
||||
void changeQuality( const struct qualitySettings & _qs );
|
||||
@@ -430,7 +399,7 @@ private:
|
||||
mixer( void );
|
||||
virtual ~mixer();
|
||||
|
||||
void startProcessing( bool _needs_fifo = TRUE );
|
||||
void startProcessing( bool _needs_fifo = true );
|
||||
void stopProcessing( void );
|
||||
|
||||
|
||||
@@ -494,8 +463,6 @@ private:
|
||||
|
||||
|
||||
QMutex m_globalMutex;
|
||||
QMutex m_playHandlesMutex;
|
||||
QMutex m_playHandlesToRemoveMutex;
|
||||
QMutex m_inputFramesMutex;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#ifndef SINGLE_SOURCE_COMPILE
|
||||
|
||||
/*
|
||||
* mixer.cpp - audio-device-independent mixer for LMMS
|
||||
*
|
||||
@@ -25,8 +23,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <QtCore/QWaitCondition>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "mixer.h"
|
||||
@@ -70,8 +66,6 @@ static QVector<fx_ch_t> __fx_channel_jobs( NumFxChannels );
|
||||
|
||||
|
||||
|
||||
#define ALIGN_SIZE 64
|
||||
|
||||
static void aligned_free( void * _buf )
|
||||
{
|
||||
if( _buf != NULL )
|
||||
@@ -560,8 +554,6 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
// remove all play-handles that have to be deleted and delete
|
||||
// them if they still exist...
|
||||
// maybe this algorithm could be optimized...
|
||||
lockPlayHandles();
|
||||
lockPlayHandlesToRemove();
|
||||
constPlayHandleVector::iterator it_rem = m_playHandlesToRemove.begin();
|
||||
while( it_rem != m_playHandlesToRemove.end() )
|
||||
{
|
||||
@@ -576,8 +568,6 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
|
||||
it_rem = m_playHandlesToRemove.erase( it_rem );
|
||||
}
|
||||
unlockPlayHandlesToRemove();
|
||||
unlockPlayHandles();
|
||||
|
||||
// now swap the buffers... current buffer becomes next (last)
|
||||
// buffer and the next buffer becomes current (first) buffer
|
||||
@@ -602,7 +592,6 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
engine::getFxMixer()->prepareMasterMix();
|
||||
engine::getSong()->processNextBuffer();
|
||||
|
||||
lockPlayHandles();
|
||||
if( m_multiThreaded )
|
||||
{
|
||||
FILL_JOB_QUEUE(playHandleVector,m_playHandles,
|
||||
@@ -645,7 +634,6 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
++it;
|
||||
}
|
||||
}
|
||||
unlockPlayHandles();
|
||||
|
||||
if( m_multiThreaded )
|
||||
{
|
||||
@@ -710,8 +698,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
void mixer::clear( void )
|
||||
{
|
||||
// TODO: m_midiClient->noteOffAll();
|
||||
lockPlayHandles();
|
||||
lockPlayHandlesToRemove();
|
||||
lock();
|
||||
for( playHandleVector::iterator it = m_playHandles.begin();
|
||||
it != m_playHandles.end(); ++it )
|
||||
{
|
||||
@@ -722,8 +709,7 @@ void mixer::clear( void )
|
||||
m_playHandlesToRemove.push_back( *it );
|
||||
}
|
||||
}
|
||||
unlockPlayHandlesToRemove();
|
||||
unlockPlayHandles();
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -930,14 +916,30 @@ void mixer::restoreAudioDevice( void )
|
||||
|
||||
|
||||
|
||||
void mixer::removeAudioPort( audioPort * _port )
|
||||
{
|
||||
QVector<audioPort *>::iterator it = qFind( m_audioPorts.begin(),
|
||||
m_audioPorts.end(),
|
||||
_port );
|
||||
if( it != m_audioPorts.end() )
|
||||
{
|
||||
lock();
|
||||
m_audioPorts.erase( it );
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void mixer::removePlayHandle( playHandle * _ph )
|
||||
{
|
||||
lock();
|
||||
// check thread affinity as we must not delete play-handles
|
||||
// which were created in a thread different than mixer thread
|
||||
if( _ph->affinityMatters() &&
|
||||
_ph->affinity() == QThread::currentThread() )
|
||||
{
|
||||
lockPlayHandles();
|
||||
playHandleVector::iterator it =
|
||||
qFind( m_playHandles.begin(),
|
||||
m_playHandles.end(), _ph );
|
||||
@@ -946,21 +948,20 @@ void mixer::removePlayHandle( playHandle * _ph )
|
||||
m_playHandles.erase( it );
|
||||
delete _ph;
|
||||
}
|
||||
unlockPlayHandles();
|
||||
}
|
||||
else
|
||||
{
|
||||
lockPlayHandlesToRemove();
|
||||
m_playHandlesToRemove.push_back( _ph );
|
||||
unlockPlayHandlesToRemove();
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void mixer::removePlayHandles( track * _track )
|
||||
{
|
||||
lockPlayHandles();
|
||||
lock();
|
||||
playHandleVector::iterator it = m_playHandles.begin();
|
||||
while( it != m_playHandles.end() )
|
||||
{
|
||||
@@ -974,7 +975,7 @@ void mixer::removePlayHandles( track * _track )
|
||||
++it;
|
||||
}
|
||||
}
|
||||
unlockPlayHandles();
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1202,5 +1203,3 @@ void mixer::fifoWriter::run( void )
|
||||
|
||||
#include "moc_mixer.cxx"
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user