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:
- writes each active voice’s allocator state into its controller handle(s),
- ticks each voice graph exactly once and mixes the results (with unison detune/balance and equal-power unison gain),
- follows each voice’s real output level and reports it to the allocator so release tails complete before the voice is freed,
- 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
impl PolyPatch
Sourcepub fn new(num_voices: usize, sample_rate: f64) -> Self
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.
Sourcepub fn with_voice_fn<F>(
num_voices: usize,
sample_rate: f64,
builder: F,
) -> Result<Self, PatchError>
pub fn with_voice_fn<F>( num_voices: usize, sample_rate: f64, builder: F, ) -> Result<Self, PatchError>
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(..).
Sourcepub fn set_max_release_time(&mut self, seconds: f64)
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.
Sourcepub fn sample_rate(&self) -> f64
pub fn sample_rate(&self) -> f64
Get the sample rate
Sourcepub fn num_voices(&self) -> usize
pub fn num_voices(&self) -> usize
Number of allocator voices.
Sourcepub fn set_sample_rate(&mut self, sample_rate: f64)
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.
Sourcepub fn voice_control(&self, index: usize) -> Option<&Arc<VoiceControl>>
pub fn voice_control(&self, index: usize) -> Option<&Arc<VoiceControl>>
The shared control handle for a voice’s first sub-voice, if any.
Sourcepub fn voice_controller(&self, index: usize) -> Option<&NodeHandle>
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.
Sourcepub fn allocator(&self) -> &VoiceAllocator
pub fn allocator(&self) -> &VoiceAllocator
Get the voice allocator
Sourcepub fn allocator_mut(&mut self) -> &mut VoiceAllocator
pub fn allocator_mut(&mut self) -> &mut VoiceAllocator
Get mutable access to the voice allocator
Sourcepub fn set_unison(&mut self, config: UnisonConfig)
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.
Sourcepub fn unison(&self) -> &UnisonConfig
pub fn unison(&self) -> &UnisonConfig
Get unison configuration
Sourcepub fn voice_patch(&self, index: usize) -> Option<&Patch>
pub fn voice_patch(&self, index: usize) -> Option<&Patch>
Get a voice’s (first sub-voice) patch for inspection.
Sourcepub fn voice_patch_mut(&mut self, index: usize) -> Option<&mut Patch>
pub fn voice_patch_mut(&mut self, index: usize) -> Option<&mut Patch>
Get a voice’s (first sub-voice) patch mutably.
Sourcepub fn note_on(&mut self, note: u8, velocity: u8)
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.
Sourcepub fn all_notes_off(&mut self)
pub fn all_notes_off(&mut self)
All notes off
Sourcepub fn compile(&mut self) -> Result<(), PatchError>
pub fn compile(&mut self) -> Result<(), PatchError>
Compile all voice graphs.
Sourcepub fn compensation_gain(&self) -> f64
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.