From 1ee274ebc9611337fa58ad42f4f8c03e1f398e03 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 3 Dec 2017 11:27:49 +0900 Subject: [PATCH] Fix various bugs when using JACK (#4005) * Fix crash on closing * Fix audio rendering artifacts * Make LMMS work properly after rendering --- include/AudioJack.h | 2 ++ src/core/audio/AudioJack.cpp | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/AudioJack.h b/include/AudioJack.h index 9bbb3bd4880..60adfc9a56d 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -37,6 +37,7 @@ #include #include #include +#include #include "AudioDevice.h" #include "AudioDeviceSetupWidget.h" @@ -107,6 +108,7 @@ private slots: bool m_active; bool m_stopped; + QMutex m_processingMutex; MidiJack *m_midiClient; QVector m_outputPorts; diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index 24f7b2f4fb0..4d730eed412 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -71,6 +71,7 @@ AudioJack::AudioJack( bool & _success_ful, Mixer* _mixer ) : AudioJack::~AudioJack() { + stopProcessing(); #ifdef AUDIO_PORT_SUPPORT while( m_portMap.size() ) { @@ -200,6 +201,7 @@ bool AudioJack::initJackClient() void AudioJack::startProcessing() { + QMutexLocker m( &m_processingMutex ); m_stopped = false; if( m_active || m_client == NULL ) @@ -252,6 +254,8 @@ void AudioJack::startProcessing() void AudioJack::stopProcessing() { + QMutexLocker m( &m_processingMutex ); + m_stopped = true; } @@ -338,6 +342,8 @@ void AudioJack::renamePort( AudioPort * _port ) int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) { + QMutexLocker m( &m_processingMutex ); + // do midi processing first so that midi input can // add to the following sound processing if( m_midiClient && _nframes > 0 ) @@ -397,15 +403,15 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) if( m_framesDoneInCurBuf == m_framesToDoInCurBuf ) { m_framesToDoInCurBuf = getNextBuffer( m_outBuf ); + m_framesDoneInCurBuf = 0; if( !m_framesToDoInCurBuf ) { - m_stopped = true; + break; } - m_framesDoneInCurBuf = 0; } } - if( m_stopped == true ) + if( _nframes != done ) { for( int c = 0; c < channels(); ++c ) {