Skip to main content

PolyPatch

Struct PolyPatch 

Source
pub struct PolyPatch { /* private fields */ }
Expand description

Polyphonic patch container.

Owns one voice graph per allocator voice (multiplied by the unison count), each fed by an in-graph VoiceInput controller. On every tick, it:

  1. writes each active voice’s allocator state into its controller handle(s),
  2. ticks each voice graph exactly once and mixes the results (with unison detune/balance and equal-power unison gain),
  3. follows each voice’s real output level and reports it to the allocator so release tails complete before the voice is freed,
  4. applies smoothed polyphony gain compensation (1/sqrt(N)).

PolyPatch::tick performs no heap allocation in steady state; all allocation happens at construction / reconfiguration time.

Implementations§

Source§

impl PolyPatch

Source

pub fn new(num_voices: usize, sample_rate: f64) -> Self

Create a new polyphonic patch whose voice graphs contain only the voice controller (no DSP). Use with_voice_fn to build real voices; this bare constructor is mostly useful for benchmarking the allocation/mixing machinery.

Source

pub fn with_voice_fn<F>( num_voices: usize, sample_rate: f64, builder: F, ) -> Result<Self, PatchError>
where F: Fn(&mut Patch, &NodeHandle) -> Result<(), PatchError> + 'static,

Create a polyphonic patch, building each voice graph with builder.

The builder is invoked once per voice (and once per unison sub-voice), each time receiving a fresh patch pre-populated with a voice controller and a NodeHandle to it. Wire the controller’s voct/gate/trigger/ velocity outputs into your DSP and call patch.set_output(..).

Source

pub fn set_max_release_time(&mut self, seconds: f64)

Set the worst-case time (seconds) a released voice may keep sounding before the allocator force-frees it, bounding voice lifetime so a non-decaying (drone / self-oscillating) voice cannot permanently pin a slot. A non-positive or non-finite value disables the cap.

Source

pub fn sample_rate(&self) -> f64

Get the sample rate

Source

pub fn num_voices(&self) -> usize

Number of allocator voices.

Source

pub fn set_sample_rate(&mut self, sample_rate: f64)

Set the sample rate and rebuild every voice graph at the new rate.

Rebuilding re-runs the voice builder so all modules (and the controller’s trigger-pulse length, the amplitude follower, and the release grace) pick up the new sample rate (Q069). Voice DSP state is reset as a result, which is acceptable for a sample-rate change.

Source

pub fn voice_control(&self, index: usize) -> Option<&Arc<VoiceControl>>

The shared control handle for a voice’s first sub-voice, if any.

Source

pub fn voice_controller(&self, index: usize) -> Option<&NodeHandle>

A NodeHandle to a voice’s controller node (first sub-voice), so the controller ports can be referenced after construction.

Source

pub fn allocator(&self) -> &VoiceAllocator

Get the voice allocator

Source

pub fn allocator_mut(&mut self) -> &mut VoiceAllocator

Get mutable access to the voice allocator

Source

pub fn set_unison(&mut self, config: UnisonConfig)

Set unison configuration. Changing the unison voice count rebuilds the voice graphs; changing only detune/spread takes effect immediately without a rebuild.

Source

pub fn unison(&self) -> &UnisonConfig

Get unison configuration

Source

pub fn voice_patch(&self, index: usize) -> Option<&Patch>

Get a voice’s (first sub-voice) patch for inspection.

Source

pub fn voice_patch_mut(&mut self, index: usize) -> Option<&mut Patch>

Get a voice’s (first sub-voice) patch mutably.

Source

pub fn note_on(&mut self, note: u8, velocity: u8)

Handle MIDI note on. When the allocation stole a sounding voice, the stolen voice’s DSP is reset to prevent the previous note’s tail from bleeding into the new note (Q070). Fresh (free) allocations are not reset, preserving oscillator phase continuity for an analog feel.

Source

pub fn note_off(&mut self, note: u8)

Handle MIDI note off

Source

pub fn all_notes_off(&mut self)

All notes off

Source

pub fn panic(&mut self)

Panic - immediately silence all voices

Source

pub fn compile(&mut self) -> Result<(), PatchError>

Compile all voice graphs.

Source

pub fn compensation_gain(&self) -> f64

The current polyphony gain-compensation factor (1/sqrt(N) with the voice count N smoothed). Exposed mainly for testing that the factor moves smoothly rather than stepping.

Source

pub fn tick(&mut self) -> (f64, f64)

Process one sample and return stereo output.

Source

pub fn output(&self) -> (f64, f64)

Get the last output

Source

pub fn reset(&mut self)

Reset all voice graphs and allocator state.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.