Upload files to "Source"

This commit is contained in:
ed
2025-10-22 16:57:48 +00:00
parent df0ab9263c
commit 9d232cb2dd
2 changed files with 248 additions and 249 deletions

View File

@@ -1,118 +1,99 @@
/* /*
============================================================================== ==============================================================================
GraphComponent.h GraphComponent.h
Created: 4 Jul 2025 11:43:57pm Created: 4 Jul 2025 11:43:57pm
Author: timot Author: timot
============================================================================== ==============================================================================
*/ */
#pragma once #pragma once
#include "AudioBufferQueue.h" #include <algorithm> // for std::minmax_element
#include "AudioBufferQueue.h"
//==============================================================================
template <typename SampleType> //==============================================================================
class GraphComponent : public juce::Component, template <typename SampleType>
private juce::Timer class GraphComponent : public juce::Component,
{ private juce::Timer
public: {
//============================================================================== public:
GraphComponent(SampleType min, SampleType max, int numPoints): func(func), min(min), max(max), numPoints(numPoints) //==============================================================================
{ GraphComponent(SampleType minIn, SampleType maxIn, int numPointsIn)
x.resize(numPoints); : min(minIn), max(maxIn), numPoints(numPointsIn)
y.resize(numPoints); {
setFramesPerSecond(30); x.resize(numPoints);
} y.resize(numPoints);
setFramesPerSecond(30);
//============================================================================== // func will be set via setFunction before paint; provide a safe default
void setFramesPerSecond(int framesPerSecond) func = [](SampleType) noexcept { return SampleType(); };
{ }
jassert(framesPerSecond > 0 && framesPerSecond < 1000);
startTimerHz(framesPerSecond); //==============================================================================
} void setFramesPerSecond(int framesPerSecond)
{
//============================================================================== jassert(framesPerSecond > 0 && framesPerSecond < 1000);
void setFunction(const std::function<SampleType(SampleType)>& func) { startTimerHz(framesPerSecond);
this->func = func; }
}
//==============================================================================
//============================================================================== void setFunction(const std::function<SampleType(SampleType)>& f) { func = f; }
void paint(juce::Graphics& g) override
{ //==============================================================================
g.fillAll(juce::Colours::black); void paint(juce::Graphics& g) override
g.setColour(juce::Colours::white); {
g.fillAll(juce::Colours::black);
auto area = getLocalBounds(); g.setColour(juce::Colours::white);
if (hasData && area.isFinite()) { auto area = getLocalBounds();
auto h = (SampleType)area.getHeight();
auto w = (SampleType)area.getWidth(); if (hasData && area.isFinite())
{
for (size_t i = 1; i < numPoints; ++i) { auto h = (SampleType)area.getHeight();
auto px_prev = ((x[i - 1] - min) / (max - min)) * w; auto w = (SampleType)area.getWidth();
auto py_prev = h - ((y[i - 1] - minY) / (maxY - minY)) * h;
for (size_t i = 1; i < (size_t)numPoints; ++i)
auto px_next = ((x[i] - min) / (max - min)) * w; {
auto py_next = h - ((y[i] - minY) / (maxY - minY)) * h; auto px_prev = ((x[i - 1] - min) / (max - min)) * w;
auto py_prev = h - ((y[i - 1] - minY) / (maxY - minY)) * h;
juce::Line<SampleType> line(juce::Point<SampleType>(px_prev, py_prev), juce::Point<SampleType>(px_next, py_next));
auto px_next = ((x[i] - min) / (max - min)) * w;
g.drawLine(line); auto py_next = h - ((y[i] - minY) / (maxY - minY)) * h;
}
} g.drawLine({ px_prev, py_prev, px_next, py_next });
} }
}
//============================================================================== }
void resized() override {}
//==============================================================================
private: void resized() override {}
//==============================================================================
std::vector<SampleType> x, y; private:
SampleType minY, maxY; //==============================================================================
SampleType min, max; std::vector<SampleType> x, y;
int numPoints; SampleType minY{ SampleType() }, maxY{ SampleType(1) };
std::function<SampleType(SampleType)> func; SampleType min{}, max{};
bool hasData = false; int numPoints{};
std::function<SampleType(SampleType)> func;
//============================================================================== bool hasData = false;
void timerCallback() override
{ //==============================================================================
float step = (max - min) / (SampleType)(numPoints - 1); void timerCallback() override
{
for (int i = 0; i < numPoints; i++) { const SampleType step = (max - min) / (SampleType)(numPoints - 1);
x[i] = min + step * (SampleType)i;
y[i] = func(x[i]); for (int i = 0; i < numPoints; i++)
} {
x[(size_t)i] = min + step * (SampleType)i;
auto p = minmax_element(y.begin(), y.end()); y[(size_t)i] = func(x[(size_t)i]);
}
minY = *p.first; maxY = *p.second;
auto p = std::minmax_element(y.begin(), y.end());
hasData = true; minY = *p.first;
repaint(); 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] });
}*/
};

View File

@@ -1,131 +1,149 @@
/* #pragma once
==============================================================================
#include <atomic>
NeuralSharedParams.h #include <unordered_map>
Created: 21 Jun 2025 7:53:02am #include <string>
Author: timot
struct SliderDetail {
============================================================================== std::string label;
*/ float min, max, interval, defValue;
};
#pragma once
using ParamMap = std::unordered_map<std::string, SliderDetail>;
#include <atomic>
// Each SliderDetail: { label, min, max, step, defaultValue }
struct SliderDetail { const std::unordered_map<std::string, ParamMap> PARAM_SETTINGS = {
std::string label; { "chorus", {
{ "rate", { "Rate", 0.0f, 1.0f, 0.1f, 0.1f } },
float min, max, interval, defValue; { "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 } },
typedef std::unordered_map <std::string, SliderDetail> ParamMap; { "mix", { "Mix", 0.0f, 1.0f, 0.1f, 0.1f } }
}},
// Each SliderDetail: { label, min, max, step, defaultValue } { "delay", {
const std::unordered_map<std::string, ParamMap> PARAM_SETTINGS = { { "delay", { "Delay", 0.0f, 1.0f, 0.1f, 0.1f } }
}},
{ "chorus", { { "reverb", {
{ "rate", { "Rate", 0.0f, 1.0f, 0.1f, 0.1f } }, // Modulation speed { "roomSize", { "Room Size", 0.0f, 1.0f, 0.1f, 0.1f } },
{ "depth", { "Depth", 0.0f, 1.0f, 0.1f, 0.1f } }, // Modulation amount { "damping", { "Damping", 0.0f, 1.0f, 0.1f, 0.1f } },
{ "centre", { "Centre", 0.0f, 1.0f, 0.1f, 0.1f } }, // Center delay { "wetLevel", { "Wet Level", 0.0f, 1.0f, 0.1f, 0.1f } },
{ "feedback", { "Feedback", 0.0f, 1.0f, 0.1f, 0.1f } }, // Feedback amount { "dryLevel", { "Dry Level", 0.0f, 1.0f, 0.1f, 0.1f } },
{ "mix", { "Mix", 0.0f, 1.0f, 0.1f, 0.1f } } // Dry/wet blend { "width", { "Width", 0.0f, 1.0f, 0.1f, 0.1f } },
}}, { "freezeMode", { "Freeze Mode", 0.0f, 1.0f, 0.1f, 0.1f } }
}},
{ "delay", { { "adsr", {
{ "delay", { "Delay", 0.0f, 1.0f, 0.1f, 0.1f } } // Delay time { "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 } },
{ "reverb", { { "release", { "Release", 0.0f, 1.0f, 0.1f, 0.1f } }
{ "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 // Filter envelope group (short key: "fenv")
{ "wetLevel", { "Wet Level", 0.0f, 1.0f, 0.1f, 0.1f } }, // Reverb amount { "fenv", {
{ "dryLevel", { "Dry Level", 0.0f, 1.0f, 0.1f, 0.1f } }, // Dry signal amount { "attack", { "Attack", 0.0f, 2.0f, 0.001f, 0.01f } },
{ "width", { "Width", 0.0f, 1.0f, 0.1f, 0.1f } }, // Stereo width { "decay", { "Decay", 0.0f, 2.0f, 0.001f, 0.10f } },
{ "freezeMode", { "Freeze Mode", 0.0f, 1.0f, 0.1f, 0.1f } } // Infinite decay toggle { "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 } }
{ "adsr", { }},
{ "attack", { "Attack", 0.0f, 1.0f, 0.1f, 0.1f } }, // Attack time { "flanger", {
{ "decay", { "Decay", 0.0f, 1.0f, 0.1f, 0.1f } }, // Decay time { "rate", { "Rate", 0.1f, 5.0f, 0.1f, 0.1f } },
{ "sustain", { "Sustain", 0.0f, 1.0f, 0.1f, 0.1f } }, // Sustain level { "depth", { "Depth", 0.1f, 10.0f, 0.1f, 0.1f } }, // ms
{ "release", { "Release", 0.0f, 1.0f, 0.1f, 0.1f } } // Release time { "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 } },
{ "flanger", { { "delay", { "Delay", 0.0f, 3.0f, 0.1f, 0.25f } } // ms base
{ "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 { "filter", {
{ "feedback", { "Feedback", 0.0f, 1.0f, 0.1f, 0.1f } }, // Feedback amount { "cutoff", { "Cutoff", 20.0f, 20000.0f, 1.0f, 1000.0f } },
{ "dryMix", { "Dry/Wet", 0.0f, 1.0f, 0.1f, 0.1f } }, // Mix control { "resonance", { "Resonance", 0.1f, 10.0f, 0.1f, 0.7f } },
{ "phase", { "Phase", 0.0f, 1.0f, 0.1f, 0.1f } }, // LFO phase offset (for stereo) { "type", { "L/H/B", 0.0f, 2.0f, 1.0f, 0.0f } },
{ "delay", { "Delay", 0.0f, 3.0f, 0.1f, 0.1f } } // Base delay offset { "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 } }
{ "filter", { }},
{ "cutoff", { "Cutoff", 0.2f, 20000.0f, 1.0f, 1000.0f } }, // Frequency cutoff { "distortion", {
{ "resonance", { "Resonance", 0.1f, 10.0f, 0.1f, 0.2f } }, // Resonance/Q factor { "drive", { "Drive", 0.0f, 30.0f, 0.1f, 10.0f } },
{ "type", { "L/H/B", 0.0f, 2.0f, 1.0f, 0.0f } }, // 0 = LPF, 1 = HPF, 2 = BPF { "mix", { "Mix", 0.0f, 1.0f, 0.01f, 0.0f } },
{ "drive", { "Drive", 0.0f, 1.0f, 0.01f, 0.0f } }, // Pre-gain into filter { "bias", { "Bias", -1.0f, 1.0f, 0.01f, 0.0f } },
{ "mod", { "Mod", -1.0f, 1.0f, 0.1f, 0.0f } }, // Modulation amount { "tone", { "Tone", 100.0f, 8000.0f, 10.0f, 3000.0f } },
{ "key", { "Key", 0.0f, 1.0f, 0.1f, 0.0f } } // Key tracking { "shape", { "Shape", 0.0f, 2.0f, 1.0f, 0.0f } }
}}, }}
};
{ "distortion", {
{ "drive", { "Drive", 0.0f, 30.0f, 0.1f, 10.0f } }, // Input gain before shaping struct NeuralSharedParams
{ "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 std::atomic<int> waveform{ -1 };
{ "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 // Amp ADSR
}} std::atomic<float>* adsrAttack{};
std::atomic<float>* adsrDecay{};
}; std::atomic<float>* adsrSustain{};
std::atomic<float>* adsrRelease{};
struct NeuralSharedParams
{ // Delay
std::atomic<int> waveform{ -1 }; std::atomic<float>* delayTime{};
std::atomic<float>* adsrAttack; // Chorus
std::atomic<float>* adsrDecay; std::atomic<float>* chorusRate{};
std::atomic<float>* adsrSustain; std::atomic<float>* chorusDepth{};
std::atomic<float>* adsrRelease; std::atomic<float>* chorusCentre{};
std::atomic<float>* chorusFeedback{};
std::atomic<float>* delayTime; std::atomic<float>* chorusMix{};
std::atomic<float>* chorusRate; // Reverb
std::atomic<float>* chorusDepth; std::atomic<float>* reverbRoomSize{};
std::atomic<float>* chorusCentre; std::atomic<float>* reverbDamping{};
std::atomic<float>* chorusFeedback; std::atomic<float>* reverbWetLevel{};
std::atomic<float>* chorusMix; std::atomic<float>* reverbDryLevel{};
std::atomic<float>* reverbWidth{};
std::atomic<float>* reverbRoomSize; std::atomic<float>* reverbFreezeMode{};
std::atomic<float>* reverbDamping;
std::atomic<float>* reverbWetLevel; // Flanger
std::atomic<float>* reverbDryLevel; std::atomic<float>* flangerRate{};
std::atomic<float>* reverbWidth; std::atomic<float>* flangerDepth{};
std::atomic<float>* reverbFreezeMode; std::atomic<float>* flangerFeedback{};
std::atomic<float>* flangerDryMix{};
std::atomic<float>* flangerRate; std::atomic<float>* flangerPhase{};
std::atomic<float>* flangerDepth; std::atomic<float>* flangerDelay{};
std::atomic<float>* flangerFeedback;
std::atomic<float>* flangerDryMix; // Filter (base)
std::atomic<float>* flangerPhase; std::atomic<float>* filterCutoff{};
std::atomic<float>* flangerDelay; std::atomic<float>* filterResonance{};
std::atomic<float>* filterType{};
std::atomic<float>* filterCutoff; std::atomic<float>* filterDrive{};
std::atomic<float>* filterResonance; std::atomic<float>* filterMod{};
std::atomic<float>* filterType; std::atomic<float>* filterKey{};
std::atomic<float>* filterDrive;
std::atomic<float>* filterMod; // Filter Env (polyphonic)
std::atomic<float>* filterKey; std::atomic<float>* fenvAttack{};
std::atomic<float>* fenvDecay{};
std::atomic<float>* distortionDrive; std::atomic<float>* fenvSustain{};
std::atomic<float>* distortionMix; std::atomic<float>* fenvRelease{};
std::atomic<float>* distortionBias; std::atomic<float>* fenvAmount{}; // +/- octaves
std::atomic<float>* distortionTone;
std::atomic<float>* distortionShape; // Distortion
std::atomic<float>* distortionDrive{};
std::atomic<float>* lowGainDbls; std::atomic<float>* distortionMix{};
std::atomic<float>* midGainDbls; std::atomic<float>* distortionBias{};
std::atomic<float>* highGainDbls; std::atomic<float>* distortionTone{};
std::atomic<float>* distortionShape{};
std::atomic<float>* masterDbls;
}; // 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{};
};