Upload files to "DrawWavesAndRevisedAudio"
This commit is contained in:
143
DrawWavesAndRevisedAudio/PluginProcessor.h
Normal file
143
DrawWavesAndRevisedAudio/PluginProcessor.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <complex>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <atomic>
|
||||
|
||||
// ============================================================
|
||||
// A wave frame: 2048 samples with six mip levels (0 = full bandwidth)
|
||||
struct WavetableFrame
|
||||
{
|
||||
std::array<std::vector<float>, 6> mip;
|
||||
};
|
||||
|
||||
// A complete morph set contains 16 frames
|
||||
struct WaveMorph
|
||||
{
|
||||
std::array<WavetableFrame, 16> frames;
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
|
||||
class WavetableSynthAudioProcessor : public juce::AudioProcessor
|
||||
{
|
||||
public:
|
||||
// -------- engine configuration ----------
|
||||
static constexpr int kBrowserCols = 4;
|
||||
static constexpr int kBrowserRows = 10;
|
||||
static constexpr int kBrowserCapacity = kBrowserCols * kBrowserRows; // 40
|
||||
static constexpr int kFactorySlots = 20; // first 20 fixed
|
||||
static constexpr int kMorphFrames = 16;
|
||||
static constexpr int kMipLevels = 6;
|
||||
static constexpr int kTableSize = 2048;
|
||||
|
||||
// --- minimal editor accessors (public) -------------------------------------
|
||||
int getBrowserCols() const noexcept { return kBrowserCols; }
|
||||
int getBrowserRows() const noexcept { return kBrowserRows; }
|
||||
int getWaveTableCount() const noexcept { return (int) waves.size(); }
|
||||
const std::vector<float>* getWaveTablePtr (int index) const noexcept
|
||||
{
|
||||
// Preview uses the first frame at the widest mip level.
|
||||
return (index >= 0 && index < (int) waves.size())
|
||||
? &waves[(size_t) index].frames[0].mip[0] : nullptr;
|
||||
}
|
||||
|
||||
// -------- juce plumbing ----------
|
||||
WavetableSynthAudioProcessor();
|
||||
~WavetableSynthAudioProcessor() override = default;
|
||||
|
||||
// AudioProcessor
|
||||
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
|
||||
void releaseResources() override {}
|
||||
void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
|
||||
|
||||
// Editor
|
||||
juce::AudioProcessorEditor* createEditor() override;
|
||||
bool hasEditor() const override { return true; }
|
||||
|
||||
// Meta
|
||||
const juce::String getName() const override { return "WavetableSynth"; }
|
||||
bool acceptsMidi() const override { return true; }
|
||||
bool producesMidi() const override { return false; }
|
||||
bool isMidiEffect() const override { return false; }
|
||||
double getTailLengthSeconds() const override { return 0.0; }
|
||||
|
||||
// Programs (unused)
|
||||
int getNumPrograms() override { return 1; }
|
||||
int getCurrentProgram() override { return 0; }
|
||||
void setCurrentProgram (int) override {}
|
||||
const juce::String getProgramName (int) override { return {}; }
|
||||
void changeProgramName (int, const juce::String&) override {}
|
||||
|
||||
// State
|
||||
void getStateInformation (juce::MemoryBlock& destData) override;
|
||||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
// Parameters
|
||||
juce::AudioProcessorValueTreeState apvts;
|
||||
static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout();
|
||||
|
||||
// -------- public data used by editor ----------
|
||||
std::vector<WaveMorph> waves; // size <= 40; first 20 are factory
|
||||
int defaultTableCount { kFactorySlots };
|
||||
int nextUserInsert { 0 }; // round-robin inside user region
|
||||
|
||||
// For the editor thumbnails (take the widest-band level 0)
|
||||
const std::vector<float>* getPreviewTablePtr (int index) const;
|
||||
|
||||
// API for editor to push user waves (single cycle, any shape)
|
||||
// Internally this builds a mip set by partial truncation.
|
||||
int addOrReplaceUserWavetable (const std::vector<float>& singleCycle01);
|
||||
void notifyPresetLoaded();
|
||||
float getMorphDisplayValue() const noexcept { return morphDisplay.load (std::memory_order_relaxed); }
|
||||
bool isMorphLoopActive() const noexcept;
|
||||
|
||||
private:
|
||||
// ---------- synthesis core ----------
|
||||
juce::Synthesiser synth;
|
||||
std::vector<float> morphBuffer;
|
||||
float morphState { 0.0f };
|
||||
float morphLoopPhase { 0.0f };
|
||||
int morphLoopDirection { 1 };
|
||||
int morphLoopStage { 0 };
|
||||
float morphLoopStagePhase { 0.0f };
|
||||
std::atomic<float> morphDisplay { 0.0f };
|
||||
juce::LinearSmoothedValue<float> presetFade { 1.0f };
|
||||
|
||||
juce::dsp::Chorus<float> chorus;
|
||||
juce::dsp::Reverb reverb;
|
||||
juce::dsp::Reverb::Parameters reverbParams;
|
||||
|
||||
// -------- wave construction helpers ----------
|
||||
static void normalize (std::vector<float>& t);
|
||||
static void addSine (std::vector<float>& t, int harmonic, float amp);
|
||||
static void removeDC (std::vector<float>& t);
|
||||
static void enforceZeroStart (std::vector<float>& t);
|
||||
static WaveMorph buildAdditiveMorph (std::function<float(int)> ampFn,
|
||||
bool oddOnly = false,
|
||||
float phaseAlt = +1.0f);
|
||||
static WaveMorph makeSine();
|
||||
static WaveMorph makeSaw();
|
||||
static WaveMorph makeSquare();
|
||||
static WaveMorph makeTriangle();
|
||||
static WaveMorph makePulse (float duty); // 0<d<1
|
||||
static WaveMorph makeEven();
|
||||
static WaveMorph makeOdd();
|
||||
static WaveMorph makeHalfSineRect();
|
||||
static WaveMorph makeBell();
|
||||
static WaveMorph makeOrgan();
|
||||
void buildFactoryWaves();
|
||||
|
||||
// choose mip level for a given fundamental
|
||||
int chooseMipLevel (float fundamentalHz) const;
|
||||
|
||||
const WaveMorph* getWavePtr (int index) const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavetableSynthAudioProcessor)
|
||||
|
||||
friend class WavetableVoice;
|
||||
};
|
||||
Reference in New Issue
Block a user