From f01c90b6a505905737a8f7026daf289949537231 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 6 Feb 2014 22:20:23 +0100 Subject: [PATCH] EffectChain: new argument hasInputNoise for processAudioBuffer() Use the extra information to determine whether we need to process input at all if plugin is not running anymore. In FX mixer we now omit starting effects if no data has been mixed to a certain FX channel. Instead let effects running until they finished. First of multiple fixes for #267. --- include/EffectChain.h | 4 ++-- src/core/EffectChain.cpp | 13 +++++++++---- src/core/FxMixer.cpp | 15 ++++++++++----- src/core/audio/AudioPort.cpp | 4 ++-- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/EffectChain.h b/include/EffectChain.h index b09863896..620caa427 100644 --- a/include/EffectChain.h +++ b/include/EffectChain.h @@ -2,7 +2,7 @@ * EffectChain.h - class for processing and effects chain * * Copyright (c) 2006-2008 Danny McRae - * Copyright (c) 2008-2009 Tobias Doerffel + * Copyright (c) 2008-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -53,7 +53,7 @@ public: void removeEffect( Effect * _effect ); void moveDown( Effect * _effect ); void moveUp( Effect * _effect ); - bool processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ); + bool processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise ); void startRunning(); bool isRunning(); diff --git a/src/core/EffectChain.cpp b/src/core/EffectChain.cpp index e38c946fe..83268950e 100644 --- a/src/core/EffectChain.cpp +++ b/src/core/EffectChain.cpp @@ -184,17 +184,21 @@ void EffectChain::moveUp( Effect * _effect ) -bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) +bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise ) { if( m_enabledModel.value() == false ) { return false; } + bool moreEffects = false; - for( EffectList::Iterator it = m_effects.begin(); - it != m_effects.end(); ++it ) + for( EffectList::Iterator it = m_effects.begin(); it != m_effects.end(); ++it ) { - moreEffects |= ( *it )->processAudioBuffer( _buf, _frames ); + if( hasInputNoise || ( *it )->isRunning() ) + { + moreEffects |= ( *it )->processAudioBuffer( _buf, _frames ); + } + #ifdef LMMS_DEBUG for( int f = 0; f < _frames; ++f ) { @@ -209,6 +213,7 @@ bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) } #endif } + return moreEffects; } diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index a87a23392..ab294c747 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -1,10 +1,8 @@ -#ifndef SINGLE_SOURCE_COMPILE - /* * FxMixer.cpp - effect mixer for LMMS * * Copyright (c) 2008-2011 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -118,8 +116,15 @@ void FxMixer::processChannel( fx_ch_t _ch, sampleFrame * _buf ) const fpp_t f = engine::mixer()->framesPerPeriod(); if( !engine::getSong()->isFreezingPattern() ) { - m_fxChannels[_ch]->m_fxChain.startRunning(); - m_fxChannels[_ch]->m_stillRunning = m_fxChannels[_ch]->m_fxChain.processAudioBuffer( _buf, f ); + // only start effects if sound was mixed to this FX channel before + if( m_fxChannels[_ch]->m_used ) + { + m_fxChannels[_ch]->m_fxChain.startRunning(); + } + + // process FX chain + m_fxChannels[_ch]->m_stillRunning = m_fxChannels[_ch]->m_fxChain.processAudioBuffer( _buf, f, m_fxChannels[_ch]->m_used ); + float peakLeft = engine::mixer()->peakValueLeft( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value(); float peakRight = engine::mixer()->peakValueRight( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value(); diff --git a/src/core/audio/AudioPort.cpp b/src/core/audio/AudioPort.cpp index b8f909b40..cdcf675b7 100644 --- a/src/core/audio/AudioPort.cpp +++ b/src/core/audio/AudioPort.cpp @@ -109,8 +109,8 @@ bool AudioPort::processEffects() if( m_effects ) { lockFirstBuffer(); - bool more = m_effects->processAudioBuffer( m_firstBuffer, - engine::mixer()->framesPerPeriod() ); + bool hasInputNoise = m_bufferUsage != NoUsage; + bool more = m_effects->processAudioBuffer( m_firstBuffer, engine::mixer()->framesPerPeriod(), hasInputNoise ); unlockFirstBuffer(); return more; }