InstrumentTrack: skip processing for IPH-driven instruments when silent
InstrumentPlayHandle-driven instruments (i.e. instruments producing only one sound stream for all notes) are running all the time even if no notes are running. The plugin itself usually does not consume much CPU time while silent but all effects afterwards inside LMMS unneccessarily consume lots of CPU time for processing silent buffer. Typical case: a song with lots of instruments like ZynAddSubFX. With this change, all processing is skipped on silent buffers which notably decreases CPU load for many projects. All effects in following effect chains continue to run until they're silent as well. Closes #267.
This commit is contained in:
@@ -65,6 +65,7 @@
|
||||
#include "MainWindow.h"
|
||||
#include "MidiClient.h"
|
||||
#include "MidiPortMenu.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "DataFile.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "pattern.h"
|
||||
@@ -150,16 +151,24 @@ InstrumentTrack::~InstrumentTrack()
|
||||
|
||||
|
||||
|
||||
void InstrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames,
|
||||
NotePlayHandle * _n )
|
||||
void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, NotePlayHandle* n )
|
||||
{
|
||||
// we must not play the sound if this InstrumentTrack is muted...
|
||||
if( isMuted() || ( _n && _n->isBbTrackMuted() ) )
|
||||
if( isMuted() || ( n && n->isBbTrackMuted() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Test for silent input data if instrument provides a single stream only (i.e. driven by InstrumentPlayHandle)
|
||||
// We could do that in all other cases as well but the overhead for silence test is bigger than
|
||||
// what we potentially save. While playing a note, a NotePlayHandle-driven instrument will produce sound in
|
||||
// 99 of 100 cases so that test would be a waste of time.
|
||||
if( n == NULL && MixHelpers::isSilent( buf, frames ) )
|
||||
{
|
||||
// skip further processing
|
||||
return;
|
||||
}
|
||||
|
||||
// if effects "went to sleep" because there was no input, wake them up
|
||||
// now
|
||||
m_audioPort.effects()->startRunning();
|
||||
@@ -167,17 +176,16 @@ void InstrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
float v_scale = (float) getVolume() / DefaultVolume;
|
||||
|
||||
// instruments using instrument-play-handles will call this method
|
||||
// without any knowledge about notes, so they pass NULL for _n, which
|
||||
// without any knowledge about notes, so they pass NULL for n, which
|
||||
// is no problem for us since we just bypass the envelopes+LFOs
|
||||
if( _n != NULL )
|
||||
if( n )
|
||||
{
|
||||
m_soundShaping.processAudioBuffer( _buf, _frames, _n );
|
||||
v_scale *= ( (float) _n->getVolume() / DefaultVolume );
|
||||
m_soundShaping.processAudioBuffer( buf, frames, n );
|
||||
v_scale *= ( (float) n->getVolume() / DefaultVolume );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( getVolume() < DefaultVolume &&
|
||||
m_instrument->isMidiBased() )
|
||||
if( getVolume() < DefaultVolume && m_instrument->isMidiBased() )
|
||||
{
|
||||
v_scale = 1;
|
||||
}
|
||||
@@ -185,18 +193,20 @@ void InstrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
|
||||
m_audioPort.setNextFxChannel( m_effectChannelModel.value() );
|
||||
|
||||
int framesToMix = frames;
|
||||
int offset = 0;
|
||||
int panning = m_panningModel.value();
|
||||
if( _n != NULL )
|
||||
|
||||
if( n )
|
||||
{
|
||||
panning += _n->getPanning();
|
||||
framesToMix = qMin<f_cnt_t>( n->framesLeftForCurrentPeriod(), framesToMix );
|
||||
offset = n->offset();
|
||||
|
||||
panning += n->getPanning();
|
||||
panning = tLimit<int>( panning, PanningLeft, PanningRight );
|
||||
}
|
||||
engine::mixer()->bufferToPort( _buf, ( _n != NULL ) ?
|
||||
qMin<f_cnt_t>(_n->framesLeftForCurrentPeriod(), _frames ) :
|
||||
_frames,
|
||||
( _n != NULL ) ? _n->offset() : 0,
|
||||
panningToVolumeVector( panning, v_scale ),
|
||||
&m_audioPort );
|
||||
|
||||
engine::mixer()->bufferToPort( buf, framesToMix, offset, panningToVolumeVector( panning, v_scale ), &m_audioPort );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user