Skip to content
IIP-GroupPublic

Latest commit

 

History

9 Commits

Folders and files

Repository files navigation

FDverb

A frequency-domain artificial reverberation effect. FDverb is implemented as a plugin (see plugin/) and as an offline Python implementation (see python/).

📄 Paper: "A Frequency-Domain Artificial Reverberator Plug-In," demo paper presented at the Int. Conf. Digital Audio Effects (DAFx-26), Cambridge, 2026. [PDF] [arXiv]

FDverb plugin UI

Credits

Developed by Nishanth Kumar, Silvan Krebs, David Wieland, Christoph Studer, and Jonas Roth at the Integrated Information Processing (IIP) Group at ETH Zurich.

Built using the JUCE framework.

Features

  • Frequency-domain reverb processing using STFT
  • Envelope follower with decay control
  • Frequency-dependent decay (tilt)
  • Spectral shifting (static and dynamic)
  • Brick-wall EQ (low cut / high cut)
  • Freeze mode with input gate
  • Synthetic early reflections
  • Stereo link and width control

Python-Only Features

The Python implementation has a number of extra features implemented, compared to the plugin implementation:

  • Load a preset early-reflections IR (config parameter early_reflections:er_preset).
  • Send early-reflections signal to tail reverberator (config parameter early_reflections:er2tail_gain).
  • Tune the early-reflections decay rate (config parameter early_reflections:decay_rate, in dB/ms). The plugin fixes this rate at 0.2 dB/ms, so presets must keep that value to match it.

How It Works

FDverb is a hybrid pipeline with two parts:

  • Early reflections (ER): a synthetic, sparse ER impulse response, implemented as a sparse convolution in the time domain so it adds no extra latency.
  • Tail reverberator: a vocoder with a noise carrier. The input is analyzed with an STFT, each frequency bin gets its own envelope follower, and these envelopes weight the spectral components of a noise signal. Conceptually related to spectral magnitude decay (Vickers et al., AES 121st Conv., 2006).

Parameters

Tail Reverberator

Parameter Description
block_size STFT block size. Trade-off between frequency resolution and the lower limit on tail_delay.
mode Envelope (AR-averager) mode — see below.
color Amplitude power γ. Affects dynamics and frequency weighting.
time Nominal T60 decay time.
tilt Increase/decrease decay time for lower/higher frequencies.
shift Static pitch shift (offsets the input bins).
drift Dynamic pitch shift (offsets the AR-averager states).
link Links envelopes between the stereo channels (follows the maximum).
width Correlates, decorrelates, or anti-correlates the noise carrier between the stereo channels.
low_cut / high_cut Brick-wall EQ applied to the noise carrier.

Modes

Mode Behavior
logarithmic Exponential-decay envelope (constant factor). Sounds like a regular reverb.
arithmetic Linear envelope (constant decrement). Sounds like a gated reverb.
freeze Infinite sustain; gate controls whether the input signal is routed into the reverb.

Early Reflections

Tap delays follow a pseudo-random pattern, with delays distributed between pre_delay and tail_delay (density grows ∝ t²) and a fixed amplitude decay of −0.2 dB/ms (tunable in Python only, see above).

Parameter Description
echoes Number of ER taps.
pre_delay Delay of the first reflection. Also sets the RNG seed for the tap pattern.
tail_delay Delay of the last reflection and onset of the tail reverberator. Lower limit depends on block_size.

Getting Started

See our releases for pre-compiled plugin binaries.

Alternatively, follow the instructions below to build from source.

git clone --recurse-submodules git@github.com:IIP-Group/FDverb.git
cd FDverb

Python (Jupyter Notebook)

offline reference implementation

Setup

Create virtual environment and install requirements:

cd python
python3.13 -m venv env_fdverb
source env_fdverb/bin/activate
pip install -r requirements.txt

Configuration

Parameter presets are found in the presets/ directory.

The paths to the active parameter config and audio input file are set at the beginning of the notebook. To tweak parameters, edit presets/default.yaml or create a new YAML and adjust the path in the notebook.

Run

Open Jupyter notebook python/FDverb.ipynb and run cells.

Output is saved to python/out/out.wav and plays automatically.

Development

Recommended development requirements are provided in python/requirements-dev.txt.

pip install -r requirements-dev.txt
nbstripout --install

User requirements are maintained in python/requirements.in and compiled using

pip-compile requirements.in

C++ (JUCE)

Requirements

  • CMake 3.22+
  • C++17-compatible compiler
  • JUCE framework

Building

cd plugin
cmake --preset macos                  # or: windows
cmake --build --preset macos-release  # or: windows-release

Build presets: macos-debug, macos-release, windows-debug, windows-release. Use Release for listening tests and releases — Debug builds are unoptimized and show -debug next to the version number in the UI.

Plugins are output to plugin/build/FDverb_artefacts/<Config>/, where <Config> is Debug or Release, and are copied to the standard user plugin directory after each build. To disable the copy, remove this line from plugin/CMakeLists.txt:

    COPY_PLUGIN_AFTER_BUILD TRUE

On Windows the default location C:\Program Files\Common Files\VST3\ is a protected system folder, so the copy fails unless Visual Studio runs as administrator.

IDEs

cmake --preset macos also generates plugin/build/FDverb.xcodeproj. Visual Studio (File > Open > Folder...) and VS Code (CMake Tools) read the presets directly; select the configuration from the preset list.

Runtime Measurement Mode

To re-run the processFrame() timing measurements, build with -DFDVERB_MEASURE_TIMING=ON:

cd plugin
cmake --preset macos -DFDVERB_MEASURE_TIMING=ON
cmake --build --preset macos-release

While the plugin runs, measurements are appended to ~/Desktop/fdverb_runtime_measurements/<timestamp>_blocksize_<N>.txt. Since the AU is declared sandbox-safe (AU_SANDBOX_SAFE), a sandboxed host may redirect that path into its own container, e.g. ~/Library/Containers/<host>/Data/Desktop/. Run python/scripts/runtime_analysis.ipynb to analyze the results — it reads directly from that directory. Rebuild with -DFDVERB_MEASURE_TIMING=OFF when done.

Factory Presets

FDverb ships with factory presets. Whether they appear automatically or need a one-time install depends on your host.

Logic / Reaper

Nothing to do. The presets are embedded in the plugin and appear in the host's native preset menu automatically.

Ableton Live / Cubase / Studio One

These hosts don't read the plugin's built-in preset list; they look for .vstpreset files on disk. Copy the files from presets/vstpreset/ into the VST3 preset folder for your OS:

  • macOS: ~/Library/Audio/Presets/IIP/FDverb/
  • Windows: %USERPROFILE%\Documents\VST3 Presets\IIP\FDverb\
  • Linux: ~/.vst3/presets/IIP/FDverb/

Then restart the host (or rescan its preset/media library) so it picks them up.

Editing or adding a preset

These instructions are for contributors changing the presets that ship with FDverb. If you just want to use the existing presets, see Factory Presets above.

A preset exists in three forms:

  • YAML source in presets/ is authoritative.
  • JUCE state XML in presets/generated/ is derived from it and embedded in the binary (Logic/Reaper).
  • .vstpreset files in presets/vstpreset/ are exported from the built plugin (Ableton/Cubase/Studio One).

Adding a new preset

  1. Create the YAML in presets/, following presets/default.yaml.
  2. Add it to PRESET_FILES in python/scripts/yaml_to_preset.py (filename + display name).
  3. Add its BinaryData:: entry to kPresets[] in plugin/src/PluginProcessor.cpp (JUCE strips hyphens from BinaryData identifiers).
  4. Reconfigure CMake (cmake --preset macos # or windows, see above) so the glob picks up the new XML.

Then run the build steps below from step 6.

Editing a preset

  1. Edit the YAML in presets/.
  2. Regenerate the XML: python python/scripts/yaml_to_preset.py (from the repo root).
  3. Re-export the .vstpreset file: load FDverb in Reaper, select the preset, and save it as a .vstpreset into presets/vstpreset/.
  4. Build, and commit the YAML plus the updated generated/ and vstpreset/ files.

Citation

If you use FDverb in your work, please cite:

@misc{roth2026fdverb,
  author        = {Roth, Jonas and Kumar, Nishanth and Krebs, Silvan and Wieland, David and Studer, Christoph},
  title         = {A Frequency-Domain Artificial Reverberator Plug-In},
  howpublished  = {Demo paper presented at the Int. Conf. Digital Audio Effects (DAFx-26), Cambridge},
  year          = {2026},
  eprint        = {2608.27695},
  archivePrefix = {arXiv}
}

License

FDverb is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). The JUCE framework is included as a Git submodule, which is used under the terms of the AGPL. The JUCE framework remains subject to its own license, which is included in the JUCE submodule.