mirror of
https://github.com/AxioDL/amuse.git
synced 2025-07-07 05:35:57 +00:00
155 lines
5.3 KiB
C++
155 lines
5.3 KiB
C++
#ifndef __AMUSE_EFFECTREVERB_HPP__
|
|
#define __AMUSE_EFFECTREVERB_HPP__
|
|
|
|
#include "EffectBase.hpp"
|
|
#include "amuse/Common.hpp"
|
|
#include <memory>
|
|
|
|
namespace amuse
|
|
{
|
|
|
|
/** Delay state for one 'tap' of the reverb effect */
|
|
struct ReverbDelayLine
|
|
{
|
|
int32_t x0_inPoint = 0;
|
|
int32_t x4_outPoint = 0;
|
|
int32_t x8_length = 0;
|
|
std::unique_ptr<float[]> xc_inputs;
|
|
float x10_lastInput = 0.f;
|
|
|
|
void allocate(int32_t delay);
|
|
void setdelay(int32_t delay);
|
|
};
|
|
|
|
template <typename T>
|
|
class EffectReverbStdImp;
|
|
|
|
template <typename T>
|
|
class EffectReverbHiImp;
|
|
|
|
/** Reverb effect with configurable reflection filtering */
|
|
class EffectReverb
|
|
{
|
|
protected:
|
|
float x140_x1c8_coloration; /**< [0.0, 1.0] influences filter coefficients to define surface characteristics of a room */
|
|
float x144_x1cc_mix; /**< [0.0, 1.0] dry/wet mix factor of reverb effect */
|
|
float x148_x1d0_time; /**< [0.01, 10.0] time in seconds for reflection decay */
|
|
float x14c_x1d4_damping; /**< [0.0, 1.0] damping factor influencing low-pass filter of reflections */
|
|
float x150_x1d8_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
|
bool m_dirty = true; /**< needs update of internal parameter data */
|
|
|
|
template <typename T>
|
|
friend class EffectReverbStdImp;
|
|
template <typename T>
|
|
friend class EffectReverbHiImp;
|
|
EffectReverb(float coloration, float mix, float time,
|
|
float damping, float preDelay);
|
|
public:
|
|
template <typename T>
|
|
using ImpType = EffectReverbStdImp<T>;
|
|
|
|
void setColoration(float coloration)
|
|
{
|
|
x140_x1c8_coloration = clamp(0.f, coloration, 1.f);
|
|
m_dirty = true;
|
|
}
|
|
|
|
void setMix(float mix)
|
|
{
|
|
x144_x1cc_mix = clamp(0.f, mix, 1.f);
|
|
m_dirty = true;
|
|
}
|
|
|
|
void setTime(float time)
|
|
{
|
|
x148_x1d0_time = clamp(0.01f, time, 10.f);
|
|
m_dirty = true;
|
|
}
|
|
|
|
void setDamping(float damping)
|
|
{
|
|
x14c_x1d4_damping = clamp(0.f, damping, 1.f);
|
|
m_dirty = true;
|
|
}
|
|
|
|
void setPreDelay(float preDelay)
|
|
{
|
|
x150_x1d8_preDelay = clamp(0.f, preDelay, 0.1f);
|
|
m_dirty = true;
|
|
}
|
|
};
|
|
|
|
/** Reverb effect with configurable reflection filtering, adds per-channel low-pass and crosstalk */
|
|
class EffectReverbHi : public EffectReverb
|
|
{
|
|
float x1dc_crosstalk; /**< [0.0, 1.0] factor defining how much reflections are allowed to bleed to other channels */
|
|
|
|
template <typename T>
|
|
friend class EffectReverbHiImp;
|
|
EffectReverbHi(float coloration, float mix, float time,
|
|
float damping, float preDelay, float crosstalk);
|
|
public:
|
|
template <typename T>
|
|
using ImpType = EffectReverbHiImp<T>;
|
|
|
|
void setCrosstalk(float crosstalk)
|
|
{
|
|
x1dc_crosstalk = clamp(0.f, crosstalk, 1.f);
|
|
m_dirty = true;
|
|
}
|
|
};
|
|
|
|
/** Standard-quality 2-stage reverb */
|
|
template <typename T>
|
|
class EffectReverbStdImp : public EffectBase<T>, public EffectReverb
|
|
{
|
|
ReverbDelayLine x0_AP[8][2] = {}; /**< All-pass delay lines */
|
|
ReverbDelayLine x78_C[8][2] = {}; /**< Comb delay lines */
|
|
float xf0_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
|
float xf4_combCoef[8][2] = {}; /**< Comb mix coefficients */
|
|
float x10c_lpLastout[8] = {}; /**< Last low-pass results */
|
|
float x118_level = 0.f; /**< Internal wet/dry mix factor */
|
|
float x11c_damping = 0.f; /**< Low-pass damping */
|
|
int32_t x120_preDelayTime = 0; /**< Sample count of pre-delay */
|
|
std::unique_ptr<float[]> x124_preDelayLine[8]; /**< Dedicated pre-delay buffers */
|
|
float* x130_preDelayPtr[8] = {}; /**< Current pre-delay pointers */
|
|
|
|
double m_sampleRate; /**< copy of sample rate */
|
|
void _update();
|
|
public:
|
|
EffectReverbStdImp(float coloration, float mix, float time,
|
|
float damping, float preDelay, double sampleRate);
|
|
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap);
|
|
};
|
|
|
|
/** High-quality 3-stage reverb with per-channel low-pass and crosstalk */
|
|
template <typename T>
|
|
class EffectReverbHiImp : public EffectBase<T>, public EffectReverbHi
|
|
{
|
|
ReverbDelayLine x0_AP[8][2] = {}; /**< All-pass delay lines */
|
|
ReverbDelayLine x78_LP[8] = {}; /**< Per-channel low-pass delay-lines */
|
|
ReverbDelayLine xb4_C[8][3] = {}; /**< Comb delay lines */
|
|
float x168_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
|
float x16c_combCoef[8][3] = {}; /**< Comb mix coefficients */
|
|
float x190_lpLastout[8] = {}; /**< Last low-pass results */
|
|
float x19c_level = 0.f; /**< Internal wet/dry mix factor */
|
|
float x1a0_damping = 0.f; /**< Low-pass damping */
|
|
int32_t x1a4_preDelayTime = 0; /**< Sample count of pre-delay */
|
|
std::unique_ptr<float[]> x1ac_preDelayLine[8]; /**< Dedicated pre-delay buffers */
|
|
float* x1b8_preDelayPtr[8] = {}; /**< Current pre-delay pointers */
|
|
float x1a8_internalCrosstalk;
|
|
|
|
double m_sampleRate; /**< copy of sample rate */
|
|
void _update();
|
|
void _handleReverb(T* audio, int chanIdx, int chanCount, int sampleCount);
|
|
void _doCrosstalk(T* audio, float wet, float dry, int chanCount, int sampleCount);
|
|
public:
|
|
EffectReverbHiImp(float coloration, float mix, float time,
|
|
float damping, float preDelay, float crosstalk, double sampleRate);
|
|
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap);
|
|
};
|
|
|
|
}
|
|
|
|
#endif // __AMUSE_EFFECTREVERB_HPP__
|