diff --git a/src/engine/enginefilterpansingle.h b/src/engine/enginefilterpansingle.h index 8e4d34a43d13..0e72d7a8341e 100644 --- a/src/engine/enginefilterpansingle.h +++ b/src/engine/enginefilterpansingle.h @@ -1,3 +1,10 @@ +/** + * FilterPan Single : + * + This delay will be applied on left channel following the + * leftDelayFrames parameter and on the right one by minus leftDelayFrames. + * + This delay is applied sample by sample and not on the full buffer. + */ + #ifndef ENGINEFILTERPANSINGLE_H #define ENGINEFILTERPANSINGLE_H @@ -31,6 +38,7 @@ class EngineFilterPanSingle { virtual void process(const CSAMPLE* pIn, CSAMPLE* pOutput, double leftDelayFrames) { double delayLeftSourceFrame; double delayRightSourceFrame; + if (leftDelayFrames > 0) { delayLeftSourceFrame = m_delayFrame + SIZE - leftDelayFrames; delayRightSourceFrame = m_delayFrame + SIZE; @@ -39,18 +47,23 @@ class EngineFilterPanSingle { delayRightSourceFrame = m_delayFrame + SIZE + leftDelayFrames; } - // put in samples into delay buffer: + // put in samples into delay buffer m_buf[m_delayFrame * 2] = pIn[0]; m_buf[m_delayFrame * 2 + 1] = pIn[1]; + // move the delay cursor forward m_delayFrame = (m_delayFrame + 1) % SIZE; - - double modLeft = fmod(delayLeftSourceFrame, 1); - double modRight = fmod(delayRightSourceFrame, 1); - - pOutput[0] = m_buf[(static_cast(floor(delayLeftSourceFrame)) % SIZE) * 2] * (1 - modLeft); - pOutput[1] = m_buf[(static_cast(floor(delayRightSourceFrame)) % SIZE) * 2 + 1] * (1 - modRight); - pOutput[0] += m_buf[(static_cast(ceil(delayLeftSourceFrame)) % SIZE) * 2] * modLeft; - pOutput[1] += m_buf[(static_cast(ceil(delayRightSourceFrame)) % SIZE) * 2 + 1] * modRight; + + // prepare coefficients for linear interpolation using a linear stretching + double timeBetweenFullSamplesLeft = fmod(delayLeftSourceFrame, 1); + double timeBetweenFullSamplesRight = fmod(delayRightSourceFrame, 1); + + // applying the delay on left channel with linear interpolation between each sample + pOutput[0] = m_buf[(static_cast(floor(delayLeftSourceFrame)) % SIZE) * 2] * (1 - timeBetweenFullSamplesLeft); + pOutput[0] += m_buf[(static_cast(ceil(delayLeftSourceFrame)) % SIZE) * 2] * timeBetweenFullSamplesLeft; + // then on right channel + pOutput[1] = m_buf[(static_cast(floor(delayRightSourceFrame)) % SIZE) * 2 + 1] * (1 - timeBetweenFullSamplesRight); + pOutput[1] += m_buf[(static_cast(ceil(delayRightSourceFrame)) % SIZE) * 2 + 1] * timeBetweenFullSamplesRight; + m_doStart = false; }