monostep/Source/dsp/FxProcessor.h
Armin 342d413563 Add delay and reverb FX section with full DSP
Rename the DIST section to FX and expand it with tempo-synced delay
(Time/Strength/Sync) and Schroeder reverb (Roomsize/Strength/Diffusion).
New FxProcessor runs post-voice on the stereo bus; widen the editor to
1280px to fit the new section. Add a TestHost check that the FX tail
rings out after note release.
2026-08-06 16:35:34 +02:00

71 lines
1.9 KiB
C++

#pragma once
#include <JuceHeader.h>
#include <vector>
namespace monostep
{
// Tempo-synced delay + Schroeder reverb, applied after the voice.
class FxProcessor
{
public:
FxProcessor() = default;
void prepare (double sampleRate, int numChannels);
void reset();
struct Params
{
float delayTime = 0.35f; // normalized knob 0..1
float delayMix = 0.0f; // 0..1 dry/wet
bool delaySync = true; // tempo-synced vs. free milliseconds
float reverbRoom = 0.5f; // 0..1
float reverbMix = 0.0f; // 0..1 dry/wet
float reverbDiff = 0.6f; // 0..1 allpass diffusion
double bpm = 120.0;
};
void setParams (const Params& p);
void process (juce::AudioBuffer<float>& buffer, int numSamples);
// Shared knob-to-time mapping so the editor displays the same values the DSP uses.
static float delayTimeSeconds (float knobNormalized, bool sync, double bpm);
static juce::String delayTimeLabel (float knobNormalized, bool sync, double bpm);
private:
struct DelayChannel
{
std::vector<float> memory;
int writeIndex = 0;
float smoothedDelay = 0.0f;
float feedbackLp = 0.0f;
};
struct ReverbChannel
{
std::vector<float> combs[4];
std::vector<float> allpasses[2];
int combIndex[4] = {};
int allpassIndex[2] = {};
};
void processDelay (juce::AudioBuffer<float>& buffer, int numSamples);
void processReverb (juce::AudioBuffer<float>& buffer, int numSamples);
double sampleRate = 44100.0;
int numChannels = 2;
int maxDelaySamples = 0;
int combDelaySamples[2][4] = {};
int allpassDelaySamples[2][2] = {};
Params params;
float currentDelaySeconds = 0.0f;
std::vector<DelayChannel> delays;
std::vector<ReverbChannel> reverbs;
};
} // namespace monostep