@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
| Setter | Range the setter enforces | Default | Unit |
|---|---|---|---|
setFeedbackDelayTime | max(1, round(ms·rate/1000)) frames, capped at the line allocated by init | The init time | ms |
setFeedbackDelayFeedback | 0 to 0.95 | 0 | linear |
setFeedbackDelayMix | 0 to 1 | 0 (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-kernelskeeps the PCM16 render entry.