Upload files to "DrawWavesAndRevisedAudio"

This commit is contained in:
ed
2025-10-26 10:35:08 +00:00
parent b2b4633005
commit 17259cc569
3 changed files with 1781 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
#pragma once
#include <JuceHeader.h>
#include <functional>
#include "PluginProcessor.h"
// === Small waveform thumbnail =================================================
class WaveThumbnail : public juce::Component
{
public:
WaveThumbnail (const std::vector<float>* tbl = nullptr) : table (tbl) {}
void setTable (const std::vector<float>* tbl) { table = tbl; repaint(); }
void setHighlight (bool shouldHighlight)
{
if (highlight == shouldHighlight) return;
highlight = shouldHighlight;
repaint();
}
void setOnClick (std::function<void()> handler) { onClick = std::move (handler); }
void paint (juce::Graphics& g) override;
void mouseDown (const juce::MouseEvent& e) override
{
juce::ignoreUnused (e);
if (onClick) onClick();
}
private:
const std::vector<float>* table { nullptr };
bool highlight { false };
std::function<void()> onClick;
};
// === Draw-your-own wave pad ===================================================
// (Grid + thicker antialiased stroke + smooth “ink” interpolation while dragging)
class DrawWaveComponent : public juce::Component
{
public:
DrawWaveComponent();
void clear();
void paint (juce::Graphics& g) override;
void mouseDown (const juce::MouseEvent& e) override;
void mouseDrag (const juce::MouseEvent& e) override;
const std::vector<float>& getTable() const { return samples; }
private:
void drawAt (const juce::MouseEvent& e);
void setSampleAt (int idx, float value);
std::vector<float> samples;
int lastDrawIndex { -1 };
};
// === Custom looks =============================================================
class MetalKnobLookAndFeel : public juce::LookAndFeel_V4
{
public:
void drawRotarySlider (juce::Graphics& g, int x, int y, int width, int height,
float sliderPosProportional, float rotaryStartAngle,
float rotaryEndAngle, juce::Slider& slider) override;
};
class FlatButtonLookAndFeel : public juce::LookAndFeel_V4
{
public:
void drawButtonBackground (juce::Graphics& g, juce::Button& b, const juce::Colour& bg,
bool isHighlighted, bool isDown) override
{
auto r = b.getLocalBounds().toFloat();
auto base = bg; if (isDown) base = base.darker (0.15f); else if (isHighlighted) base = base.brighter (0.08f);
g.setColour (base);
g.fillRoundedRectangle (r, 4.0f);
g.setColour (juce::Colours::black.withAlpha (0.5f));
g.drawRoundedRectangle (r.reduced (0.5f), 4.0f, 1.0f);
}
};
// === Editor ===================================================================
class WavetableSynthAudioProcessorEditor : public juce::AudioProcessorEditor,
private juce::Timer
{
public:
explicit WavetableSynthAudioProcessorEditor (WavetableSynthAudioProcessor&);
~WavetableSynthAudioProcessorEditor() override = default;
void paint (juce::Graphics&) override;
void resized() override;
void mouseDown (const juce::MouseEvent& e) override;
private:
WavetableSynthAudioProcessor& audioProcessor;
// Morph
juce::Slider morphSlider;
juce::ToggleButton morphLoopToggle { "Loop Morph" };
juce::ComboBox morphLoopMode; // Forward / Ping-Pong / Half Trip
// Master
juce::Slider master;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> morphAttach, masterAttach;
// A/B/C thumbnails
WaveThumbnail slotABox, slotBBox, slotCBox;
// Synth knobs
juce::Slider cutoffSlider, attack, decay, sustain, release;
juce::Slider lfoRate, lfoDepth, fenvA, fenvD, fenvS, fenvR, fenvAmt;
// FX knobs
juce::Slider chRate, chDepth, chDelay, chFb, chMix;
juce::Slider rvRoom, rvDamp, rvWidth, rvWet;
// Attachments
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>
cutoffAttach, attAttach, decAttach, susAttach, relAttach,
lfoRateAttach, lfoDepthAttach, fenvAAttach, fenvDAttach, fenvSAttach, fenvRAttach, fenvAmtAttach,
chRateAttach, chDepthAttach, chDelayAttach, chFbAttach, chMixAttach,
rvRoomAttach, rvDampAttach, rvWidthAttach, rvWetAttach;
// Hidden slot params
juce::Slider slotAParam, slotBParam, slotCParam;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>
slotAAttach, slotBAttach, slotCAttach;
// Toggles
juce::ToggleButton chorusOn { "Chorus" }, reverbOn { "Reverb" }, osc2Mute { "Deactivate Osc2" };
std::unique_ptr<juce::AudioProcessorValueTreeState::ButtonAttachment> chOnAttach, rvOnAttach, osc2MuteAttach;
std::unique_ptr<juce::AudioProcessorValueTreeState::ButtonAttachment> morphLoopToggleAttach;
std::unique_ptr<juce::AudioProcessorValueTreeState::ComboBoxAttachment> morphLoopModeAttach;
// Browser grid cells
std::vector<juce::Rectangle<int>> browserCells; // 4 x 10 = 40
// Draw pad + buttons
DrawWaveComponent userDraw;
juce::TextButton addToBrowser { "Add to Browser" }, clearDraw { "Clear" }, presetButton { "Presets" };
// Labels
juce::Label lblCutoff, lblAttack, lblDecay, lblSustain, lblRelease;
juce::Label lblLfoRate, lblLfoDepth, lblFenvA, lblFenvD, lblFenvS, lblFenvR, lblFenvAmt;
juce::Label lblChRate, lblChDepth, lblChDelay, lblChFb, lblChMix;
juce::Label lblRvRoom, lblRvDamp, lblRvWidth, lblRvWet;
juce::Label lblMaster, lblDrawWave;
// L&F
MetalKnobLookAndFeel metalKnobLNF;
FlatButtonLookAndFeel flatBtnLNF;
// Layout helpers
juce::Rectangle<int> getTopPanelBounds() const;
juce::Rectangle<int> getBottomPanelBounds() const;
// Logic
void timerCallback() override;
void handleBrowserClick (juce::Point<int> pos);
void showPresetMenu();
void setActiveSlot (int slotIndex);
// Helpers
static void labelAbove (juce::Label& L, const juce::String& text);
int activeSlot { 0 };
// Local morph animation (fallback)
double lastTimerMs { juce::Time::getMillisecondCounterHiRes() };
float localMorphPhase { 0.0f }; // 0..1
};