From 3319380cf65ae50292816a31c2be3d46c4cf0c32 Mon Sep 17 00:00:00 2001 From: Vesa Date: Thu, 12 Jun 2014 22:34:32 +0300 Subject: [PATCH 1/4] FxMixer: Fix channel delete --- include/FxMixer.h | 4 ++-- src/core/FxMixer.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/FxMixer.h b/include/FxMixer.h index 7cecb7803..f8a7c86f6 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -22,8 +22,8 @@ * */ -#ifndef _FX_MIXER_H -#define _FX_MIXER_H +#ifndef FX_MIXER_H +#define FX_MIXER_H #include "Model.h" #include "Mixer.h" diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index d2c79a972..155be30cd 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -207,13 +207,13 @@ void FxMixer::deleteChannel(int index) } // delete all of this channel's sends and receives - for(int i=0; im_sends.size(); ++i) + while( ! m_fxChannels[index]->m_sends.isEmpty() ) { - deleteChannelSend(index, m_fxChannels[index]->m_sends[i]); + deleteChannelSend( index, m_fxChannels[index]->m_sends.first() ); } - for(int i=0; im_receives.size(); ++i) + while( ! m_fxChannels[index]->m_receives.isEmpty() ) { - deleteChannelSend(m_fxChannels[index]->m_receives[i], index); + deleteChannelSend( m_fxChannels[index]->m_receives.first(), index ); } for(int i=0; i Date: Sat, 14 Jun 2014 14:53:22 +0300 Subject: [PATCH 2/4] FxMixer: fix crashes on modifying sends Added a mutex so that the GUI thread can't change the sends around during the rendering loop. --- include/FxMixer.h | 1 + src/core/FxMixer.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/FxMixer.h b/include/FxMixer.h index f8a7c86f6..8136d9ed4 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -140,6 +140,7 @@ private: // make sure we have at least num channels void allocateChannelsTo(int num); + QMutex m_sendsMutex; void addChannelLeaf( int _ch, sampleFrame * _buf ); diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 155be30cd..02a6d3d8a 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -252,7 +252,7 @@ void FxMixer::moveChannelLeft(int index) { return; } - + m_sendsMutex.lock(); // channels to swap int a = index - 1, b = index; @@ -314,6 +314,7 @@ void FxMixer::moveChannelLeft(int index) FxChannel * tmpChannel = m_fxChannels[a]; m_fxChannels[a] = m_fxChannels[b]; m_fxChannels[b] = tmpChannel; + m_sendsMutex.unlock(); } @@ -340,7 +341,7 @@ void FxMixer::createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel, } // connection does not exist. create a new one - + m_sendsMutex.lock(); // add to from's sends from->m_sends.push_back(toChannel); from->m_sendAmount.push_back(new FloatModel(amount, 0, 1, 0.001, NULL, @@ -348,7 +349,7 @@ void FxMixer::createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel, // add to to's receives m_fxChannels[toChannel]->m_receives.push_back(fromChannel); - + m_sendsMutex.unlock(); } @@ -359,7 +360,7 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel) // delete the send FxChannel * from = m_fxChannels[fromChannel]; FxChannel * to = m_fxChannels[toChannel]; - + m_sendsMutex.lock(); // find and delete the send entry for(int i=0; im_sends.size(); ++i) { if( from->m_sends[i] == toChannel ) @@ -382,6 +383,7 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel) break; } } + m_sendsMutex.unlock(); } @@ -480,6 +482,7 @@ void FxMixer::masterMix( sampleFrame * _buf ) // and add all channels to job list that have no dependencies // when the channel completes it will check its parent to see if it needs // to be processed. + m_sendsMutex.lock(); MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic ); addChannelLeaf( 0, _buf ); while( m_fxChannels[0]->state() != ThreadableJob::Done ) @@ -487,6 +490,7 @@ void FxMixer::masterMix( sampleFrame * _buf ) MixerWorkerThread::startAndWaitForJobs(); } //m_fxChannels[0]->doProcessing( NULL ); + m_sendsMutex.unlock(); const float v = m_fxChannels[0]->m_volumeModel.value(); MixHelpers::addMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp ); From e733042cdbc29b3837448b36db190c6df1e83d35 Mon Sep 17 00:00:00 2001 From: Vesa Date: Sat, 14 Jun 2014 17:42:00 +0300 Subject: [PATCH 3/4] FxMixer: clearChannel had the same erroneous for loop as deleteChannel --- src/core/FxMixer.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 02a6d3d8a..961d6f8d6 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -538,9 +538,9 @@ void FxMixer::clearChannel(fx_ch_t index) if( index > 0) { // delete existing sends - for( int i=0; im_sends.size(); ++i) + while( ! ch->m_sends.isEmpty() ) { - deleteChannelSend(index, ch->m_sends[i]); + deleteChannelSend( index, ch->m_sends.first() ); } // add send to master @@ -548,11 +548,10 @@ void FxMixer::clearChannel(fx_ch_t index) } // delete receives - for( int i=0; im_receives.size(); ++i) + while( ! ch->m_receives.isEmpty() ) { - deleteChannelSend(ch->m_receives[i], index); + deleteChannelSend( ch->m_receives.first(), index ); } - } void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this ) From ad1c6957b0c19e6150fbc0ffb9dd6e63e50a2f1d Mon Sep 17 00:00:00 2001 From: Vesa Date: Sat, 14 Jun 2014 18:36:17 +0300 Subject: [PATCH 4/4] AutomatableModel: prevent linking of model to itself There's no need to ever link a model to itself, allowing it can cause weird issues and crashes, plus it's easy to do by accident if you start a ctrl-drag and end it while still on the same widget --- src/core/AutomatableModel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index b11374e9a..e8e22e5c2 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -394,7 +394,7 @@ float AutomatableModel::fittedValue( float value ) const void AutomatableModel::linkModel( AutomatableModel* model ) { - if( !m_linkedModels.contains( model ) ) + if( !m_linkedModels.contains( model ) && model != this ) { m_linkedModels.push_back( model ); m_hasLinkedModels = true; @@ -426,8 +426,8 @@ void AutomatableModel::unlinkModel( AutomatableModel* model ) void AutomatableModel::linkModels( AutomatableModel* model1, AutomatableModel* model2 ) { - model1->linkModel( model2 ); - model2->linkModel( model1 ); + model1->linkModel( model2 ); + model2->linkModel( model1 ); }