210 lines
5.2 KiB
C++
210 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "DSP/Delay.h"
|
|
#include "DSP/AllPassFilter.h"
|
|
#include "DSP/OnePole.h"
|
|
|
|
namespace Audio
|
|
{
|
|
// forward
|
|
class FWaveTableOsc;
|
|
|
|
struct FEarlyReflectionsSettings
|
|
{
|
|
// Early reflections gain
|
|
float Gain;
|
|
|
|
// Delay between input signal and early reflections
|
|
float PreDelayMsec;
|
|
|
|
// Input sample bandwidth before entering early reflections
|
|
float Bandwidth;
|
|
|
|
// Early reflections decay (lower value is longer)
|
|
float Decay;
|
|
|
|
// Early reflection high frequency absorption factor
|
|
float Absorption;
|
|
|
|
FEarlyReflectionsSettings()
|
|
: Gain(1.0f)
|
|
, PreDelayMsec(0.0f)
|
|
, Bandwidth(0.8)
|
|
, Decay(0.5)
|
|
, Absorption(0.7)
|
|
{}
|
|
};
|
|
|
|
// Basic implementation of a 4x4 Feedback Delay Network
|
|
class FEarlyReflections
|
|
{
|
|
public:
|
|
SIGNALPROCESSING_API FEarlyReflections();
|
|
SIGNALPROCESSING_API virtual ~FEarlyReflections();
|
|
|
|
SIGNALPROCESSING_API void Init(const int32 InSampleRate);
|
|
|
|
// Sets the reverb settings, applies, and updates
|
|
SIGNALPROCESSING_API void SetSettings(const FEarlyReflectionsSettings& InSettings);
|
|
|
|
// Process the single audio frame
|
|
SIGNALPROCESSING_API void ProcessAudioFrame(const float* InBuffer, const int32 InChannels, float* OutBuffer, const int32 OutChannels);
|
|
|
|
protected:
|
|
SIGNALPROCESSING_API void ApplySettings();
|
|
SIGNALPROCESSING_API float ProcessDelayLine(const float InSample, FDelayAPF& InAPF, FOnePoleLPF& InLPF);
|
|
|
|
FEarlyReflectionsSettings Settings;
|
|
|
|
struct FFDNDelayData
|
|
{
|
|
// Pre-Delay for the input audio to the FDN reverberator
|
|
FDelay PreDelay;
|
|
|
|
// Input LPF for early reflections
|
|
FOnePoleLPF InputLPF;
|
|
|
|
// 4 feedback delay lines per input channel (stereo) which feed into each other using a normalized feedback matrix
|
|
FDelayAPF APF[4];
|
|
FOnePoleLPF LPF[4];
|
|
|
|
float DelayLineInputs[4];
|
|
float DelayLineOuputs[4];
|
|
};
|
|
|
|
float MatrixScaleFactor;
|
|
|
|
// Stereo input/output for early reflections
|
|
FFDNDelayData Data[2];
|
|
};
|
|
|
|
struct FPlateReverbSettings
|
|
{
|
|
// The settings for the early reflections part of the reverb
|
|
FEarlyReflectionsSettings EarlyReflections;
|
|
|
|
// Milliseconds for the predelay
|
|
float LateDelayMsec;
|
|
|
|
// Initial attenuation of audio after it leaves the predelay
|
|
float LateGain;
|
|
|
|
// Frequency bandwidth of audio going into input diffusers. 0.999 is full bandwidth
|
|
float Bandwidth;
|
|
|
|
// Amount of input diffusion (larger value results in more diffusion)
|
|
float Diffusion;
|
|
|
|
// The amount of high-frequency dampening in plate feedback paths
|
|
float Dampening;
|
|
|
|
// The amount of decay in the feedback path. Lower value is larger reverb time.
|
|
float Decay;
|
|
|
|
// The amount of diffusion in decay path. Larger values is a more dense reverb.
|
|
float Density;
|
|
|
|
// The amount of output wetness of the reverb as a whole
|
|
float Wetness;
|
|
|
|
FPlateReverbSettings()
|
|
: LateDelayMsec(0.0f)
|
|
, LateGain(0.0f)
|
|
, Bandwidth(0.5f)
|
|
, Diffusion(0.5f)
|
|
, Dampening(0.5f)
|
|
, Decay(0.5f)
|
|
, Density(0.5f)
|
|
, Wetness(0.5f)
|
|
{}
|
|
};
|
|
|
|
class FPlateReverb
|
|
{
|
|
public:
|
|
SIGNALPROCESSING_API FPlateReverb();
|
|
SIGNALPROCESSING_API ~FPlateReverb();
|
|
|
|
// Initialize the reverb with the given sample rate
|
|
SIGNALPROCESSING_API void Init(const int32 InSampleRate);
|
|
|
|
// Whether or not to enable late reflections
|
|
SIGNALPROCESSING_API void EnableLateReflections(const bool bInEnableLateReflections);
|
|
|
|
// Whether or not to enable late reflections
|
|
SIGNALPROCESSING_API void EnableEarlyReflections(const bool bInEnableEarlyReflections);
|
|
|
|
// Sets the reverb settings, applies, and updates
|
|
SIGNALPROCESSING_API void SetSettings(const FPlateReverbSettings& InSettings);
|
|
|
|
// Process the single audio frame
|
|
SIGNALPROCESSING_API void ProcessAudioFrame(const float* InBuffer, const int32 InChannels, float* OutBuffer, const int32 OutChannels);
|
|
|
|
protected:
|
|
|
|
SIGNALPROCESSING_API void ApplySettings();
|
|
|
|
// Current parameter settings of reverb
|
|
FPlateReverbSettings Settings;
|
|
|
|
// Early reflections effect
|
|
FEarlyReflections EarlyReflections;
|
|
|
|
// Sample rate used for hard-coded delay line values
|
|
static const int32 PresetSampleRate = 29761;
|
|
|
|
// A simple pre-delay line to emulate large delays for late-reflections
|
|
FDelay PreDelay;
|
|
|
|
// Input diffusion
|
|
FOnePoleLPF InputLPF;
|
|
FDelayAPF APF1;
|
|
FDelayAPF APF2;
|
|
FDelayAPF APF3;
|
|
FDelayAPF APF4;
|
|
|
|
// Wave table oscillator, modulates input APF in plates
|
|
TSharedPtr<FWaveTableOsc> LFO;
|
|
|
|
// Plate data struction to organize each plate's delay lines and filters
|
|
struct FPlate
|
|
{
|
|
FDelayAPF ModulatedAPF;
|
|
FDelay Delay1;
|
|
FOnePoleLPF LPF;
|
|
FDelayAPF APF;
|
|
FDelay Delay2;
|
|
|
|
// Sample output of tank
|
|
float PreviousSample;
|
|
float ModulatedBaseDelayMsec;
|
|
float ModulatedDeltaDelayMsec;
|
|
|
|
FPlate()
|
|
: PreviousSample(0.0f)
|
|
, ModulatedBaseDelayMsec(0.0f)
|
|
, ModulatedDeltaDelayMsec(0.0f)
|
|
{}
|
|
};
|
|
|
|
// The plate data
|
|
FPlate LeftPlate;
|
|
FPlate RightPlate;
|
|
|
|
// Tap points to read audio from various delay lines in plates
|
|
static const int32 NumTaps = 7;
|
|
|
|
float LeftTaps[NumTaps];
|
|
float RightTaps[NumTaps];
|
|
|
|
// Whether or not late reflections are enabled
|
|
bool bEnableLateReflections;
|
|
|
|
// Whether or not to enable early reflections
|
|
bool bEnableEarlyReflections;
|
|
};
|
|
}
|