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:
45
Source/Grain.h
Normal file
45
Source/Grain.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <JuceHeader.h>
|
||||
|
||||
// ============================================================
|
||||
// Hann window lookup table (1024 points, computed once)
|
||||
// ============================================================
|
||||
struct GrainWindow
|
||||
{
|
||||
static constexpr int tableSize = 1024;
|
||||
float table[tableSize];
|
||||
|
||||
GrainWindow()
|
||||
{
|
||||
for (int i = 0; i < tableSize; ++i)
|
||||
{
|
||||
float phase = (float) i / (float) (tableSize - 1);
|
||||
table[i] = 0.5f * (1.0f - std::cos (juce::MathConstants<float>::twoPi * phase));
|
||||
}
|
||||
}
|
||||
|
||||
float getValue (float phase) const
|
||||
{
|
||||
float index = juce::jlimit (0.0f, 1.0f, phase) * (float) (tableSize - 1);
|
||||
int i0 = (int) index;
|
||||
int i1 = std::min (i0 + 1, tableSize - 1);
|
||||
float frac = index - (float) i0;
|
||||
return table[i0] + frac * (table[i1] - table[i0]);
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// Single grain
|
||||
// ============================================================
|
||||
struct Grain
|
||||
{
|
||||
int startSample = 0; // where in source buffer
|
||||
int lengthSamples = 0; // grain duration in samples
|
||||
float pitchRatio = 1.0f; // playback speed
|
||||
double readPosition = 0.0; // current fractional read position
|
||||
int samplesElapsed = 0; // output samples generated
|
||||
float panPosition = 0.0f; // -1 left, +1 right
|
||||
float volume = 1.0f;
|
||||
bool reverse = false;
|
||||
bool active = false;
|
||||
};
|
||||
Reference in New Issue
Block a user