diff --git a/include/MixHelpers.h b/include/MixHelpers.h index 9b953ffc7..376b0bd61 100644 --- a/include/MixHelpers.h +++ b/include/MixHelpers.h @@ -49,6 +49,12 @@ void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuff /*! \brief Same as addMultiplied, but sanitize output (strip out infs/nans) */ void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); +/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */ +void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ); + +/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */ +void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ); + /*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */ void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ); diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index fcd1cc959..f599ae521 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -119,6 +119,7 @@ void FxChannel::unmuteForSolo() void FxChannel::doProcessing() { const fpp_t fpp = engine::mixer()->framesPerPeriod(); + const bool exporting = engine::getSong()->isExporting(); if( m_muted == false ) { @@ -141,21 +142,25 @@ void FxChannel::doProcessing() if( ! volBuf && ! sendBuf ) // neither volume nor send has sample-exact data... { const float v = sender->m_volumeModel.value() * sendModel->value(); - MixHelpers::addMultiplied( m_buffer, ch_buf, v, fpp ); + if( exporting ) { MixHelpers::addSanitizedMultiplied( m_buffer, ch_buf, v, fpp ); } + else { MixHelpers::addMultiplied( m_buffer, ch_buf, v, fpp ); } } else if( volBuf && sendBuf ) // both volume and send have sample-exact data { - MixHelpers::addMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp ); + if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp ); } + else { MixHelpers::addMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp ); } } else if( volBuf ) // volume has sample-exact data but send does not { const float v = sendModel->value(); - MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp ); + if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp ); } + else { MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp ); } } else // vice versa { const float v = sender->m_volumeModel.value(); - MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp ); + if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp ); } + else { MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp ); } } m_hasInput = true; } diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 154ec6024..da5f34c55 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -124,11 +124,34 @@ void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuff } +void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames ) +{ + for( int f = 0; f < frames; ++f ) + { + dst[f][0] += ( isinff( src[f][0] ) || isnanf( src[f][0] ) ) ? 0.0f : src[f][0] * coeffSrc * coeffSrcBuf->values()[f]; + dst[f][1] += ( isinff( src[f][1] ) || isnanf( src[f][1] ) ) ? 0.0f : src[f][1] * coeffSrc * coeffSrcBuf->values()[f]; + } +} + +void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames ) +{ + for( int f = 0; f < frames; ++f ) + { + dst[f][0] += ( isinff( src[f][0] ) || isnanf( src[f][0] ) ) + ? 0.0f + : src[f][0] * coeffSrcBuf1->values()[f] * coeffSrcBuf2->values()[f]; + dst[f][1] += ( isinff( src[f][1] ) || isnanf( src[f][1] ) ) + ? 0.0f + : src[f][1] * coeffSrcBuf1->values()[f] * coeffSrcBuf2->values()[f]; + } + +} + struct AddSanitizedMultipliedOp { AddSanitizedMultipliedOp( float coeff ) : m_coeff( coeff ) { } - + void operator()( sampleFrame& dst, const sampleFrame& src ) const { dst[0] += ( isinff( src[0] ) || isnanf( src[0] ) ) ? 0.0f : src[0] * m_coeff;