Class PAGranularVoice

java.lang.Object
net.paulhertz.pixelaudio.granular.PAGranularVoice

public class PAGranularVoice extends Object
Single voice for rendering one granular PASource.

PAGranularVoice is the voice layer in PixelAudio's granular synthesis chain. A PAGranularSampler activates voices with a source, macro envelope, gain, pan, looping flag, and optional grain-window settings. The voice then pulls audio from its PASource, applies the macro envelope and voice-level pan/gain, and returns one sample frame at a time to the sampler.

The voice renders internally in blocks. When the sampler asks for the next stereo sample, the voice reads from cached block buffers; when those buffers are exhausted, it asks the source to render the next block. This keeps source rendering block-oriented while allowing the sampler to mix voices one frame at a time inside Minim's UGen callback.

The envelope used here is a macro envelope over the whole voice. Individual grains may still have their own source-level windows, supplied through WindowFunction and handled by the source.

See Also:
  • Field Details

    • NEXT_VOICE_ID

      private static long NEXT_VOICE_ID
    • source

      private PASource source
      Granular source: a PABurstGranularSource, in the current design using @link PAGranularInstrumentDirector}
    • blockSize

      private final int blockSize
    • voiceId

      private long voiceId
    • active

      private boolean active
    • released

      private boolean released
    • finished

      private boolean finished
    • gain

      private float gain
    • pan

      private float pan
    • looping

      private boolean looping
    • playbackSampleRate

      private float playbackSampleRate
    • blockL

      private final float[] blockL
    • blockR

      private final float[] blockR
    • cursor

      private int cursor
    • absSample

      private long absSample
    • envelope

      private SimpleADSR envelope
    • defaultEnvParams

      ADSRParams defaultEnvParams
    • panGainL

      private float panGainL
    • panGainR

      private float panGainR
    • grainWindow

      private ddf.minim.analysis.WindowFunction grainWindow
      granular window function, may be null, in which case defaults apply
    • grainLenSamples

      private int grainLenSamples
    • endTriggered

      private boolean endTriggered
  • Constructor Details

    • PAGranularVoice

      public PAGranularVoice(PASource source, int blockSize, float playbackSampleRate)
      Creates an inactive granular voice.
      Parameters:
      source - initial source for the voice; may be replaced during activation
      blockSize - internal render-block size
      playbackSampleRate - sample rate used by the voice envelope
  • Method Details

    • setSource

      public void setSource(PASource source)
    • activate

      public void activate(PASource source, ADSRParams envParams, float gain, float pan, boolean looping)
      Activates this voice with no external grain-window override.
      Parameters:
      source - source to render
      envParams - macro envelope parameters, or null to use the voice default
      gain - voice gain
      pan - stereo pan in the range [-1, 1]
      looping - true to loop the source path when the source length is reached
    • activate

      public void activate(PASource source, ADSRParams envParams, float gain, float pan, boolean looping, ddf.minim.analysis.WindowFunction grainWindow, int grainLenSamples)
      Activates this voice with a source and playback settings.

      Activation resets voice state, assigns a new voice id, initializes pan gains, rewinds the source with PASource.seekTo(long), optionally pushes grain-window settings into the source, and starts a fresh macro envelope.

      Parameters:
      source - source to render
      envParams - macro envelope parameters, or null to use the voice default
      gain - voice gain
      pan - stereo pan in the range [-1, 1]
      looping - true to loop the source path when the source length is reached
      grainWindow - optional grain window to pass to the source
      grainLenSamples - grain length associated with grainWindow
    • nextSampleStereo

      public void nextSampleStereo(float[] outLR)
      Writes the next stereo sample frame from this voice.

      If the voice is inactive or finished, both output samples are set to 0. Otherwise this method refills the internal block when needed, reads the next cached source sample, advances the macro envelope, applies voice gain and equal-power pan, and writes left and right samples into outLR.

      Parameters:
      outLR - two-element array receiving left and right sample values
    • nextSample

      public float nextSample()
      Returns the next mono sample from this voice.

      This method mirrors nextSampleStereo(float[]) but folds the panned stereo block sample to mono. It is retained for future mono-output use.

      Returns:
      next mono sample, or 0 if the voice is inactive or finished
    • refillBlock

      private void refillBlock()
      Refills the internal stereo block buffers from the source.

      The voice asks its PASource to render the block beginning at absSample, then advances absSample by blockSize. If looping is enabled and the source span has ended, the voice rewinds the source and starts again. If looping is disabled and the source span has ended, the voice triggers envelope release or stops immediately when no envelope is available.

    • updatePanGains

      private void updatePanGains()
    • release

      public void release()
      Starts the macro envelope release stage for this voice.

      Release is less abrupt than stop() because the voice remains active until its envelope finishes.

    • stop

      public void stop()
      Immediately marks this voice inactive and finished.

      Unlike release(), this bypasses the envelope release stage.

    • isActive

      public boolean isActive()
    • isReleasing

      public boolean isReleasing()
    • isFinished

      public boolean isFinished()
    • getVoiceId

      public long getVoiceId()
    • getPan

      public float getPan()
    • clampPan

      private static float clampPan(float p)