Added Ping Pong Mode and Mix control to Delay FX

pull/764/head
jnonis 7 months ago
parent 897c35aad0
commit 002c2b985c
  1. 91
      src/effect_delay.cpp
  2. 15
      src/effect_delay.h
  3. 6
      src/uimenu.cpp

@ -1,3 +1,7 @@
/*
* Stereo Delay
* Javier Nonis (https://github.com/jnonis) - 2024
*/
#include <circle/logger.h>
#include "effect_delay.h"
@ -19,7 +23,9 @@ AudioEffectDelay::AudioEffectDelay(float32_t samplerate) : AudioEffect(samplerat
this->timeL = 0.36f;
this->timeR = 0.36f;
this->feedback = 0.5f;
this->feedback = 0.6f;
this->pingPongMode = false;
this->setMix(0.5f);
}
AudioEffectDelay::~AudioEffectDelay()
@ -53,6 +59,12 @@ void AudioEffectDelay::setParameter(unsigned param, unsigned value)
case AudioEffectDelay::Param::TONE:
this->lpf->setParameter(AudioEffectLPF::Param::CUTOFF, value);
break;
case AudioEffectDelay::Param::PING_PONG:
this->pingPongMode = (value == 1);
break;
case AudioEffectDelay::Param::MIX:
this->setMix((float32_t) value / 100.0f);
break;
default:
break;
}
@ -72,35 +84,80 @@ unsigned AudioEffectDelay::getParameter(unsigned param)
return roundf(this->feedback * 100);
case AudioEffectDelay::Param::TONE:
return this->lpf->getParameter(AudioEffectLPF::Param::CUTOFF);
case AudioEffectDelay::Param::PING_PONG:
return this->pingPongMode ? 1 : 0;
case AudioEffectDelay::Param::MIX:
return roundf(this->mix * 100);
default:
return 0;
}
}
void AudioEffectDelay::setMix(float32_t mix)
{
this->mix = mix;
if (this->mix <= 0.5f)
{
this->dryMix = 1.0f;
this->wetMix = this->mix * 2;
}
else
{
this->dryMix = 1.0f - ((this->mix - 0.5f) * 2);
this->wetMix = 1.0f;
}
}
void AudioEffectDelay::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{
for (uint16_t i=0; i < len; i++)
{
// Update buffers
this->bufferL[index] = inblockL[i];
this->bufferR[index] = inblockR[i];
// Calculate offsets
int offsetL = this->index - (this->timeL * this->samplerate);
if (offsetL < 0) {
offsetL = this->bufferSize + offsetL;
}
int offsetR = this->index - (this->timeR * this->samplerate);
if (offsetR < 0) {
offsetR = this->bufferSize + offsetR;
float32_t inL = inblockL[i];
float32_t inR = inblockR[i];
if (this->pingPongMode)
{
// Ping Pong mode only uses timeL
// Calculate offsets
int offsetL = this->index - (this->timeL * this->samplerate);
if (offsetL < 0)
{
offsetL = this->bufferSize + offsetL;
}
// We need to feed the buffers each other
this->bufferL[index] = this->lpf->processSampleR(this->bufferR[offsetL]) * this->feedback;
this->bufferR[index] = this->lpf->processSampleL(this->bufferL[offsetL]) * this->feedback;
outblockL[i] = (inL * this->dryMix) + (this->bufferL[index] * this->wetMix);
outblockR[i] = (inR * this->dryMix) + (this->bufferR[index] * this->wetMix);
// Update buffers
this->bufferL[index] += (inL + inR) * 0.5f;
}
else
{
// Calculate offsets
int offsetL = this->index - (this->timeL * this->samplerate);
if (offsetL < 0)
{
offsetL = this->bufferSize + offsetL;
}
int offsetR = this->index - (this->timeR * this->samplerate);
if (offsetR < 0)
{
offsetR = this->bufferSize + offsetR;
}
this->bufferL[index] += this->lpf->processSampleL(this->bufferL[offsetL]) * this->feedback;
this->bufferR[index] += this->lpf->processSampleR(this->bufferR[offsetR]) * this->feedback;
this->bufferL[index] = this->lpf->processSampleL(this->bufferL[offsetL]) * this->feedback;
this->bufferR[index] = this->lpf->processSampleR(this->bufferR[offsetR]) * this->feedback;
outblockL[i] = this->bufferL[index];
outblockR[i] = this->bufferR[index];
outblockL[i] = (inL * this->dryMix) + (this->bufferL[index] * this->wetMix);
outblockR[i] = (inR * this->dryMix) + (this->bufferR[index] * this->wetMix);
// Update buffers
this->bufferL[index] += inL;
this->bufferR[index] += inR;
}
// Update index
this->index++;

@ -1,3 +1,10 @@
/*
* Stereo Delay
* Features:
* - Tone control using Low Pass Filter
* - Ping Pong mode.
* Javier Nonis (https://github.com/jnonis) - 2024
*/
#ifndef _EFFECT_DELAY_H
#define _EFFECT_DELAY_H
@ -16,6 +23,8 @@ public:
TIME_R,
FEEDBACK,
TONE,
PING_PONG,
MIX,
UNKNOWN
};
@ -41,6 +50,12 @@ private:
float32_t timeR; // Right delay time in seconds (0.0 - 2.0)
float32_t feedback; // Feedback (0.0 - 1.0)
AudioEffectLPF* lpf;
bool pingPongMode;
float32_t mix;
float32_t dryMix;
float32_t wetMix;
void setMix(float32_t mix);
};
#endif // _EFFECT_DELAY_H

@ -167,6 +167,8 @@ const CUIMenu::TMenuItem CUIMenu::s_FXDelay[] =
{"Time R", EditTGFXParameter, 0, AudioEffectDelay::Param::TIME_R},
{"Feedback", EditTGFXParameter, 0, AudioEffectDelay::Param::FEEDBACK},
{"Tone", EditTGFXParameter, 0, AudioEffectDelay::Param::TONE},
{"Ping Pong", EditTGFXParameter, 0, AudioEffectDelay::Param::PING_PONG},
{"Mix", EditTGFXParameter, 0, AudioEffectDelay::Param::MIX},
{0}
};
@ -349,7 +351,9 @@ const CUIMenu::TParameter CUIMenu::s_TGFXDelayParam[AudioEffectDelay::Param::UNK
{0, AudioEffectDelay::MAX_DELAY_TIME * 1000, 1}, // TIME_L
{0, AudioEffectDelay::MAX_DELAY_TIME * 1000, 1}, // TIME_R
{0, 100, 1}, // FEEDBACK,
{0, 100, 1} // TONE
{0, 100, 1}, // TONE
{0, 1, 1, ToOnOff}, // PING_PONG
{0, 100, 1} // MIX
};
// must match AudioEffectLPF::Param

Loading…
Cancel
Save