# Backwash

> Backwards echo: every chunk of time is played back reversed during the next one, so notes swell in from nothing and cut off. Feedback flips the repeats back and forth. Fade sets how soft each chunk's edges are. Sync: 0 = free, 1..13 = 1/32 to 1 bar (chunks longer than 2 s are held at 2 s).

- Engine id: `org.sournd.delay.backwash`
- Category: Delay
- Licence: paid: £2.99 an effect or £4.99 a synth, once (owned for good, with updates), or included in the Everything plan (£14.99 a month)
- Version: 1.0.0
- Latency: 0 samples
- Tail: 60 s
- Sidechain input: no
- Channels: mono or stereo
- Audio demo: https://sournd.com/static/preview/demos/backwash.mp3 (plucked chords, default settings)

## Parameters

The id is the C ABI parameter id and the JUCE parameter id (as a decimal string).

| Id | Key | Name | Min | Max | Default | Unit | Taper |
|---|---|---|---|---|---|---|---|
| 0 | `time_ms` | Time | 50 | 2000 | 500 | ms | log |
| 1 | `sync` | Sync | 0 | 13 | 0 | - | linear |
| 2 | `feedback` | Feedback | 0 | 0.9 | 0.3 | - | linear |
| 3 | `fade` | Fade | 1 | 50 | 10 | % | linear |
| 4 | `tone_hz` | Tone | 1000 | 20000 | 12000 | Hz | log |
| 5 | `tempo` | Tempo | 40 | 300 | 120 | bpm | linear |
| 6 | `mix` | Mix | 0 | 100 | 50 | % | linear |

## Use it in JUCE

CMake ([quick start](/docs/juce/index.md)):

```cmake
juce_add_module(path/to/sournd_engine)
target_include_directories(MyPlugin PRIVATE path/to/include)
target_link_libraries(MyPlugin PRIVATE sournd_engine path/to/libsournd_cabi.a)
```

C++:

```cpp
#include <sournd_engine/sournd_engine.h>

sournd::SourndEngine engine { "org.sournd.delay.backwash" };
juce::AudioProcessorValueTreeState parameters { *this, nullptr, "Parameters",
    sournd::SourndEngineParameters::createLayout (engine) };
sournd::SourndEngineParameters bridge { engine, parameters };

// prepareToPlay
engine.prepare ({ sampleRate, (juce::uint32) maximumBlock, 2 });
bridge.prepare (sampleRate);
setLatencySamples ((int) engine.latency());

// processBlock
bridge.apply ((uint32_t) buffer.getNumSamples());
juce::dsp::AudioBlock<float> block { buffer };
engine.process (juce::dsp::ProcessContextReplacing<float> { block });

// get/setStateInformation: hold getCallbackLock() around saveState / loadState,
// so state work never overlaps processBlock (full example: /docs/juce/)
```

Plain C:

```c
sournd_engine *e = NULL;
if (sournd_engine_create("org.sournd.delay.backwash", &e) == SOURND_OK) {
    sournd_engine_prepare(e, 48000.0, 512);
    sournd_engine_set_param(e, 0, 500); /* Time */
    sournd_engine_process(e, in, out, 2, frames);
    sournd_engine_destroy(e);
}
```

## How it is made

Original sOURnd design: a delay line whose read delay grows at twice real time across each chunk (so the previous chunk is read backwards), chunk length latched at each chunk start, a raised-sine edge window, and a one-pole low-pass on the feedback path.

## Ask your AI

Paste this into your coding assistant:

```text
Add the sournd engine org.sournd.delay.backwash to my JUCE plugin. Follow https://sournd.com/docs/juce/index.md
and the engine reference at https://sournd.com/engines/backwash/index.md. Expose every parameter through APVTS.
```
