diff --git a/include/FxMixer.h b/include/FxMixer.h index 1d1f60b03..dcff82f31 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -201,7 +201,6 @@ private: // make sure we have at least num channels void allocateChannelsTo(int num); - QMutex m_sendsMutex; int m_lastSoloed; diff --git a/include/FxMixerView.h b/include/FxMixerView.h index 08d24fd09..6127ebd1b 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -30,8 +30,6 @@ #include #include -#include "FxLine.h" -#include "FxMixer.h" #include "ModelView.h" #include "Engine.h" #include "Fader.h" diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index f1d8abd12..616e6070a 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -211,9 +211,11 @@ FxMixer::~FxMixer() { deleteChannelSend( m_fxRoutes.first() ); } - for( int i = 0; i < m_fxChannels.size(); ++i ) + while( m_fxChannels.size() ) { - delete m_fxChannels[i]; + FxChannel * f = m_fxChannels[m_fxChannels.size() - 1]; + m_fxChannels.pop_back(); + delete f; } } @@ -288,8 +290,6 @@ void FxMixer::deleteChannel( int index ) // channel deletion is performed between mixer rounds Engine::mixer()->requestChangeInModel(); - FxChannel * ch = m_fxChannels[index]; - // go through every instrument and adjust for the channel index change TrackContainer::TrackList tracks; tracks += Engine::getSong()->tracks(); @@ -315,6 +315,8 @@ void FxMixer::deleteChannel( int index ) } } + FxChannel * ch = m_fxChannels[index]; + // delete all of this channel's sends and receives while( ! ch->m_sends.isEmpty() ) { @@ -326,8 +328,8 @@ void FxMixer::deleteChannel( int index ) } // actually delete the channel - delete m_fxChannels[index]; m_fxChannels.remove(index); + delete ch; for( int i = index; i < m_fxChannels.size(); ++i ) { @@ -434,7 +436,7 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount ) { return NULL; } - m_sendsMutex.lock(); + Engine::mixer()->requestChangeInModel(); FxRoute * route = new FxRoute( from, to, amount ); // add us to from's sends @@ -445,7 +447,7 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount ) // add us to fxmixer's list Engine::fxMixer()->m_fxRoutes.append( route ); - m_sendsMutex.unlock(); + Engine::mixer()->doneChangeInModel(); return route; } @@ -472,7 +474,7 @@ void FxMixer::deleteChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel ) void FxMixer::deleteChannelSend( FxRoute * route ) { - m_sendsMutex.lock(); + Engine::mixer()->requestChangeInModel(); // remove us from from's sends route->sender()->m_sends.remove( route->sender()->m_sends.indexOf( route ) ); // remove us from to's receives @@ -480,7 +482,7 @@ void FxMixer::deleteChannelSend( FxRoute * route ) // remove us from fxmixer's list Engine::fxMixer()->m_fxRoutes.remove( Engine::fxMixer()->m_fxRoutes.indexOf( route ) ); delete route; - m_sendsMutex.unlock(); + Engine::mixer()->doneChangeInModel(); } @@ -571,33 +573,46 @@ void FxMixer::masterMix( sampleFrame * _buf ) { const int fpp = Engine::mixer()->framesPerPeriod(); - if( m_sendsMutex.tryLock() ) + // add the channels that have no dependencies (no incoming senders, ie. + // no receives) to the jobqueue. The channels that have receives get + // added when their senders get processed, which is detected by + // dependency counting. + // also instantly add all muted channels as they don't need to care + // about their senders, and can just increment the deps of their + // recipients right away. + MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic ); + for( FxChannel * ch : m_fxChannels ) { - // add the channels that have no dependencies (no incoming senders, ie. no receives) - // to the jobqueue. The channels that have receives get added when their senders get processed, which - // is detected by dependency counting. - // also instantly add all muted channels as they don't need to care about their senders, and can just increment the deps of - // their recipients right away. - MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic ); + ch->m_muted = ch->m_muteModel.value(); + if( ch->m_muted ) // instantly "process" muted channels + { + ch->processed(); + ch->done(); + } + else if( ch->m_receives.size() == 0 ) + { + ch->m_queued = true; + MixerWorkerThread::addJob( ch ); + } + } + while( m_fxChannels[0]->state() != ThreadableJob::Done ) + { + bool found = false; for( FxChannel * ch : m_fxChannels ) { - ch->m_muted = ch->m_muteModel.value(); - if( ch->m_muted ) // instantly "process" muted channels + int s = ch->state(); + if( s == ThreadableJob::Queued + || s == ThreadableJob::InProgress ) { - ch->processed(); - ch->done(); - } - else if( ch->m_receives.size() == 0 ) - { - ch->m_queued = true; - MixerWorkerThread::addJob( ch ); + found = true; + break; } } - while( m_fxChannels[0]->state() != ThreadableJob::Done ) + if( !found ) { - MixerWorkerThread::startAndWaitForJobs(); + break; } - m_sendsMutex.unlock(); + MixerWorkerThread::startAndWaitForJobs(); } // handle sample-exact data in master volume fader diff --git a/src/core/JournallingObject.cpp b/src/core/JournallingObject.cpp index 4c3163f0c..1e15383d3 100644 --- a/src/core/JournallingObject.cpp +++ b/src/core/JournallingObject.cpp @@ -135,6 +135,7 @@ void JournallingObject::changeID( jo_id_t _id ) return; } + Engine::projectJournal()->freeID( m_id ); Engine::projectJournal()->reallocID( _id, this ); m_id = _id; } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 631f90601..52aa8f9e0 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -25,6 +25,7 @@ #include "Song.h" #include #include +#include #include #include #include diff --git a/src/core/midi/MidiPort.cpp b/src/core/midi/MidiPort.cpp index 7a745e2e0..4309966c0 100644 --- a/src/core/midi/MidiPort.cpp +++ b/src/core/midi/MidiPort.cpp @@ -341,7 +341,10 @@ void MidiPort::updateMidiPortMode() emit writablePortsChanged(); emit modeChanged(); - Engine::getSong()->setModified(); + if( Engine::getSong() ) + { + Engine::getSong()->setModified(); + } } diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 5ce2d2030..91a6dde8f 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -41,6 +41,8 @@ #include "Knob.h" #include "Engine.h" #include "embed.h" +#include "FxLine.h" +#include "FxMixer.h" #include "GuiApplication.h" #include "MainWindow.h" #include "Mixer.h" diff --git a/src/gui/widgets/EffectRackView.cpp b/src/gui/widgets/EffectRackView.cpp index 12202cf87..49be493e7 100644 --- a/src/gui/widgets/EffectRackView.cpp +++ b/src/gui/widgets/EffectRackView.cpp @@ -84,12 +84,12 @@ EffectRackView::~EffectRackView() void EffectRackView::clearViews() { - for( QVector::Iterator it = m_effectViews.begin(); - it != m_effectViews.end(); ++it ) + while( m_effectViews.size() ) { - delete *it; + EffectView * e = m_effectViews[m_effectViews.size() - 1]; + m_effectViews.pop_back(); + delete e; } - m_effectViews.clear(); }