rmx-19/Source/PluginProcessor.h
Armin 35d6cd014a add generative evolution, cross-mod and reverb FX; expand preset bank
- 4 new params (xmod/xmix/evolve/warp) with free-running brownian evolution
- evolution: tune drift, osc2 detune sway, osc-mix crossfade, filter cutoff
  wander, resonance growl, warp drive/bias, cross-mod bloom
- per-voice unison detune spread for fat stacks
- FX engine: 3-tap ensemble chorus, filtered-feedback ping-pong delay,
  Schroeder hall reverb; new FX types 4-7 (REV HALL/ENS+REV/DLY+REV/CATHEDRAL)
- 195 presets: 40-field realignment, genre-tuned FX identities, showcase eval
- calibrate banks vs attack-inclusive peak (median 0.263); fix square-LFO
  on filter sustain collapse
2026-09-10 16:55:47 +02:00

69 lines
No EOL
2.5 KiB
C++

#pragma once
#include <juce_audio_processors/juce_audio_processors.h>
#include "Params.h"
#include "PresetBank.h"
#include "SynthEngine.h"
#include <juce_dsp/juce_dsp.h>
class RMX19AudioProcessor : public juce::AudioProcessor
{
public:
RMX19AudioProcessor();
~RMX19AudioProcessor() override;
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
void releaseResources() override;
void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
juce::AudioProcessorEditor* createEditor() override;
bool hasEditor() const override;
const juce::String getName() const override;
bool acceptsMidi() const override { return true; }
bool producesMidi() const override { return false; }
double getTailLengthSeconds() const override { return prm::delaySyncMaxTime() + 2.0; }
int getNumPrograms() override;
int getCurrentProgram() override;
void setCurrentProgram (int) override;
const juce::String getProgramName (int) override;
void changeProgramName (int, const juce::String&) override;
void getStateInformation (juce::MemoryBlock&) override;
void setStateInformation (const void*, int) override;
juce::AudioProcessorValueTreeState apvts;
PresetBank& getBank() { return bank; }
SynthEngine& getEngine() { return engine; }
int getPatchIndex() const noexcept { return patchIndex; }
void selectPatch (int i);
int getActiveVoices() const noexcept { return engine.activeVoices(); }
juce::uint32 getLastMidiTime() const noexcept { return lastMidi; }
float getOutputLevel() const noexcept { return outMeter; }
float getCpu() const noexcept { return cpu; }
private:
void processMidi (juce::MidiBuffer&, const VParams&);
juce::AudioProcessorValueTreeState::ParameterLayout createParams();
class FxEngine;
std::unique_ptr<FxEngine> fx;
class ArpEngine;
std::unique_ptr<ArpEngine> arp;
PresetBank bank;
SynthEngine engine;
int patchIndex = 0;
int lastPatchParam = 0;
juce::uint32 lastMidi = 0;
float cpu = 0.0f;
float outMeter = 0.0f; // smoothed output peak, written on the audio thread
float dcL = 0.0f, dcR = 0.0f, dcPrevL = 0.0f, dcPrevR = 0.0f;
juce::AudioBuffer<float> osBuf; // internal 2x oversample target (HQ mode)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RMX19AudioProcessor)
};