Upload files to "Source"
This commit is contained in:
@@ -1,118 +1,99 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
GraphComponent.h
|
||||
Created: 4 Jul 2025 11:43:57pm
|
||||
Author: timot
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AudioBufferQueue.h"
|
||||
|
||||
//==============================================================================
|
||||
template <typename SampleType>
|
||||
class GraphComponent : public juce::Component,
|
||||
private juce::Timer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
GraphComponent(SampleType min, SampleType max, int numPoints): func(func), min(min), max(max), numPoints(numPoints)
|
||||
{
|
||||
x.resize(numPoints);
|
||||
y.resize(numPoints);
|
||||
setFramesPerSecond(30);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void setFramesPerSecond(int framesPerSecond)
|
||||
{
|
||||
jassert(framesPerSecond > 0 && framesPerSecond < 1000);
|
||||
startTimerHz(framesPerSecond);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void setFunction(const std::function<SampleType(SampleType)>& func) {
|
||||
this->func = func;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void paint(juce::Graphics& g) override
|
||||
{
|
||||
g.fillAll(juce::Colours::black);
|
||||
g.setColour(juce::Colours::white);
|
||||
|
||||
auto area = getLocalBounds();
|
||||
|
||||
if (hasData && area.isFinite()) {
|
||||
auto h = (SampleType)area.getHeight();
|
||||
auto w = (SampleType)area.getWidth();
|
||||
|
||||
for (size_t i = 1; i < numPoints; ++i) {
|
||||
auto px_prev = ((x[i - 1] - min) / (max - min)) * w;
|
||||
auto py_prev = h - ((y[i - 1] - minY) / (maxY - minY)) * h;
|
||||
|
||||
auto px_next = ((x[i] - min) / (max - min)) * w;
|
||||
auto py_next = h - ((y[i] - minY) / (maxY - minY)) * h;
|
||||
|
||||
juce::Line<SampleType> line(juce::Point<SampleType>(px_prev, py_prev), juce::Point<SampleType>(px_next, py_next));
|
||||
|
||||
g.drawLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void resized() override {}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::vector<SampleType> x, y;
|
||||
SampleType minY, maxY;
|
||||
SampleType min, max;
|
||||
int numPoints;
|
||||
std::function<SampleType(SampleType)> func;
|
||||
bool hasData = false;
|
||||
|
||||
//==============================================================================
|
||||
void timerCallback() override
|
||||
{
|
||||
float step = (max - min) / (SampleType)(numPoints - 1);
|
||||
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
x[i] = min + step * (SampleType)i;
|
||||
y[i] = func(x[i]);
|
||||
}
|
||||
|
||||
auto p = minmax_element(y.begin(), y.end());
|
||||
|
||||
minY = *p.first; maxY = *p.second;
|
||||
|
||||
hasData = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/*static void plot(const SampleType* data,
|
||||
size_t numSamples,
|
||||
juce::Graphics& g,
|
||||
juce::Rectangle<SampleType> rect,
|
||||
SampleType scaler = SampleType(1),
|
||||
SampleType offset = SampleType(0))
|
||||
{
|
||||
auto w = rect.getWidth();
|
||||
auto h = rect.getHeight();
|
||||
auto right = rect.getRight();
|
||||
|
||||
auto center = rect.getBottom() - offset;
|
||||
auto gain = h * scaler;
|
||||
|
||||
for (size_t i = 1; i < numSamples; ++i)
|
||||
g.drawLine({ juce::jmap(SampleType(i - 1), SampleType(0), SampleType(numSamples - 1), SampleType(right - w), SampleType(right)),
|
||||
center - gain * data[i - 1],
|
||||
juce::jmap(SampleType(i), SampleType(0), SampleType(numSamples - 1), SampleType(right - w), SampleType(right)),
|
||||
center - gain * data[i] });
|
||||
}*/
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
GraphComponent.h
|
||||
Created: 4 Jul 2025 11:43:57pm
|
||||
Author: timot
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm> // for std::minmax_element
|
||||
#include "AudioBufferQueue.h"
|
||||
|
||||
//==============================================================================
|
||||
template <typename SampleType>
|
||||
class GraphComponent : public juce::Component,
|
||||
private juce::Timer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
GraphComponent(SampleType minIn, SampleType maxIn, int numPointsIn)
|
||||
: min(minIn), max(maxIn), numPoints(numPointsIn)
|
||||
{
|
||||
x.resize(numPoints);
|
||||
y.resize(numPoints);
|
||||
setFramesPerSecond(30);
|
||||
// func will be set via setFunction before paint; provide a safe default
|
||||
func = [](SampleType) noexcept { return SampleType(); };
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void setFramesPerSecond(int framesPerSecond)
|
||||
{
|
||||
jassert(framesPerSecond > 0 && framesPerSecond < 1000);
|
||||
startTimerHz(framesPerSecond);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void setFunction(const std::function<SampleType(SampleType)>& f) { func = f; }
|
||||
|
||||
//==============================================================================
|
||||
void paint(juce::Graphics& g) override
|
||||
{
|
||||
g.fillAll(juce::Colours::black);
|
||||
g.setColour(juce::Colours::white);
|
||||
|
||||
auto area = getLocalBounds();
|
||||
|
||||
if (hasData && area.isFinite())
|
||||
{
|
||||
auto h = (SampleType)area.getHeight();
|
||||
auto w = (SampleType)area.getWidth();
|
||||
|
||||
for (size_t i = 1; i < (size_t)numPoints; ++i)
|
||||
{
|
||||
auto px_prev = ((x[i - 1] - min) / (max - min)) * w;
|
||||
auto py_prev = h - ((y[i - 1] - minY) / (maxY - minY)) * h;
|
||||
|
||||
auto px_next = ((x[i] - min) / (max - min)) * w;
|
||||
auto py_next = h - ((y[i] - minY) / (maxY - minY)) * h;
|
||||
|
||||
g.drawLine({ px_prev, py_prev, px_next, py_next });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void resized() override {}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::vector<SampleType> x, y;
|
||||
SampleType minY{ SampleType() }, maxY{ SampleType(1) };
|
||||
SampleType min{}, max{};
|
||||
int numPoints{};
|
||||
std::function<SampleType(SampleType)> func;
|
||||
bool hasData = false;
|
||||
|
||||
//==============================================================================
|
||||
void timerCallback() override
|
||||
{
|
||||
const SampleType step = (max - min) / (SampleType)(numPoints - 1);
|
||||
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
{
|
||||
x[(size_t)i] = min + step * (SampleType)i;
|
||||
y[(size_t)i] = func(x[(size_t)i]);
|
||||
}
|
||||
|
||||
auto p = std::minmax_element(y.begin(), y.end());
|
||||
minY = *p.first;
|
||||
maxY = *p.second;
|
||||
|
||||
hasData = true;
|
||||
repaint();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,131 +1,149 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
NeuralSharedParams.h
|
||||
Created: 21 Jun 2025 7:53:02am
|
||||
Author: timot
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
struct SliderDetail {
|
||||
std::string label;
|
||||
|
||||
float min, max, interval, defValue;
|
||||
};
|
||||
|
||||
typedef std::unordered_map <std::string, SliderDetail> ParamMap;
|
||||
|
||||
// Each SliderDetail: { label, min, max, step, defaultValue }
|
||||
const std::unordered_map<std::string, ParamMap> PARAM_SETTINGS = {
|
||||
|
||||
{ "chorus", {
|
||||
{ "rate", { "Rate", 0.0f, 1.0f, 0.1f, 0.1f } }, // Modulation speed
|
||||
{ "depth", { "Depth", 0.0f, 1.0f, 0.1f, 0.1f } }, // Modulation amount
|
||||
{ "centre", { "Centre", 0.0f, 1.0f, 0.1f, 0.1f } }, // Center delay
|
||||
{ "feedback", { "Feedback", 0.0f, 1.0f, 0.1f, 0.1f } }, // Feedback amount
|
||||
{ "mix", { "Mix", 0.0f, 1.0f, 0.1f, 0.1f } } // Dry/wet blend
|
||||
}},
|
||||
|
||||
{ "delay", {
|
||||
{ "delay", { "Delay", 0.0f, 1.0f, 0.1f, 0.1f } } // Delay time
|
||||
}},
|
||||
|
||||
{ "reverb", {
|
||||
{ "roomSize", { "Room Size", 0.0f, 1.0f, 0.1f, 0.1f } }, // Size of reverb space
|
||||
{ "damping", { "Damping", 0.0f, 1.0f, 0.1f, 0.1f } }, // High-frequency attenuation
|
||||
{ "wetLevel", { "Wet Level", 0.0f, 1.0f, 0.1f, 0.1f } }, // Reverb amount
|
||||
{ "dryLevel", { "Dry Level", 0.0f, 1.0f, 0.1f, 0.1f } }, // Dry signal amount
|
||||
{ "width", { "Width", 0.0f, 1.0f, 0.1f, 0.1f } }, // Stereo width
|
||||
{ "freezeMode", { "Freeze Mode", 0.0f, 1.0f, 0.1f, 0.1f } } // Infinite decay toggle
|
||||
}},
|
||||
|
||||
{ "adsr", {
|
||||
{ "attack", { "Attack", 0.0f, 1.0f, 0.1f, 0.1f } }, // Attack time
|
||||
{ "decay", { "Decay", 0.0f, 1.0f, 0.1f, 0.1f } }, // Decay time
|
||||
{ "sustain", { "Sustain", 0.0f, 1.0f, 0.1f, 0.1f } }, // Sustain level
|
||||
{ "release", { "Release", 0.0f, 1.0f, 0.1f, 0.1f } } // Release time
|
||||
}},
|
||||
|
||||
{ "flanger", {
|
||||
{ "rate", { "Rate", 0.1f, 5.0f, 0.1f, 0.1f } }, // LFO speed
|
||||
{ "depth", { "Depth", 0.1f, 10.0f, 0.1f, 0.1f } }, // Mod depth in ms
|
||||
{ "feedback", { "Feedback", 0.0f, 1.0f, 0.1f, 0.1f } }, // Feedback amount
|
||||
{ "dryMix", { "Dry/Wet", 0.0f, 1.0f, 0.1f, 0.1f } }, // Mix control
|
||||
{ "phase", { "Phase", 0.0f, 1.0f, 0.1f, 0.1f } }, // LFO phase offset (for stereo)
|
||||
{ "delay", { "Delay", 0.0f, 3.0f, 0.1f, 0.1f } } // Base delay offset
|
||||
}},
|
||||
|
||||
{ "filter", {
|
||||
{ "cutoff", { "Cutoff", 0.2f, 20000.0f, 1.0f, 1000.0f } }, // Frequency cutoff
|
||||
{ "resonance", { "Resonance", 0.1f, 10.0f, 0.1f, 0.2f } }, // Resonance/Q factor
|
||||
{ "type", { "L/H/B", 0.0f, 2.0f, 1.0f, 0.0f } }, // 0 = LPF, 1 = HPF, 2 = BPF
|
||||
{ "drive", { "Drive", 0.0f, 1.0f, 0.01f, 0.0f } }, // Pre-gain into filter
|
||||
{ "mod", { "Mod", -1.0f, 1.0f, 0.1f, 0.0f } }, // Modulation amount
|
||||
{ "key", { "Key", 0.0f, 1.0f, 0.1f, 0.0f } } // Key tracking
|
||||
}},
|
||||
|
||||
{ "distortion", {
|
||||
{ "drive", { "Drive", 0.0f, 30.0f, 0.1f, 10.0f } }, // Input gain before shaping
|
||||
{ "mix", { "Mix", 0.0f, 1.0f, 0.01f, 0.5f } }, // Wet/dry blend
|
||||
{ "bias", { "Bias", -1.0f, 1.0f, 0.01f, 0.0f } }, // DC offset
|
||||
{ "tone", { "Tone", 100.0f, 8000.0f, 10.0f, 3000.0f } }, // LPF after distortion
|
||||
{ "shape", { "Shape", 0.0f, 2.0f, 1.0f, 0.0f } } // 0=tanh, 1=hard clip, 2=atan
|
||||
}}
|
||||
|
||||
};
|
||||
|
||||
struct NeuralSharedParams
|
||||
{
|
||||
std::atomic<int> waveform{ -1 };
|
||||
|
||||
std::atomic<float>* adsrAttack;
|
||||
std::atomic<float>* adsrDecay;
|
||||
std::atomic<float>* adsrSustain;
|
||||
std::atomic<float>* adsrRelease;
|
||||
|
||||
std::atomic<float>* delayTime;
|
||||
|
||||
std::atomic<float>* chorusRate;
|
||||
std::atomic<float>* chorusDepth;
|
||||
std::atomic<float>* chorusCentre;
|
||||
std::atomic<float>* chorusFeedback;
|
||||
std::atomic<float>* chorusMix;
|
||||
|
||||
std::atomic<float>* reverbRoomSize;
|
||||
std::atomic<float>* reverbDamping;
|
||||
std::atomic<float>* reverbWetLevel;
|
||||
std::atomic<float>* reverbDryLevel;
|
||||
std::atomic<float>* reverbWidth;
|
||||
std::atomic<float>* reverbFreezeMode;
|
||||
|
||||
std::atomic<float>* flangerRate;
|
||||
std::atomic<float>* flangerDepth;
|
||||
std::atomic<float>* flangerFeedback;
|
||||
std::atomic<float>* flangerDryMix;
|
||||
std::atomic<float>* flangerPhase;
|
||||
std::atomic<float>* flangerDelay;
|
||||
|
||||
std::atomic<float>* filterCutoff;
|
||||
std::atomic<float>* filterResonance;
|
||||
std::atomic<float>* filterType;
|
||||
std::atomic<float>* filterDrive;
|
||||
std::atomic<float>* filterMod;
|
||||
std::atomic<float>* filterKey;
|
||||
|
||||
std::atomic<float>* distortionDrive;
|
||||
std::atomic<float>* distortionMix;
|
||||
std::atomic<float>* distortionBias;
|
||||
std::atomic<float>* distortionTone;
|
||||
std::atomic<float>* distortionShape;
|
||||
|
||||
std::atomic<float>* lowGainDbls;
|
||||
std::atomic<float>* midGainDbls;
|
||||
std::atomic<float>* highGainDbls;
|
||||
|
||||
std::atomic<float>* masterDbls;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
struct SliderDetail {
|
||||
std::string label;
|
||||
float min, max, interval, defValue;
|
||||
};
|
||||
|
||||
using ParamMap = std::unordered_map<std::string, SliderDetail>;
|
||||
|
||||
// Each SliderDetail: { label, min, max, step, defaultValue }
|
||||
const std::unordered_map<std::string, ParamMap> PARAM_SETTINGS = {
|
||||
{ "chorus", {
|
||||
{ "rate", { "Rate", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "depth", { "Depth", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "centre", { "Centre", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "feedback", { "Feedback", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "mix", { "Mix", 0.0f, 1.0f, 0.1f, 0.1f } }
|
||||
}},
|
||||
{ "delay", {
|
||||
{ "delay", { "Delay", 0.0f, 1.0f, 0.1f, 0.1f } }
|
||||
}},
|
||||
{ "reverb", {
|
||||
{ "roomSize", { "Room Size", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "damping", { "Damping", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "wetLevel", { "Wet Level", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "dryLevel", { "Dry Level", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "width", { "Width", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "freezeMode", { "Freeze Mode", 0.0f, 1.0f, 0.1f, 0.1f } }
|
||||
}},
|
||||
{ "adsr", {
|
||||
{ "attack", { "Attack", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "decay", { "Decay", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "sustain", { "Sustain", 0.0f, 1.0f, 0.1f, 0.1f } },
|
||||
{ "release", { "Release", 0.0f, 1.0f, 0.1f, 0.1f } }
|
||||
}},
|
||||
// Filter envelope group (short key: "fenv")
|
||||
{ "fenv", {
|
||||
{ "attack", { "Attack", 0.0f, 2.0f, 0.001f, 0.01f } },
|
||||
{ "decay", { "Decay", 0.0f, 2.0f, 0.001f, 0.10f } },
|
||||
{ "sustain", { "Sustain", 0.0f, 1.0f, 0.001f, 0.80f } },
|
||||
{ "release", { "Release", 0.0f, 4.0f, 0.001f, 0.40f } },
|
||||
{ "amount", { "Amount", -1.0f, 1.0f, 0.001f, 0.50f } }
|
||||
}},
|
||||
{ "flanger", {
|
||||
{ "rate", { "Rate", 0.1f, 5.0f, 0.1f, 0.1f } },
|
||||
{ "depth", { "Depth", 0.1f, 10.0f, 0.1f, 0.1f } }, // ms
|
||||
{ "feedback", { "Feedback", 0.0f, 0.95f, 0.01f, 0.1f } },
|
||||
{ "dryMix", { "Dry/Wet", 0.0f, 1.0f, 0.01f, 0.0f } },
|
||||
{ "phase", { "Phase", 0.0f, 1.0f, 0.1f, 0.0f } },
|
||||
{ "delay", { "Delay", 0.0f, 3.0f, 0.1f, 0.25f } } // ms base
|
||||
}},
|
||||
{ "filter", {
|
||||
{ "cutoff", { "Cutoff", 20.0f, 20000.0f, 1.0f, 1000.0f } },
|
||||
{ "resonance", { "Resonance", 0.1f, 10.0f, 0.1f, 0.7f } },
|
||||
{ "type", { "L/H/B", 0.0f, 2.0f, 1.0f, 0.0f } },
|
||||
{ "drive", { "Drive", 0.0f, 1.0f, 0.01f, 0.0f } },
|
||||
{ "mod", { "Mod", -1.0f, 1.0f, 0.1f, 0.0f } },
|
||||
{ "key", { "Key", 0.0f, 1.0f, 0.1f, 0.0f } }
|
||||
}},
|
||||
{ "distortion", {
|
||||
{ "drive", { "Drive", 0.0f, 30.0f, 0.1f, 10.0f } },
|
||||
{ "mix", { "Mix", 0.0f, 1.0f, 0.01f, 0.0f } },
|
||||
{ "bias", { "Bias", -1.0f, 1.0f, 0.01f, 0.0f } },
|
||||
{ "tone", { "Tone", 100.0f, 8000.0f, 10.0f, 3000.0f } },
|
||||
{ "shape", { "Shape", 0.0f, 2.0f, 1.0f, 0.0f } }
|
||||
}}
|
||||
};
|
||||
|
||||
struct NeuralSharedParams
|
||||
{
|
||||
std::atomic<int> waveform{ -1 };
|
||||
|
||||
// Amp ADSR
|
||||
std::atomic<float>* adsrAttack{};
|
||||
std::atomic<float>* adsrDecay{};
|
||||
std::atomic<float>* adsrSustain{};
|
||||
std::atomic<float>* adsrRelease{};
|
||||
|
||||
// Delay
|
||||
std::atomic<float>* delayTime{};
|
||||
|
||||
// Chorus
|
||||
std::atomic<float>* chorusRate{};
|
||||
std::atomic<float>* chorusDepth{};
|
||||
std::atomic<float>* chorusCentre{};
|
||||
std::atomic<float>* chorusFeedback{};
|
||||
std::atomic<float>* chorusMix{};
|
||||
|
||||
// Reverb
|
||||
std::atomic<float>* reverbRoomSize{};
|
||||
std::atomic<float>* reverbDamping{};
|
||||
std::atomic<float>* reverbWetLevel{};
|
||||
std::atomic<float>* reverbDryLevel{};
|
||||
std::atomic<float>* reverbWidth{};
|
||||
std::atomic<float>* reverbFreezeMode{};
|
||||
|
||||
// Flanger
|
||||
std::atomic<float>* flangerRate{};
|
||||
std::atomic<float>* flangerDepth{};
|
||||
std::atomic<float>* flangerFeedback{};
|
||||
std::atomic<float>* flangerDryMix{};
|
||||
std::atomic<float>* flangerPhase{};
|
||||
std::atomic<float>* flangerDelay{};
|
||||
|
||||
// Filter (base)
|
||||
std::atomic<float>* filterCutoff{};
|
||||
std::atomic<float>* filterResonance{};
|
||||
std::atomic<float>* filterType{};
|
||||
std::atomic<float>* filterDrive{};
|
||||
std::atomic<float>* filterMod{};
|
||||
std::atomic<float>* filterKey{};
|
||||
|
||||
// Filter Env (polyphonic)
|
||||
std::atomic<float>* fenvAttack{};
|
||||
std::atomic<float>* fenvDecay{};
|
||||
std::atomic<float>* fenvSustain{};
|
||||
std::atomic<float>* fenvRelease{};
|
||||
std::atomic<float>* fenvAmount{}; // +/- octaves
|
||||
|
||||
// Distortion
|
||||
std::atomic<float>* distortionDrive{};
|
||||
std::atomic<float>* distortionMix{};
|
||||
std::atomic<float>* distortionBias{};
|
||||
std::atomic<float>* distortionTone{};
|
||||
std::atomic<float>* distortionShape{};
|
||||
|
||||
// Per-panel bypass (AudioParameterBool, exposed as float 0/1 via getRawParameterValue)
|
||||
std::atomic<float>* chorusOn{};
|
||||
std::atomic<float>* delayOn{};
|
||||
std::atomic<float>* reverbOn{};
|
||||
std::atomic<float>* flangerOn{};
|
||||
std::atomic<float>* distortionOn{};
|
||||
std::atomic<float>* filterOn{};
|
||||
std::atomic<float>* eqOn{};
|
||||
|
||||
// ==== Wavetable controls ====
|
||||
std::atomic<float>* wtOn{}; // 0/1 (AudioParameterBool appears as float raw value)
|
||||
std::atomic<float>* wtMorph{}; // 0..15 (continuous frame index)
|
||||
|
||||
// EQ + Master
|
||||
std::atomic<float>* lowGainDbls{};
|
||||
std::atomic<float>* midGainDbls{};
|
||||
std::atomic<float>* highGainDbls{};
|
||||
std::atomic<float>* masterDbls{};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user