From 32b7e0418b55d2fb6e45bff9a32103e532a9dab5 Mon Sep 17 00:00:00 2001 From: Fastigium Date: Mon, 14 Mar 2016 13:37:00 +0100 Subject: [PATCH] Fix two crashes when deleting FX channels Lock the mixer before performing a channel delete to prevent any race conditions causing a crash. Also, update the audioport FX channel when an InstrumentTrack's FX channel is changed to prevent the audioport mixing to a nonexistent channel. --- include/FxMixer.h | 1 - include/InstrumentTrack.h | 1 + src/core/FxMixer.cpp | 13 +++++-------- src/tracks/InstrumentTrack.cpp | 11 +++++++++-- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/FxMixer.h b/include/FxMixer.h index ac5c72530..a00df914a 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -56,7 +56,6 @@ class FxChannel : public ThreadableJob BoolModel m_soloModel; FloatModel m_volumeModel; QString m_name; - QMutex m_lock; int m_channelIndex; // what channel index are we bool m_queued; // are we queued up for rendering yet? bool m_muted; // are we muted? updated per period so we don't have to call m_muteModel.value() twice diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 4067d2d37..f24097c9d 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -227,6 +227,7 @@ protected slots: void updateBaseNote(); void updatePitch(); void updatePitchRange(); + void updateEffectChannel(); private: diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index be4378bd8..6ed83d45b 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -68,7 +68,6 @@ FxChannel::FxChannel( int idx, Model * _parent ) : m_soloModel( false, _parent ), m_volumeModel( 1.0, 0.0, 2.0, 0.001, _parent ), m_name(), - m_lock(), m_channelIndex( idx ), m_queued( false ), m_dependenciesMet( 0 ) @@ -284,7 +283,8 @@ void FxMixer::toggledSolo() void FxMixer::deleteChannel( int index ) { - m_fxChannels[index]->m_lock.lock(); + // lock the mixer so channel deletion is performed between mixer rounds + Engine::mixer()->lock(); FxChannel * ch = m_fxChannels[index]; @@ -344,6 +344,8 @@ void FxMixer::deleteChannel( int index ) r->updateName(); } } + + Engine::mixer()->unlock(); } @@ -543,15 +545,10 @@ FloatModel * FxMixer::channelSendModel( fx_ch_t fromChannel, fx_ch_t toChannel ) void FxMixer::mixToChannel( const sampleFrame * _buf, fx_ch_t _ch ) { - // The first check is for the case where the last fxchannel was deleted but - // there was a race condition where it had to be processed. - if( _ch < m_fxChannels.size() && - m_fxChannels[_ch]->m_muteModel.value() == false ) + if( m_fxChannels[_ch]->m_muteModel.value() == false ) { - m_fxChannels[_ch]->m_lock.lock(); MixHelpers::add( m_fxChannels[_ch]->m_buffer, _buf, Engine::mixer()->framesPerPeriod() ); m_fxChannels[_ch]->m_hasInput = true; - m_fxChannels[_ch]->m_lock.unlock(); } } diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index d1eb5bc1e..b98c9a1d5 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -139,6 +139,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) : connect( &m_baseNoteModel, SIGNAL( dataChanged() ), this, SLOT( updateBaseNote() ) ); connect( &m_pitchModel, SIGNAL( dataChanged() ), this, SLOT( updatePitch() ) ); connect( &m_pitchRangeModel, SIGNAL( dataChanged() ), this, SLOT( updatePitchRange() ) ); + connect( &m_effectChannelModel, SIGNAL( dataChanged() ), this, SLOT( updateEffectChannel() ) ); } @@ -220,8 +221,6 @@ void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, } } } - - m_audioPort.setNextFxChannel( m_effectChannelModel.value() ); } @@ -558,6 +557,14 @@ void InstrumentTrack::updatePitchRange() +void InstrumentTrack::updateEffectChannel() +{ + m_audioPort.setNextFxChannel( m_effectChannelModel.value() ); +} + + + + int InstrumentTrack::masterKey( int _midi_key ) const {