NOT WORKING! Fx Mixer uses job threads

The FxMixer now uses job threads to accomplish its mixing. It's
theoretically efficient, but there is a horrible thread bug
preventing the code from working. I've spent 5 hours debugging and
need some external help!
This commit is contained in:
Andrew Kelley
2009-10-12 01:09:35 -07:00
parent 3fa96a576c
commit f6f4414c98
3 changed files with 147 additions and 72 deletions

View File

@@ -33,31 +33,38 @@
struct FxChannel
class FxChannel : public ThreadableJob
{
FxChannel( Model * _parent );
~FxChannel();
public:
FxChannel( Model * _parent );
~FxChannel();
EffectChain m_fxChain;
EffectChain m_fxChain;
// set to true if any effect in the channel is enabled and running
bool m_stillRunning;
// set to true if any effect in the channel is enabled and running
bool m_stillRunning;
float m_peakLeft;
float m_peakRight;
sampleFrame * m_buffer;
BoolModel m_muteModel;
FloatModel m_volumeModel;
QString m_name;
QMutex m_lock;
float m_peakLeft;
float m_peakRight;
sampleFrame * m_buffer;
BoolModel m_muteModel;
FloatModel m_volumeModel;
QString m_name;
QMutex m_lock;
int m_channelIndex; // what channel index are we
// pointers to other channels that this one sends to
QVector<fx_ch_t> m_sends;
QVector<FloatModel *> m_sendAmount;
// pointers to other channels that this one sends to
QVector<fx_ch_t> m_sends;
QVector<FloatModel *> m_sendAmount;
// pointers to other channels that send to this one
QVector<fx_ch_t> m_receives;
} ;
// pointers to other channels that send to this one
QVector<fx_ch_t> m_receives;
virtual bool requiresProcessing() const { return true; }
private:
virtual void doProcessing( sampleFrame * _working_buffer );
};
@@ -128,9 +135,11 @@ private:
// the fx channels in the mixer. index 0 is always master.
QVector<FxChannel *> m_fxChannels;
// make sure we have at least num channels
void allocateChannelsTo(int num);
void addChannelLeaf( int _ch, sampleFrame * _buf );
friend class mixerWorkerThread;
friend class FxMixerView;

View File

@@ -69,21 +69,31 @@ class MixerWorkerThread;
class ThreadableJob
{
public:
enum ProcessingState
{
Unstarted,
Queued,
InProgress,
Done
};
ThreadableJob() :
m_done( false )
m_state( ThreadableJob::Unstarted )
{
}
void reset()
{
m_done = false;
m_state = ThreadableJob::Unstarted;
}
bool process( sampleFrame * _working_buffer )
{
if( m_done.fetchAndStoreOrdered( true ) == false )
if( m_state.testAndSetOrdered( Queued, InProgress ) )
{
doProcessing( _working_buffer );
m_state = Done;
return true;
}
return false;
@@ -91,12 +101,11 @@ public:
virtual bool requiresProcessing() const = 0;
QAtomicInt m_state;
private:
virtual void doProcessing( sampleFrame * _working_buffer ) = 0;
QAtomicInt m_done;
} ;
@@ -575,7 +584,7 @@ public:
{
if( _job->requiresProcessing() )
{
_job->reset();
_job->m_state = ThreadableJob::Queued;
s_jobQueue.items[s_jobQueue.queueSize.fetchAndAddOrdered(1)] = _job;
}
}