Build with this node

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

Ask Studio

@maruaudio/dsp/delays/fractional is a bounded f32 delay line read at a fractional position by linear interpolation, y = a + (b − a)·frac, rounded to f32. It has two states. The modulation delay (up to 50 ms) writes the clamped input, then reads, then advances, and mixes dry with delayed. The feedback delay (up to 1000 ms) reads first, in DelayNode order, then writes clamp(x + delayed·feedback, −1, 1) and returns the delayed sample only. Both offer extra read taps, a write without clipping for tap compositions, a first-order allpass tap and a staged clear.

const state = initFractionalFeedbackDelayNode(MAX_PROCESSING_RATE)
prepareFractionalFeedbackDelayNodeSampleRate(state, 48000)
setFractionalFeedbackDelayTime(state, 300)
const wet = fractionalFeedbackDelayNodeTick(state, x)

Parameters

SetterRange the setter enforcesDefaultUnit
setFractionalDelayTime0 to 503.5ms
setFractionalDelayMix0 to 11linear
setFractionalFeedbackDelayTime0 to 1000250ms
setFractionalFeedbackDelayFeedback0 to 0.950linear
fractionalDelayRead / fractionalFeedbackDelayReadAt (delay argument)0 to ring length − 2—samples
configureFractionalAllpassTap(tap, w, phase)Coefficient (1 − g)/(1 + g), clamped to 0 to 1; bypass below 1e−10 phaseBypassrad

Lifecycle

Init allocates a ring of the maximum time plus 2 frames at the given rate; pass the highest rate, then prepare for the processing rate. Prepare re-derives the active ring length (within the capacity) and the delay, and clears history only if the length changed. Setters → tick, or the read, write and advance calls → reset, which zeroes the line and index. clear…Step(state, cursor, budget) zeroes at most 256 samples per call and returns line.length when done; then call finalize…Clear.

When to use it

Chorus, flanger and vibrato taps that move smoothly (the modulation state), or a tunable echo with feedback. The allpass tap tunes a fixed feedback loop, such as a string model, at unit magnitude.

Limits

Nonfinite delay-time edits and invalid preparation rates leave the previous configuration intact. A direct read with a nonfinite delay returns silence. Ring wrap also handles the floating-point case where adding the ring length to a tiny negative position rounds exactly to the ring end.

  • Mono. Linear interpolation attenuates high frequencies at fractional delays.
  • The allpass tap is for a fixed delay: configure and reset it before a note.
  • fractionalFeedbackDelayWriteAdvance does not clip; pass finite audio.

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.

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

Proved in the stated domain.Subtracting an admitted whole-sample delay wraps to an in-range fractional-ring tap.Natural-number ring addresses; rational interpolation with bounded fraction
Limits and assumptions
  • Hand-written source-reviewed Nat/Rat model, not formal refinement of TypeScript, Rust or compiled output. Whole-file source digests and finite canonical JavaScript vectors are checked. Capacities, clocks, delay and block addresses must be valid nonnegative exactly representable integers. Circular subtraction models the integer tap coordinate; the continuous floor/wrap implementation is linked by dyadic vectors rather than a general floating-point proof. Interpolation bounds omit IEEE rounding, Float32 storage, NaN and infinities; they require a fraction in [0,1]. No proof of initialization, ownership or the allpass-tap path.
Theorem
MaruLean.LeafContracts.circular_subtract_in_bounds
Recorded axioms
propext, Quot.sound
Manifest reviewed
Proved in the stated domain.A delay that does not cross the ring seam preserves its integer address difference.Natural-number ring addresses; rational interpolation with bounded fraction
Limits and assumptions
  • Hand-written source-reviewed Nat/Rat model, not formal refinement of TypeScript, Rust or compiled output. Whole-file source digests and finite canonical JavaScript vectors are checked. Capacities, clocks, delay and block addresses must be valid nonnegative exactly representable integers. Circular subtraction models the integer tap coordinate; the continuous floor/wrap implementation is linked by dyadic vectors rather than a general floating-point proof. Interpolation bounds omit IEEE rounding, Float32 storage, NaN and infinities; they require a fraction in [0,1]. No proof of initialization, ownership or the allpass-tap path.
Theorem
MaruLean.LeafContracts.circular_subtract_no_wrap
Recorded axioms
propext, Quot.sound
Manifest reviewed
Proved in the stated domain.Both interpolating taps stay inside a prepared ring when the write clock and delay are admitted.Natural-number ring addresses; rational interpolation with bounded fraction
Limits and assumptions
  • Hand-written source-reviewed Nat/Rat model, not formal refinement of TypeScript, Rust or compiled output. Whole-file source digests and finite canonical JavaScript vectors are checked. Capacities, clocks, delay and block addresses must be valid nonnegative exactly representable integers. Circular subtraction models the integer tap coordinate; the continuous floor/wrap implementation is linked by dyadic vectors rather than a general floating-point proof. Interpolation bounds omit IEEE rounding, Float32 storage, NaN and infinities; they require a fraction in [0,1]. No proof of initialization, ownership or the allpass-tap path.
Theorem
MaruLean.LeafContracts.fractional_pair_in_bounds
Recorded axioms
propext, Quot.sound
Manifest reviewed
Show 2 more Lean 4 results
Proved in exact arithmetic.The exact interpolation of two bounded ring samples stays within their interval.Natural-number ring addresses; rational interpolation with bounded fraction
Limits and assumptions
  • Hand-written source-reviewed Nat/Rat model, not formal refinement of TypeScript, Rust or compiled output. Whole-file source digests and finite canonical JavaScript vectors are checked. Capacities, clocks, delay and block addresses must be valid nonnegative exactly representable integers. Circular subtraction models the integer tap coordinate; the continuous floor/wrap implementation is linked by dyadic vectors rather than a general floating-point proof. Interpolation bounds omit IEEE rounding, Float32 storage, NaN and infinities; they require a fraction in [0,1]. No proof of initialization, ownership or the allpass-tap path.
Theorem
MaruLean.LeafContracts.fractional_interpolation_bounded
Recorded axioms
propext, Classical.choice, Quot.sound
Manifest reviewed
Counterexample.An invalid write clock defeats the circular-read bound.Natural-number ring addresses; rational interpolation with bounded fraction
Limits and assumptions
  • Hand-written source-reviewed Nat/Rat model, not formal refinement of TypeScript, Rust or compiled output. Whole-file source digests and finite canonical JavaScript vectors are checked. Capacities, clocks, delay and block addresses must be valid nonnegative exactly representable integers. Circular subtraction models the integer tap coordinate; the continuous floor/wrap implementation is linked by dyadic vectors rather than a general floating-point proof. Interpolation bounds omit IEEE rounding, Float32 storage, NaN and infinities; they require a fraction in [0,1]. No proof of initialization, ownership or the allpass-tap path.
Theorem
MaruLean.LeafContracts.fractional_invalid_clock_refuses_bound
Manifest reviewed
Explore proofs alongside performance

Parameters

ParameterTypeSetter
Fractional feedback delay time fractionalFeedbackDelayTimefloatsetFractionalFeedbackDelayTime
Feedback feedbackfloatsetFractionalFeedbackDelayFeedback
Fractional delay time fractionalDelayTimefloatsetFractionalDelayTime
Mix mixfloatsetFractionalDelayMix

Dependencies

None: this node imports no other node.

Dependents

Used by