#pragma once #include #include "GrainCloud.h" class GrainVoice { public: GrainVoice(); void prepare (double sampleRate); void noteOn (int midiNote, float velocity); void noteOff(); void forceStop(); void processBlock (juce::AudioBuffer& output, int numSamples, const juce::AudioBuffer& sourceBuffer); bool isActive() const { return voiceActive; } int getCurrentNote() const { return currentNote; } GrainCloud& getCloud() { return cloud; } const GrainCloud& getCloud() const { return cloud; } // ADSR parameters (set from processor) // Root note reference (set from engine) std::atomic rootNote { 60 }; // ADSR parameters (set from processor) std::atomic attackTime { 0.01f }; std::atomic decayTime { 0.1f }; std::atomic sustainLevel { 1.0f }; std::atomic releaseTime { 0.3f }; private: GrainCloud cloud; juce::ADSR adsr; juce::ADSR::Parameters adsrParams; float velocityGain = 1.0f; int currentNote = -1; bool voiceActive = false; double currentSampleRate = 44100.0; };