Many delay plugins have ping-pong delay options, so I made the ping-pong delay function. Procedures follow the steps below.
1. Implementing a panning system
const float mono = (inSampleL + inSampleR) * 0.5f;
- First of all, for making typical pinpong delay, you have to mix L, R channel to mono. If you do that, you need to reduce it by half.
- This mono signal should be sent to both L and R channels, each multiplied by its respective panning value.

Considering the human perception of the loudness, there is a specific way to make the panning system.
static constexpr float kQuarterPi = juce::MathConstants<float>::halfPi * 0.5f;
const float x = kQuarterPi * (mWidth + 1.0f);
mPanL = std::cos(x);
mPanR = std::sin(x);
outSampleL = mono * mPanL;
outSampleR = mono * mPanR;
- Multiplying values are derived from the equatrion above.
- Panning is implemented from controlling of the volume of each channel(L, R). So the sum of squares of mPanL and mPanR is always 1.
- mWidth is the parameter that user controlls from UI.
2. Creating the module that implements the cross feedback.
void ModulePingPong::process(const float inFeedbackL, const float inFeedbackR,
float& outSampleL, float& outSampleR,
const bool inPingPong, const float inWidth) noexcept
{
float outPanL = 0.0f;
float outPanR = 0.0f;
mPanning.process(outPanL, outPanR);
outSampleL = outPanL + (inPingPong ? inFeedbackR : inFeedbackL);
outSampleR = outPanR + (inPingPong ? inFeedbackL : inFeedbackR);
}
- outPanL and outPanR is the result from 1(Implementing a panning system).
- inPingPong is a active button whether pingpong is enabled or disabeld.
- So if inPingPong is true, outSampleL became the sum of outPanL and Feedback of R. Else if it isn't true, it added by feedback of L.
Through this recuessive argorithm, It is possible to implement a ping-pong delay that creates the effect of the sound bouncing back and forth between the left and right channels.