Adapted Plate Reverb as AudioEffect

pull/764/head
jnonis 7 months ago
parent 751b69da3f
commit fc6f7152f0
  1. 1
      src/effect_base.h
  2. 95
      src/effect_platervbstereo.cpp
  3. 65
      src/effect_platervbstereo.h
  4. 4
      src/effects.h
  5. 2
      src/minidexed.cpp
  6. 53
      src/uimenu.cpp
  7. 3
      src/uimenu.h

@ -15,6 +15,7 @@
#define EFFECT_DS1 4
#define EFFECT_BIGMUFF 5
#define EFFECT_TALREVERB3 6
#define EFFECT_REVERB 7
class AudioEffect
{

@ -83,7 +83,7 @@ const int16_t AudioWaveformSine[257] = {
-4808, -4011, -3212, -2410, -1608, -804, 0
};
AudioEffectPlateReverb::AudioEffectPlateReverb(float32_t samplerate)
AudioEffectPlateReverb::AudioEffectPlateReverb(float32_t samplerate) : AudioEffect(samplerate)
{
input_attn = 0.5f;
in_allp_k = INP_ALLP_COEFF;
@ -154,6 +154,87 @@ AudioEffectPlateReverb::AudioEffectPlateReverb(float32_t samplerate)
lfo2_adder = (UINT32_MAX + 1)/(samplerate * LFO2_FREQ_HZ);
reverb_level = 0.0f;
this->setParameter(AudioEffectPlateReverb::Param::SIZE, 70);
this->setParameter(AudioEffectPlateReverb::Param::HIGH_DAMP, 50);
this->setParameter(AudioEffectPlateReverb::Param::LOW_DAMP, 50);
this->setParameter(AudioEffectPlateReverb::Param::LOW_PASS, 30);
this->setParameter(AudioEffectPlateReverb::Param::DIFFUSION, 65);
this->setParameter(AudioEffectPlateReverb::Param::MIX, 50);
this->setParameter(AudioEffectPlateReverb::Param::LEVEL, 99);
}
void AudioEffectPlateReverb::initializeSendFX()
{
this->setParameter(AudioEffectPlateReverb::Param::MIX, 100);
}
void AudioEffectPlateReverb::setParameter(unsigned param, unsigned value)
{
switch (param)
{
case AudioEffectPlateReverb::Param::BYPASS:
this->setBypass(value == 1);
break;
case AudioEffectPlateReverb::Param::SIZE:
this->sizeValue = value;
this->size((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::HIGH_DAMP:
this->hidampValue = value;
this->hidamp((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::LOW_DAMP:
this->lodampValue = value;
this->lodamp((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::LOW_PASS:
this->lowpassValue = value;
this->lowpass((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::DIFFUSION:
this->diffusionValue = value;
this->diffusion((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::MIX:
this->setMix((float32_t) value / 100.0f);
break;
case AudioEffectPlateReverb::Param::LEVEL:
this->level((float32_t) value / 100.0f);
break;
default:
break;
}
}
unsigned AudioEffectPlateReverb::getParameter(unsigned param)
{
switch (param)
{
case AudioEffectPlateReverb::Param::BYPASS:
return this->getBypass() ? 1 : 0;
case AudioEffectPlateReverb::Param::SIZE:
return this->sizeValue;
case AudioEffectPlateReverb::Param::HIGH_DAMP:
return this->hidampValue;
case AudioEffectPlateReverb::Param::LOW_DAMP:
return this->lodampValue;
case AudioEffectPlateReverb::Param::LOW_PASS:
return this->lowpassValue;
case AudioEffectPlateReverb::Param::DIFFUSION:
return this->diffusionValue;
case AudioEffectPlateReverb::Param::MIX:
return roundf(this->mix * 100);
case AudioEffectPlateReverb::Param::LEVEL:
return roundf(this->reverb_level * 100);
default:
return 0;
}
}
void AudioEffectPlateReverb::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{
this->doReverb(inblockL, inblockR, outblockL, outblockR, len);
}
// #define sat16(n, rshift) signed_saturate_rshift((n), 16, (rshift))
@ -235,7 +316,7 @@ void AudioEffectPlateReverb::doReverb(const float32_t* inblockL, const float32_t
y += (int64_t)y1 * idx;
lfo2_out_cos = (int32_t) (y >> (32-8)); // 16bit output
input = inblockL[i] * input_attn;
input = inblockL[i] * input_attn;
// chained input allpasses, channel L
acc = in_allp1_bufL[in_allp1_idxL] + input * in_allp_k;
@ -405,10 +486,10 @@ void AudioEffectPlateReverb::doReverb(const float32_t* inblockL, const float32_t
temp1 = acc - master_lowpass_l;
master_lowpass_l += temp1 * master_lowpass_f;
rvbblockL[i] = master_lowpass_l;
rvbblockL[i] = inblockL[i] * dryMix + master_lowpass_l * wetMix;
// Channel R
#ifdef TAP1_MODULATED
#ifdef TAP1_MODULATED
temp16 = (lp_dly1_idx + lp_dly1_offset_R + (lfo2_out_cos>>LFO_FRAC_BITS)) % (sizeof(lp_dly1_buf)/sizeof(float32_t));
temp1 = lp_dly1_buf[temp16++]; // sample now
if (temp16 >= sizeof(lp_dly1_buf)/sizeof(float32_t)) temp16 = 0;
@ -416,10 +497,10 @@ void AudioEffectPlateReverb::doReverb(const float32_t* inblockL, const float32_t
input = (float32_t)(lfo2_out_cos & LFO_FRAC_MASK) / ((float32_t)LFO_FRAC_MASK); // interp. k
acc = (temp1*(1.0f-input) + temp2*input)* 0.8f;
#else
#else
temp16 = (lp_dly1_idx + lp_dly1_offset_R) % (sizeof(lp_dly1_buf)/sizeof(float32_t));
acc = lp_dly1_buf[temp16] * 0.8f;
#endif
#endif
#ifdef TAP2_MODULATED
temp16 = (lp_dly2_idx + lp_dly2_offset_R + (lfo1_out_cos>>LFO_FRAC_BITS)) % (sizeof(lp_dly2_buf)/sizeof(float32_t));
temp1 = lp_dly2_buf[temp16++];
@ -449,6 +530,6 @@ void AudioEffectPlateReverb::doReverb(const float32_t* inblockL, const float32_t
temp1 = acc - master_lowpass_r;
master_lowpass_r += temp1 * master_lowpass_f;
rvbblockR[i] = master_lowpass_r;
rvbblockR[i] = inblockR[i] * dryMix + master_lowpass_r * wetMix;
}
}

@ -47,6 +47,7 @@
#include <stdint.h>
#include <arm_math.h>
#include "common.h"
#include "effect_base.h"
/***
* Loop delay modulation: comment/uncomment to switch sin/cos
@ -56,10 +57,35 @@
//#define TAP1_MODULATED
#define TAP2_MODULATED
class AudioEffectPlateReverb
class AudioEffectPlateReverb : public AudioEffect
{
public:
enum Param
{
BYPASS,
SIZE,
HIGH_DAMP,
LOW_DAMP,
LOW_PASS,
DIFFUSION,
MIX,
LEVEL,
UNKNOWN
};
AudioEffectPlateReverb(float32_t samplerate);
//virtual ~AudioEffectPlateReverb();
virtual unsigned getId()
{
return EFFECT_REVERB;
}
virtual void initializeSendFX();
virtual void setParameter(unsigned param, unsigned value);
virtual unsigned getParameter(unsigned param);
void doReverb(const float32_t* inblockL, const float32_t* inblockR, float32_t* rvbblockL, float32_t* rvbblockR,uint16_t len);
void size(float n)
@ -105,13 +131,42 @@ public:
}
float32_t get_size(void) {return rv_time_k;}
bool get_bypass(void) {return bypass;}
void set_bypass(bool state) {bypass = state;};
void tgl_bypass(void) {bypass ^=1;}
float32_t get_level(void) {return reverb_level;}
protected:
virtual size_t getParametersSize()
{
return sizeof(AudioEffectPlateReverb::Param);
}
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len);
private:
bool bypass = false;
float32_t reverb_level;
unsigned sizeValue;
unsigned hidampValue;
unsigned lodampValue;
unsigned lowpassValue;
unsigned diffusionValue;
float32_t mix;
float32_t dryMix;
float32_t wetMix;
void 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;
}
}
float32_t input_attn;
float32_t in_allp_k; // input allpass coeff

@ -13,6 +13,7 @@
#include "effect_ds1.h"
#include "effect_bigmuff.h"
#include "effect_talreverb3.h"
#include "effect_platervbstereo.h"
inline AudioEffect* newAudioEffect(unsigned type, float32_t samplerate)
{
@ -30,6 +31,8 @@ inline AudioEffect* newAudioEffect(unsigned type, float32_t samplerate)
return new AudioEffectBigMuff(samplerate);
case EFFECT_TALREVERB3:
return new AudioEffectTalReverb3(samplerate);
case EFFECT_REVERB:
return new AudioEffectPlateReverb(samplerate);
case EFFECT_NONE:
default:
return new AudioEffectNone(samplerate);
@ -46,6 +49,7 @@ inline std::string getFXTypeName(int nValue)
case EFFECT_DS1: return "DS1";
case EFFECT_BIGMUFF: return "Big Muff";
case EFFECT_TALREVERB3: return "TalRvrb3";
case EFFECT_REVERB: return "Reverb";
case EFFECT_NONE:
default: return "None";
}

@ -850,7 +850,7 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
case ParameterReverbEnable:
nValue=constrain((int)nValue,0,1);
m_ReverbSpinLock.Acquire ();
reverb->set_bypass (!nValue);
reverb->setBypass (!nValue);
m_ReverbSpinLock.Release ();
break;

@ -221,6 +221,19 @@ CUIMenu::TMenuItem CUIMenu::s_FXTalReverb3[] =
{0}
};
CUIMenu::TMenuItem CUIMenu::s_FXReverb[] =
{
{"Bypass", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::BYPASS},
{"Size", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::SIZE},
{"High damp", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::HIGH_DAMP},
{"Low damp", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::LOW_DAMP},
{"Low pass", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::LOW_PASS},
{"Diffusion", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::DIFFUSION},
{"Mix", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::MIX},
{"Level", EditTGFXParameter, 0, AudioEffectPlateReverb::Param::LEVEL},
{0}
};
// inserting menu items before "OP1" affect OPShortcutHandler()
const CUIMenu::TMenuItem CUIMenu::s_EditVoiceMenu[] =
{
@ -292,7 +305,7 @@ const CUIMenu::TMenuItem CUIMenu::s_SaveMenu[] =
const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknown] =
{
{0, 1, 1, ToOnOff}, // ParameterCompessorEnable
{0, 6, 1, ToFXType}, // ParameterSendFXType
{0, 7, 1, ToFXType}, // ParameterSendFXType
{0, 1, 1, ToOnOff}, // ParameterReverbEnable
{0, 99, 1}, // ParameterReverbSize
{0, 99, 1}, // ParameterReverbHighDamp
@ -313,7 +326,7 @@ const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown]
{0, CSysExFileLoader::VoicesPerBank-1, 1}, // TGParameterProgram
{0, 127, 8, ToVolume}, // TGParameterVolume
{0, 127, 8, ToPan}, // TGParameterPan
{0, 6, 1, ToFXType}, // TGParameterInsertFXType
{0, 7, 1, ToFXType}, // TGParameterInsertFXType
{-99, 99, 1}, // TGParameterMasterTune
{0, 99, 1}, // TGParameterCutoff
{0, 99, 1}, // TGParameterResonance
@ -362,7 +375,7 @@ const CUIMenu::TParameter CUIMenu::s_TGFXDelayParam[AudioEffectDelay::Param::UNK
{0, 100, 1}, // FEEDBACK,
{0, 100, 1}, // TONE
{0, 1, 1, ToOnOff}, // PING_PONG
{0, 100, 1} // MIX
{0, 100, 1, ToMix} // MIX
};
// must match AudioEffectLPF::Param
@ -382,7 +395,7 @@ const CUIMenu::TParameter CUIMenu::s_TGFXDS1Param[AudioEffectDS1::Param::UNKNOWN
{1, 99, 1} // LEVEL
};
// must match AudioEffectDS1::Param
// must match AudioEffectBigMuff::Param
const CUIMenu::TParameter CUIMenu::s_TGFXBigMuffParam[AudioEffectBigMuff::Param::UNKNOWN] =
{
{0, 1, 1, ToOnOff}, // BYPASS
@ -406,6 +419,19 @@ const CUIMenu::TParameter CUIMenu::s_TGFXTalReverb3Param[AudioEffectTalReverb3::
{0, 1, 1, ToOnOff} // POWER
};
// must match AudioEffectPlateReverb::Param
const CUIMenu::TParameter CUIMenu::s_TGFXReverbParam[AudioEffectPlateReverb::Param::UNKNOWN] =
{
{0, 1, 1, ToOnOff}, // BYPASS
{0, 99, 1}, // SIZE
{0, 99, 1}, // HIGH_DAMP
{0, 99, 1}, // LOW_DAMP
{0, 99, 1}, // LOW_PASS
{0, 99, 1}, // DIFFUSION
{0, 100, 1, ToMix}, // MIX
{0, 99, 1}, // LEVEL
};
// must match DexedVoiceParameters in Synth_Dexed
const CUIMenu::TParameter CUIMenu::s_VoiceParameter[] =
{
@ -1731,6 +1757,19 @@ string CUIMenu::ToFXType (int nValue)
return getFXTypeName(nValue);
}
string CUIMenu::ToMix (int nValue)
{
switch (nValue)
{
case 0:
return "Dry";
case 100:
return "Wet";
default:
return to_string (nValue);
}
}
void CUIMenu::TGShortcutHandler (TMenuEvent Event)
{
assert (m_nCurrentMenuDepth >= 2);
@ -2455,6 +2494,9 @@ CUIMenu::TMenuItem* CUIMenu::getFXMenuItem(unsigned type)
case EFFECT_TALREVERB3:
menu = s_FXTalReverb3;
break;
case EFFECT_REVERB:
menu = s_FXReverb;
break;
case EFFECT_NONE:
default:
menu = s_FXNone;
@ -2510,6 +2552,9 @@ CUIMenu::TParameter CUIMenu::getFXParameter(unsigned type, unsigned nParam)
case EFFECT_TALREVERB3:
pParam = s_TGFXTalReverb3Param[nParam];
break;
case EFFECT_REVERB:
pParam = s_TGFXReverbParam[nParam];
break;
default:
break;
}

@ -127,6 +127,7 @@ private:
static std::string ToPortaGlissando (int nValue);
static std::string ToPolyMono (int nValue);
static std::string ToFXType (int nValue);
static std::string ToMix (int nValue);
void TGShortcutHandler (TMenuEvent Event);
void OPShortcutHandler (TMenuEvent Event);
@ -171,6 +172,7 @@ private:
static TMenuItem s_FXDS1[];
static TMenuItem s_FXBigMuff[];
static TMenuItem s_FXTalReverb3[];
static TMenuItem s_FXReverb[];
static const TMenuItem s_EditVoiceMenu[];
static const TMenuItem s_OperatorMenu[];
@ -190,6 +192,7 @@ private:
static const TParameter s_TGFXDS1Param[];
static const TParameter s_TGFXBigMuffParam[];
static const TParameter s_TGFXTalReverb3Param[];
static const TParameter s_TGFXReverbParam[];
static const TParameter s_VoiceParameter[];
static const TParameter s_OPParameter[];

Loading…
Cancel
Save