Initial release — InstaGrain granular synthesizer v1.0
8-voice polyphonic granular synth (VST3/AU/LV2) with: - 128 grain pool per voice, Hann windowing, linear interpolation - Root note selector, sample rate correction, sustain pedal (CC64) - Scatter controls, direction modes (Fwd/Rev/PingPong), freeze - ADSR envelope, global filter (LP/HP/BP), reverb - Waveform display with grain visualization - Drag & drop sample loading, full state save/restore - CI/CD for Windows/macOS/Linux Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
Source/GrainCloud.h
Normal file
52
Source/GrainCloud.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <JuceHeader.h>
|
||||
#include "Grain.h"
|
||||
|
||||
class GrainCloud
|
||||
{
|
||||
public:
|
||||
static constexpr int maxGrains = 128;
|
||||
|
||||
enum class Direction { Forward, Reverse, PingPong };
|
||||
|
||||
GrainCloud();
|
||||
|
||||
void prepare (double sampleRate);
|
||||
void processBlock (juce::AudioBuffer<float>& output, int numSamples,
|
||||
const juce::AudioBuffer<float>& sourceBuffer);
|
||||
void reset();
|
||||
|
||||
// Parameters (atomic — GUI writes, audio reads)
|
||||
std::atomic<float> position { 0.5f }; // 0-1
|
||||
std::atomic<float> grainSizeMs { 100.0f }; // 10-500
|
||||
std::atomic<float> density { 10.0f }; // 1-100 grains/sec
|
||||
std::atomic<float> pitchSemitones { 0.0f }; // -24..+24
|
||||
std::atomic<float> pan { 0.0f }; // -1..+1
|
||||
std::atomic<float> posScatter { 0.0f }; // 0-1
|
||||
std::atomic<float> sizeScatter { 0.0f }; // 0-1
|
||||
std::atomic<float> pitchScatter { 0.0f }; // 0-1
|
||||
std::atomic<float> panScatter { 0.0f }; // 0-1
|
||||
std::atomic<int> direction { 0 }; // 0=Fwd, 1=Rev, 2=PingPong
|
||||
std::atomic<bool> freeze { false };
|
||||
|
||||
// Extra pitch offset from MIDI note
|
||||
float midiPitchOffset = 0.0f;
|
||||
|
||||
// Sample rate correction: sourceSampleRate / dawSampleRate
|
||||
float sampleRateRatio = 1.0f;
|
||||
|
||||
// For visualization — snapshot of active grains
|
||||
struct GrainInfo { int startSample; int lengthSamples; float progress; };
|
||||
std::array<GrainInfo, maxGrains> getActiveGrainInfo() const;
|
||||
int getActiveGrainCount() const;
|
||||
|
||||
private:
|
||||
double currentSampleRate = 44100.0;
|
||||
std::array<Grain, maxGrains> grains;
|
||||
GrainWindow window;
|
||||
int samplesUntilNextGrain = 0;
|
||||
juce::Random rng;
|
||||
|
||||
void spawnGrain (const juce::AudioBuffer<float>& sourceBuffer);
|
||||
float readSampleInterpolated (const juce::AudioBuffer<float>& buffer, double position) const;
|
||||
};
|
||||
Reference in New Issue
Block a user