Build with this node

Start with a prompt in Studio, or copy it into your own coding agent.

Ask Studio

@maruaudio/dsp/delays/feedback is the chain's fixed delay stage as a DSP node: a whole-frame ring in a Float32Array, read, mixed with the dry input, then overwritten with clamp(x + delayed·feedback, −1, 1) so each repeat regenerates. The arithmetic is @maru/delays-primitives; only the line store rounds to f32.

const state = initFeedbackDelayNode(48000, FEEDBACK_DELAY_MAX_MILLISECONDS)
setFeedbackDelayTime(state, 375)
setFeedbackDelayFeedback(state, 0.4)
setFeedbackDelayMix(state, 0.3)
const y = feedbackDelayNodeTick(state, x)

Parameters

SetterRange the setter enforcesDefaultUnit
setFeedbackDelayTimemax(1, round(ms·rate/1000)) frames, capped at the line allocated by initThe init timems
setFeedbackDelayFeedback0 to 0.950linear
setFeedbackDelayMix0 to 10 (fully dry)linear

Lifecycle

initFeedbackDelayNode(sampleRate, ms) allocates a line of that length, the capacity for the life of the state; pass FEEDBACK_DELAY_MAX_MILLISECONDS (2000) to leave room → setters → feedbackDelayNodeTick → resetFeedbackDelayNode, which zeroes the line and index and keeps the settings. A time change inside the capacity rewinds the index if it falls outside the new length. prepareFeedbackDelayNodeSampleRate re-derives the length from the stored time without allocating and keeps the history.

When to use it

Rhythmic echoes on a mono voice or instrument, where repeats fade by a fixed amount each pass.

Limits

  • Mono, whole-frame delay, no interpolation, modulation or damping.
  • A time change jumps the read position, with no crossfade.
  • The write clamps to ±1, so hot input is clipped inside the loop.
  • audio-kernels keeps the PCM16 render entry.

Implementations

Rust Output verified: The build passed and its output matches the reference implementation.

Verified on Apple Silicon macOS native and Node WASM at 8, 44.1, 48, 96 and 192 kHz. Output and state match the TypeScript reference, with no observed allocations, reallocations or deallocations during the tested processing, control and reset calls. Delay storage is prepared for 200 ms at 192 kHz; that prepared capacity is retained at lower rates. Browser hosts, plugins, other operating systems and realtime deadlines have not been verified. Performance has not been measured.

View target checks and scope

Algorithm properties and proofs

Lean 4 checks specific properties of this algorithm’s mathematical model. Each model result applies within its stated domain and assumptions.

8 Lean 4 results: 2 proofs in their stated domains; 5 proofs in exact arithmetic; 1 counterexample.

Proved in the stated domain.Advancing a ring cursor by compare-and-reset produces an index below every positive active length.Natural-number cursor and positive active length
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Integer addresses must be valid, nonnegative and exactly representable; validated region and arena assumptions are explicit. Sampler mapping covers only its delegated indexing/interpolation stage, not voice lifecycle, arena ownership or the whole renderer. The read before this update still needs a valid initial cursor and allocated capacity.
Theorem
MaruLean.LeafContracts.ring_step_in_bounds
Recorded axioms
propext, Quot.sound
Manifest reviewed
Proved in the stated domain.The final active ring position advances to zero.Natural-number positive active length
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Integer addresses must be valid, nonnegative and exactly representable; validated region and arena assumptions are explicit. Sampler mapping covers only its delegated indexing/interpolation stage, not voice lifecycle, arena ownership or the whole renderer.
Theorem
MaruLean.LeafContracts.ring_step_last
Recorded axioms
propext, Quot.sound
Manifest reviewed
Counterexample.An empty active ring has no valid in-range cursor, even when compare-and-reset returns zero.One zero-length integer witness
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. One concrete witness; it refutes the stated unrestricted claim, not every possible guarded implementation. Alignment deliberately bypasses its buffer when frames is zero; this is not a claim that its bypass is unsafe.
Theorem
MaruLean.LeafContracts.ring_empty_refuses_bound
Manifest reviewed
Show 5 more Lean 4 results
Proved in exact arithmetic.The dry/wet sum and the subtract-then-scale interpolation form are algebraically equal.Exact rational samples and mix coefficient
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Exact rational arithmetic only: IEEE rounding, overflow, NaN, infinities and signed-zero behavior are not proved. Sampler mappings cover the named shared stage only. No optimization is enabled or claimed faster. This does not authorize changing the existing floating-point operation order.
Theorem
MaruLean.LeafContracts.drywet_is_lerp
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Proved in exact arithmetic.A dry/wet mix stays inside the common input interval for a mix between zero and one.Exact rationals; ordered finite bounds and stated coefficient guards; mix in [0, 1]
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Exact rational arithmetic only: IEEE rounding, overflow, NaN, infinities and signed-zero behavior are not proved. Sampler mappings cover the named shared stage only. No optimization is enabled or claimed faster.
Theorem
MaruLean.LeafContracts.drywet_bounded
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Proved in exact arithmetic.The clamped feedback write is between minus one and one in exact arithmetic.Exact rational dry sample, delayed sample and feedback
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Exact rational arithmetic only: IEEE rounding, overflow, NaN, infinities and signed-zero behavior are not proved. Sampler mappings cover the named shared stage only. No optimization is enabled or claimed faster. This covers only the write stage, not feedback-system stability.
Theorem
MaruLean.LeafContracts.feedback_write_bounded
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Proved in exact arithmetic.At zero feedback the write stage is exactly the clamped dry sample.Exact rational dry and delayed samples; feedback = 0
Limits and assumptions
  • Hand-written source-reviewed model, not formal refinement of TypeScript or compiled code. Named functions and whole-file source digests are checked; finite canonical JavaScript cases are compared with executable Lean definitions. Exact rational arithmetic only: IEEE rounding, overflow, NaN, infinities and signed-zero behavior are not proved. Sampler mappings cover the named shared stage only. No optimization is enabled or claimed faster.
Theorem
MaruLean.LeafContracts.feedback_zero
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Proved in exact arithmetic.For every positive delay length and every sample, bounded input of amplitude A and arbitrary signed feedback |g[n]|<=q<1 give an exact state bound A/(1-q).Ordered field; positive integer delay, A>=0, 0<=q<1, input in [-A,A], feedback in [-q,q], zero initial history.
Limits and assumptions
  • Mathematical theorem over an arbitrary ordered field, with every hypothesis in its Lean type. Exact arithmetic only; IEEE rounding, overflow, non-finites and platform transcendental implementations are outside this theorem. Source bindings identify the reviewed DSP relationship, not a formal translation or a compiled-artifact proof. Strong induction handles arbitrary delay lengths, input streams and feedback modulation. This is the ideal unclipped delay recurrence; the shipped node also clips writes and stores binary32. Those operations are separate obligations. The delay length is fixed within the recurrence; delay-time automation is not covered.
  • This record also covers MaruLean.SignalBounds.delay_bibo_invariant, MaruLean.SignalBounds.signed_product_bound, MaruLean.SignalBounds.feedback_step_bound; axioms describe MaruLean.SignalBounds.delay_bibo only.
Theorem
MaruLean.SignalBounds.delay_bibo
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Explore proofs alongside performance

Parameters

ParameterTypeSetter
Feedback feedbackfloatsetFeedbackDelayFeedback
Delay milliseconds delayMilliseconds

Select a bounded active length inside a preallocated maximum line.

floatsetFeedbackDelayTime
Mix mixfloatsetFeedbackDelayMix

Ports

  • In ininput · audio · mono
  • Out outoutput · audio · mono

One sample per feedbackDelayNodeTick call.

Dependencies

Dependents

No other node imports this one.

Used by