From ccd4ff3c2c2abcbadcf7a5f8cef750ae7cafa34c Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 29 Apr 2018 17:01:51 +0200 Subject: [PATCH 1/8] Fix job queue crash * Don't add jobs when job queue is full * Icrease job queue size from 1024 to 8192 --- include/MixerWorkerThread.h | 2 +- src/core/MixerWorkerThread.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/MixerWorkerThread.h b/include/MixerWorkerThread.h index 8b900195f..4af42897c 100644 --- a/include/MixerWorkerThread.h +++ b/include/MixerWorkerThread.h @@ -62,7 +62,7 @@ public: void wait(); private: -#define JOB_QUEUE_SIZE 1024 +#define JOB_QUEUE_SIZE 8192 QAtomicPointer m_items[JOB_QUEUE_SIZE]; AtomicInt m_queueSize; AtomicInt m_itemsDone; diff --git a/src/core/MixerWorkerThread.cpp b/src/core/MixerWorkerThread.cpp index e8c6bd61c..14363f4d1 100644 --- a/src/core/MixerWorkerThread.cpp +++ b/src/core/MixerWorkerThread.cpp @@ -25,6 +25,7 @@ #include "MixerWorkerThread.h" #include "denormals.h" +#include #include #include #include "ThreadableJob.h" @@ -54,7 +55,13 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) // update job state _job->queue(); // actually queue the job via atomic operations - m_items[m_queueSize.fetchAndAddOrdered(1)] = _job; + auto index = m_queueSize.fetchAndAddOrdered(1); + if (index < JOB_QUEUE_SIZE) { + m_items[index] = _job; + } else { + qWarning() << "Job queue is full!"; + m_itemsDone.fetchAndAddOrdered(1); + } } } @@ -66,7 +73,7 @@ void MixerWorkerThread::JobQueue::run() while( processedJob && (int) m_itemsDone < (int) m_queueSize ) { processedJob = false; - for( int i = 0; i < m_queueSize; ++i ) + for( int i = 0; i < m_queueSize && i < JOB_QUEUE_SIZE; ++i ) { ThreadableJob * job = m_items[i].fetchAndStoreOrdered( NULL ); if( job ) From 9a52c7b901611ab6dfb7f480d3883e97fb53672b Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 2 May 2018 12:54:45 +0200 Subject: [PATCH 2/8] JobQueue: Rename m_queueSize to m_writeIndex Hopefully makes it less confusing that m_writeIndex grows beyond JOB_QUEUE_SIZE when the queue is full. --- include/MixerWorkerThread.h | 4 ++-- src/core/MixerWorkerThread.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/MixerWorkerThread.h b/include/MixerWorkerThread.h index 4af42897c..8d6b0c72a 100644 --- a/include/MixerWorkerThread.h +++ b/include/MixerWorkerThread.h @@ -48,7 +48,7 @@ public: JobQueue() : m_items(), - m_queueSize( 0 ), + m_writeIndex( 0 ), m_itemsDone( 0 ), m_opMode( Static ) { @@ -64,7 +64,7 @@ public: private: #define JOB_QUEUE_SIZE 8192 QAtomicPointer m_items[JOB_QUEUE_SIZE]; - AtomicInt m_queueSize; + AtomicInt m_writeIndex; AtomicInt m_itemsDone; OperationMode m_opMode; diff --git a/src/core/MixerWorkerThread.cpp b/src/core/MixerWorkerThread.cpp index 14363f4d1..ae5d50564 100644 --- a/src/core/MixerWorkerThread.cpp +++ b/src/core/MixerWorkerThread.cpp @@ -40,7 +40,7 @@ QList MixerWorkerThread::workerThreads; // implementation of internal JobQueue void MixerWorkerThread::JobQueue::reset( OperationMode _opMode ) { - m_queueSize = 0; + m_writeIndex = 0; m_itemsDone = 0; m_opMode = _opMode; } @@ -55,7 +55,7 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) // update job state _job->queue(); // actually queue the job via atomic operations - auto index = m_queueSize.fetchAndAddOrdered(1); + auto index = m_writeIndex.fetchAndAddOrdered(1); if (index < JOB_QUEUE_SIZE) { m_items[index] = _job; } else { @@ -70,10 +70,10 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job ) void MixerWorkerThread::JobQueue::run() { bool processedJob = true; - while( processedJob && (int) m_itemsDone < (int) m_queueSize ) + while( processedJob && (int) m_itemsDone < (int) m_writeIndex ) { processedJob = false; - for( int i = 0; i < m_queueSize && i < JOB_QUEUE_SIZE; ++i ) + for( int i = 0; i < m_writeIndex && i < JOB_QUEUE_SIZE; ++i ) { ThreadableJob * job = m_items[i].fetchAndStoreOrdered( NULL ); if( job ) @@ -93,7 +93,7 @@ void MixerWorkerThread::JobQueue::run() void MixerWorkerThread::JobQueue::wait() { - while( (int) m_itemsDone < (int) m_queueSize ) + while( (int) m_itemsDone < (int) m_writeIndex ) { #if defined(LMMS_HOST_X86) || defined(LMMS_HOST_X86_64) asm( "pause" ); From 511c7a64febe7c01757e455ca6fe322b5bf33089 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Thu, 3 May 2018 11:23:35 +0900 Subject: [PATCH 3/8] Fix occasional crash when moving TCOs --- src/core/Track.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 88266d36c..8af5393dc 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -143,7 +143,9 @@ void TrackContentObject::movePosition( const MidiTime & pos ) { if( m_startPosition != pos ) { + Engine::mixer()->requestChangeInModel(); m_startPosition = pos; + Engine::mixer()->doneChangeInModel(); Engine::getSong()->updateLength(); emit positionChanged(); } From 03aa5fb3c76b2b95b854d9b10da14f2e9914800a Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 8 May 2018 09:08:43 +0900 Subject: [PATCH 4/8] Fix crash on exit from MIDI connections (#4340) --- include/MidiPort.h | 2 ++ src/core/midi/MidiClient.cpp | 4 ++++ src/core/midi/MidiPort.cpp | 8 +++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/MidiPort.h b/include/MidiPort.h index c8a3c6e44..07c61d788 100644 --- a/include/MidiPort.h +++ b/include/MidiPort.h @@ -124,6 +124,8 @@ public: return m_writablePorts; } + void invalidateCilent(); + MidiPortMenu* m_readablePortsMenu; MidiPortMenu* m_writablePortsMenu; diff --git a/src/core/midi/MidiClient.cpp b/src/core/midi/MidiClient.cpp index 8ba70bcb7..b88c64db1 100644 --- a/src/core/midi/MidiClient.cpp +++ b/src/core/midi/MidiClient.cpp @@ -38,6 +38,10 @@ MidiClient::MidiClient() MidiClient::~MidiClient() { //TODO: noteOffAll(); / clear all ports + for (MidiPort* port : m_midiPorts) + { + port->invalidateCilent(); + } } diff --git a/src/core/midi/MidiPort.cpp b/src/core/midi/MidiPort.cpp index 43019876e..9e3cdb13d 100644 --- a/src/core/midi/MidiPort.cpp +++ b/src/core/midi/MidiPort.cpp @@ -27,9 +27,12 @@ #include "MidiPort.h" #include "MidiClient.h" +#include "MidiDummy.h" #include "Note.h" #include "Song.h" +static MidiDummy s_dummyClient; + MidiPort::MidiPort( const QString& name, @@ -410,4 +413,7 @@ void MidiPort::updateOutputProgram() - +void MidiPort::invalidateCilent() +{ + m_midiClient = &s_dummyClient; +} From bb43bfb96157be25123f831e6c398162e00aa4da Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Thu, 17 May 2018 18:39:31 +0200 Subject: [PATCH 5/8] Remove release time from arpeggiated note (#4355) An arpeggio master note shouldn't trigger new notes while it's decaying. #fixes #4342 --- src/core/InstrumentFunctions.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 5cf02c934..b44dbdc90 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -344,7 +344,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) if( _n->origin() == NotePlayHandle::OriginArpeggio || _n->origin() == NotePlayHandle::OriginNoteStacking || !m_arpEnabledModel.value() || - ( _n->isReleased() && _n->releaseFramesDone() >= _n->actualReleaseFramesToDo() ) ) + _n->isReleased() ) { return; } @@ -412,7 +412,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) // Skip notes randomly if( m_arpSkipModel.value() ) { - if( 100 * ( (float) rand() / (float)( RAND_MAX + 1.0f ) ) < m_arpSkipModel.value() ) { // Set master note to prevent the note to extend over skipped notes @@ -501,12 +500,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) continue; } - float vol_level = 1.0f; - if( _n->isReleased() ) - { - vol_level = _n->volumeLevel( cur_frame + gated_frames ); - } - // create new arp-note // create sub-note-play-handle, only ptr to note is different @@ -515,7 +508,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) NotePlayHandleManager::acquire( _n->instrumentTrack(), frames_processed, gated_frames, - Note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, (volume_t) qRound( _n->getVolume() * vol_level ), + Note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, _n->getVolume(), _n->getPanning(), _n->detuning() ), _n, -1, NotePlayHandle::OriginArpeggio ) ); From 0caaebaecbfff360dd4157111b8054f8f80afa3b Mon Sep 17 00:00:00 2001 From: Hussam Eddin Alhomsi Date: Thu, 17 May 2018 20:35:52 +0300 Subject: [PATCH 6/8] Remove FluidSynth requirement for background pic (#4364) --- src/core/ConfigManager.cpp | 2 -- src/gui/SetupDialog.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index 177a90437..f52e10ac7 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -292,9 +292,7 @@ void ConfigManager::setDefaultSoundfont( const QString & _sf ) void ConfigManager::setBackgroundArtwork( const QString & _ba ) { -#ifdef LMMS_HAVE_FLUIDSYNTH m_backgroundArtwork = _ba; -#endif } void ConfigManager::setGIGDir(const QString &gd) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index f88e1dcf6..5063761e2 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -1525,9 +1525,7 @@ void SetupDialog::setDefaultSoundfont( const QString & _sf ) void SetupDialog::setBackgroundArtwork( const QString & _ba ) { -#ifdef LMMS_HAVE_FLUIDSYNTH m_backgroundArtwork = _ba; -#endif } From 68a621cc162b240c2674a80acebbf0058bb23976 Mon Sep 17 00:00:00 2001 From: Joshua Wade Date: Fri, 18 May 2018 13:34:46 -0400 Subject: [PATCH 7/8] Restart flanger LFO on Song::playbackStateChanged signal (#4363) Closes https://github.com/LMMS/lmms/issues/3689 --- plugins/Flanger/FlangerControls.cpp | 7 +++++++ plugins/Flanger/FlangerControls.h | 1 + plugins/Flanger/FlangerEffect.cpp | 11 ++++++++++- plugins/Flanger/FlangerEffect.h | 1 + plugins/Flanger/QuadratureLfo.h | 8 ++++++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/plugins/Flanger/FlangerControls.cpp b/plugins/Flanger/FlangerControls.cpp index 4ba91dba3..fa3640db4 100644 --- a/plugins/Flanger/FlangerControls.cpp +++ b/plugins/Flanger/FlangerControls.cpp @@ -43,6 +43,7 @@ FlangerControls::FlangerControls( FlangerEffect *effect ) : { connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changedSampleRate() ) ); + connect( Engine::getSong(), SIGNAL( playbackStateChanged() ), this, SLOT( changedPlaybackState() ) ); } @@ -81,3 +82,9 @@ void FlangerControls::changedSampleRate() } + + +void FlangerControls::changedPlaybackState() +{ + m_effect->restartLFO(); +} diff --git a/plugins/Flanger/FlangerControls.h b/plugins/Flanger/FlangerControls.h index bbd8444fa..d51141ed0 100644 --- a/plugins/Flanger/FlangerControls.h +++ b/plugins/Flanger/FlangerControls.h @@ -57,6 +57,7 @@ public: private slots: void changedSampleRate(); + void changedPlaybackState(); private: FlangerEffect* m_effect; diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index ab952e5a4..528eacf01 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -68,7 +68,7 @@ FlangerEffect::~FlangerEffect() { delete m_rDelay; } - if(m_lfo ) + if( m_lfo ) { delete m_lfo; } @@ -139,6 +139,15 @@ void FlangerEffect::changeSampleRate() + +void FlangerEffect::restartLFO() +{ + m_lfo->restart(); +} + + + + extern "C" { diff --git a/plugins/Flanger/FlangerEffect.h b/plugins/Flanger/FlangerEffect.h index ad1052b5a..a70e87827 100644 --- a/plugins/Flanger/FlangerEffect.h +++ b/plugins/Flanger/FlangerEffect.h @@ -44,6 +44,7 @@ public: return &m_flangerControls; } void changeSampleRate(); + void restartLFO(); private: FlangerControls m_flangerControls; diff --git a/plugins/Flanger/QuadratureLfo.h b/plugins/Flanger/QuadratureLfo.h index 90f7f77dc..e7e27d14a 100644 --- a/plugins/Flanger/QuadratureLfo.h +++ b/plugins/Flanger/QuadratureLfo.h @@ -53,6 +53,14 @@ public: + inline void restart() + { + m_phase = 0; + } + + + + inline void setSampleRate ( int samplerate ) { m_samplerate = samplerate; From daa3f535158f321e7a01ea531fc3085f2d26ab37 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 23 May 2018 14:59:45 +0900 Subject: [PATCH 8/8] Fix compilation with Qt 5.11 (#4374) Add extends attribute for custom widget RowTableView per upstream uic change http://code.qt.io/cgit/qt/qtbase.git/commit/?id=058474884c2505a8a00d4c59b4922bfcd3597c2f --- src/gui/Forms/EffectSelectDialog.ui | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/Forms/EffectSelectDialog.ui b/src/gui/Forms/EffectSelectDialog.ui index a9c6de019..f8e773486 100644 --- a/src/gui/Forms/EffectSelectDialog.ui +++ b/src/gui/Forms/EffectSelectDialog.ui @@ -102,6 +102,7 @@ RowTableView + QTableView
RowTableView.h