Skip to main content

LivePoly

Struct LivePoly 

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

A polyphonic live instrument over one patch.

Implementations§

Source§

impl LivePoly

Source

pub fn new( tree_json: &str, sample_rate: f64, n_voices: usize, ) -> Result<LivePoly, JsValue>

Build an n_voices-voice instrument from a PatchTree JSON.

Source

pub fn set_meter(&mut self, on: bool) -> usize

Turn interior metering on or off.

On, every module in the patch gets a Level subscription and Self::meter_ptr carries its RMS in dB; off, nothing is subscribed and the render loop does no metering work at all. Returns the number of taps, which is the length of both Self::meter_keys and the level buffer.

Nothing here needs sync_output_keepalive. That call pins ports with no consumer so a module implementing tick_masked still produces them, and it dirties the patch — a recompile that would have to be staged around the audio thread the way patch swaps are. It is not needed because the genome is a typed tree: every module’s output feeds exactly one parent, so quiver is already computing every value metered here. Metering costs no recompile and cannot glitch the audio.

Source

pub fn meter_keys(&self) -> String

The term keys the level buffer is indexed by, as a JSON array.

Read once after Self::set_meter rather than per quantum — this allocates, and the order is fixed until the next patch swap.

Source

pub fn meter_ptr(&self) -> *const f32

Pointer to the RMS dB per tap, in Self::meter_keys order.

The same zero-allocation contract as Self::process_ptr: a view into wasm memory, overwritten in place, valid until the next patch swap resizes it. A tap that has not filled a buffer yet reads f32::NEG_INFINITY — silence, not zero dB.

Source

pub fn meter_len(&self) -> usize

How many taps Self::meter_ptr holds.

Source

pub fn set_patch(&mut self, tree_json: &str) -> bool

Queue a patch swap. Parses eagerly (false = bad JSON, nothing changes); the actual voice rebuild is amortized over the next few silent quanta. Held notes are re-pressed on the new patch.

Source

pub fn poll_event(&mut self) -> u32

Poll the latest swap event (0 = none, 1 = patched, 2 = error). Clears on read.

Source

pub fn last_error(&self) -> String

The message of the last patch error.

Source

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

Press a MIDI note (60 = C4) with velocity 0..1. Retriggers if already held; otherwise takes a parked voice, else steals the oldest. With the arp on, the note joins the held set and the arp presses it.

Source

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

Release a MIDI note (the voice keeps ringing through its tail).

Source

pub fn all_off(&mut self)

Release everything.

Source

pub fn set_bend(&mut self, semitones: f64)

Pitch bend in semitones (smoothed on the audio thread).

Source

pub fn set_glide(&mut self, amount: f64)

Portamento amount 0..1 (0 = off, 1 ≈ 500 ms).

Source

pub fn set_unison(&mut self, on: bool, detune: f64, spread: f64)

Unison mode: every voice plays the same note, detuned/panned apart.

Source

pub fn set_arp( &mut self, on: bool, mode: u32, div: f64, bpm: f64, gate: f64, octaves: u32, swing: f64, )

Configure the arpeggiator. mode: 0 up, 1 down, 2 up-down, 3 random. div: steps per beat. gate: note length as a fraction of the step (0.05 staccato … 1.0; at or above [ARP_TIE] the pattern is tied and slides between pitches instead of retriggering). octaves: how many octaves the pattern climbs before wrapping (1–4). swing: 0–0.75, which lengthens every even step and shortens the odd one after it, leaving the pair’s total duration unchanged.

Turning it off re-presses the held chord; turning it on hands the held notes to the scheduler.

Source

pub fn set_param(&mut self, addr: &str, value: f64) -> bool

Set a knob target in the site’s own units. The value ramps in over ~25 ms on the audio thread (no zipper) — no recompilation: filter and delay state survive. Returns false for addresses with no live handle (the remaining enums, structure) — those need set_patch.

“The site’s own units” is new, and it is the whole reason table and oct can be here at all: they send a category index, and the blanket clamp(0.0, 1.0) this used to apply would have folded all eight wavetables onto the first two and every octave onto −2 and −1.

Source

pub fn set_makeup(&mut self, gain: f64)

Loudness makeup gain (linear). Applied immediately when idle, or deferred to swap completion when a patch swap is pending (so the outgoing patch fades at its own level).

Source

pub fn process_ptr(&mut self, frames: usize) -> *const f32

Render frames frames into the internal interleaved-stereo buffer and return a pointer into wasm memory — the zero-allocation worklet path ([l0, r0, l1, r1, …], frames * 2 floats).

Source

pub fn process(&mut self, frames: usize) -> Vec<f32>

Render and return a copy (allocating; native tests only).

Trait Implementations§

Source§

impl From<LivePoly> for JsValue

Source§

fn from(value: LivePoly) -> Self

Converts to this type from the input type.
Source§

impl FromWasmAbi for LivePoly

Source§

type Abi = WasmPtr<WasmRefCell<LivePoly>>

The Wasm ABI type that this converts from when coming back out from the ABI boundary.
Source§

unsafe fn from_abi(js: Self::Abi) -> Self

Recover a Self from Self::Abi. Read more
Source§

impl IntoWasmAbi for LivePoly

Source§

type Abi = WasmPtr<WasmRefCell<LivePoly>>

The Wasm ABI type that this converts into when crossing the ABI boundary.
Source§

fn into_abi(self) -> Self::Abi

Convert self into Self::Abi so that it can be sent across the wasm ABI boundary.
Source§

impl LongRefFromWasmAbi for LivePoly

Source§

type Abi = WasmPtr<WasmRefCell<LivePoly>>

Same as RefFromWasmAbi::Abi
Source§

type Anchor = RcRef<LivePoly>

Same as RefFromWasmAbi::Anchor
Source§

unsafe fn long_ref_from_abi(js: Self::Abi) -> Self::Anchor

Same as RefFromWasmAbi::ref_from_abi
Source§

impl OptionFromWasmAbi for LivePoly

Source§

fn is_none(abi: &Self::Abi) -> bool

Tests whether the argument is a “none” instance. If so it will be deserialized as None, and otherwise it will be passed to FromWasmAbi.
Source§

impl OptionIntoWasmAbi for LivePoly

Source§

fn none() -> Self::Abi

Returns an ABI instance indicating “none”, which JS will interpret as the None branch of this option. Read more
Source§

impl RefFromWasmAbi for LivePoly

Source§

type Abi = WasmPtr<WasmRefCell<LivePoly>>

The Wasm ABI type references to Self are recovered from.
Source§

type Anchor = RcRef<LivePoly>

The type that holds the reference to Self for the duration of the invocation of the function that has an &Self parameter. This is required to ensure that the lifetimes don’t persist beyond one function call, and so that they remain anonymous.
Source§

unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor

Recover a Self::Anchor from Self::Abi. Read more
Source§

impl RefMutFromWasmAbi for LivePoly

Source§

type Abi = WasmPtr<WasmRefCell<LivePoly>>

Same as RefFromWasmAbi::Abi
Source§

type Anchor = RcRefMut<LivePoly>

Same as RefFromWasmAbi::Anchor
Source§

unsafe fn ref_mut_from_abi(js: Self::Abi) -> Self::Anchor

Same as RefFromWasmAbi::ref_from_abi
Source§

impl TryFromJsValue for LivePoly

Source§

fn try_from_js_value(value: JsValue) -> Result<Self, JsValue>

Performs the conversion.
Source§

fn try_from_js_value_ref(value: &JsValue) -> Option<Self>

Performs the conversion.
Source§

impl VectorFromWasmAbi for LivePoly

Source§

type Abi = <Box<[JsValue]> as FromWasmAbi>::Abi

Source§

unsafe fn vector_from_abi(js: Self::Abi) -> Box<[LivePoly]>

Source§

impl VectorIntoWasmAbi for LivePoly

Source§

impl WasmDescribe for LivePoly

Source§

impl WasmDescribeVector for LivePoly

Source§

impl SupportsConstructor for LivePoly

Source§

impl SupportsInstanceProperty for LivePoly

Source§

impl SupportsStaticProperty for LivePoly

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> ReturnWasmAbi for T
where T: IntoWasmAbi,

Source§

type Abi = <T as IntoWasmAbi>::Abi

Same as IntoWasmAbi::Abi
Source§

fn return_abi(self) -> <T as ReturnWasmAbi>::Abi

Same as IntoWasmAbi::into_abi, except that it may throw and never return in the case of Err.
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.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,