Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reverb Extractor

DOI License: MIT

Point it at a room recording, get that room's reverb back as a cheap, real-time, editable effect.

Under the hood this is a differentiable Feedback Delay Network with learnable delay lines — a clean, open-source PyTorch reimplementation of

A. I. Mezza, R. Giampiccolo, E. De Sena, A. Bernardini, "Data-driven room acoustic modeling via differentiable feedback delay networks with learnable delay lines," EURASIP Journal on Audio, Speech, and Music Processing, 2024(1):51. arXiv:2404.00082 · DOI:10.1186/s13636-024-00371-5

Differentiable FDN fitting a target RIR

📄 Read the interactive write-up — Inverting the Room — with playable before/after audio → A room's reverb, extracted and then removed: the informed case works (0.41 → 0.91 STOI), and the write-up is honest about where blind system-ID hits the wall.

The idea in one line

A room's reverb, captured as a Room Impulse Response (RIR), is expensive to use directly (long convolution, fixed, not tweakable). This fits a Feedback Delay Network — the classic Schroeder/Jot artificial-reverb structure — to that RIR, so you get the same room as a handful of delay lines and gains: it renders in real time, costs almost nothing, and every parameter (decay, delay lengths, absorption) is now a knob you can turn.

What actually works — and the wall

Be honest about scope. There are two very different problems here:

  • Informed inversion — works. Give it the room's measured RIR (or a synthetic target) and it fits an FDN whose energy decay and echo build-up match that room. The optimiser reliably drives the loss down ~99% on the synthetic target and recovers a plausible, renderable reverb. This is the regime the demo and the smoke test live in.
  • Blind system-ID — the wall. Recovering the room from an ordinary reverberant recording alone (no measured RIR, e.g. estimating the RIR from a voice clip and then fitting it) is the hard, open part. RIR estimation is itself unsolved in general, and errors there dominate everything downstream. This repo does not claim to do blind extraction well — that's the frontier, not a shipped feature.

So: informed inversion is real; blind system-ID is where it stops. Everything below describes the informed case.

What this is (the method)

A Feedback Delay Network (FDN) is a bank of delay lines stitched together by a feedback matrix, with input/output gains and per-line absorption. It has been the workhorse of digital reverberation for decades — but its parameters, especially the delay-line lengths, are traditionally hand-tuned because a delay read from a buffer is not differentiable.

This project makes the entire FDN differentiable — delay lines and all — so every parameter can be learned by backpropagation to match a target RIR. It reproduces the method of Mezza et al. (2024):

  • Learnable delay lines (the novel part). Each integer delay z^{-m} is realised in the frequency domain with the Pei–Lai closed-form fractional-delay filter, whose response is a smooth function of a real-valued m. Gradients flow through the FFT straight to the delay lengths.
  • Learnable feedback matrix A = U·diag(γ), with U an orthogonal (unilossless) matrix parameterised through a skew-symmetric matrix exponential — stable by construction.
  • Learnable input/output/direct gains and per-line absorption, each a differentiable reparameterisation of an unconstrained proxy.
  • A perceptual, fully-differentiable loss: Energy Decay Curve (EDC) + a differentiable normalised Echo Density Profile (soft-EDP) in which the Heaviside indicator is replaced by a scaled sigmoid with a time-varying sharpness κ_n.

The optimiser fits one FDN to one RIR — a white-box system-identification view of reverberation: the result is a causal, real-time-renderable reverb whose decay and echo build-up match the target room.

Method → code map

Paper concept Where
Fractional delay D_i[k] (Pei–Lai), gradients to m dfdn/delay.py
FDN transfer function H = cᵀ(I − D·A)⁻¹D·b + d, frequency sampling dfdn/fdn.py
Orthogonal U = expm(triu(W) − triuᵀ), A = U·diag(γ) dfdn/fdn.py
Delay/gain/absorption reparameterisations dfdn/fdn.py
Schroeder EDC + normalised-MSE loss dfdn/losses.py
Soft-EDP with sigmoid + time-varying κ_n dfdn/losses.py
L = L_EDC + λ·L_EDP, Adam training loop dfdn/train.py
Target RIR (synthetic or real WAV) dfdn/rir.py
CLI example, plots, audio export train.py

Install

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt          # CPU torch is fine; GPU optional
# CPU-only wheel: pip install torch --index-url https://download.pytorch.org/whl/cpu

Run

Smoke test on a synthetic target RIR (clearly labelled as such — a direct impulse + sparse early reflections + decaying Gaussian tail so the echo density rises realistically):

python train.py --iters 500 --t60 0.5

Fit a real measured RIR (mono/stereo WAV, any sample rate — it is downmixed, resampled to 16 kHz and trimmed to the direct-sound onset):

python train.py --rir path/to/room.wav --iters 800

Outputs land in results/: fit_summary.png (loss curves, EDC in dB, echo density profile, impulse response — before/after) plus target_rir.wav and fitted_rir.wav.

Use the library directly:

import torch
from dfdn import fit_fdn, TrainConfig
from dfdn.rir import synth_rir, to_tensor

h = to_tensor(synth_rir(t60=0.5))
model, history, h_init, h_final = fit_fdn(h, TrainConfig(iters=500))
rir = model.render(len(h))          # differentiable, real-valued RIR

Run the tests (fast, CPU, no dataset needed):

python tests/test_dfdn.py            # or: python -m pytest tests/ -q

Try it in the browser

A one-click Gradio demo lives in app.py — drop a boomy clip or a RIR, watch the FDN fit it, and hear the extracted reverb. It is designed for the Hugging Face Space described in HF_SPACE_PLAN.md, tagged arxiv:2404.00082 so it surfaces from HF Papers. CPU-basic tier is enough (a 500-iteration fit is ~1 minute).

pip install gradio
python app.py

Results

A 500-iteration run (N = 6 delay lines, 16 kHz, Adam lr = 0.1) on the synthetic target reduces the loss by ~99% and recovers the target's decay and echo build-up:

Loss: 9.96e-01 -> 9.70e-03   (99.0% reduction)
Learned delays (ms): [24.3, 3.3, 3.7, 1.7, 3.5, 6.6]
Absorption γ:        [0.88, 0.97, 0.96, 0.95, 0.97, 0.93]

See docs/fit_summary.png. The fitted EDC tracks the target's exponential decay closely (versus a badly-mismatched initialisation), and the fitted echo density profile rises from sparse early reflections toward the diffuse (≈ 1.0) late field, matching the target.

Honest status. This is a faithful, runnable first pass, not a tuned reproduction of every number in the paper:

  • The core contribution — differentiable, learnable delay lines with gradients flowing to the delay lengths — is implemented and verified (the delays receive non-zero gradients and update during training).
  • The FDN here uses broadband (frequency-independent) absorption γ, as in the paper's decoupled A = U·diag(γ). Frequency-dependent attenuation filters (graphic-EQ / one-pole absorbers for T60(f)) are a natural next step and are listed in the roadmap.
  • Loss curves oscillate under the paper's aggressive lr = 0.1; a scheduler or smaller lr trades a little final accuracy for smoother convergence.
  • Numbers were validated on a synthetic target for reproducibility. Quantitative agreement with the paper's reported errors on standard RIR datasets (e.g. differences in T60/EDT/echo density) has not yet been benchmarked, and blind RIR estimation (see the wall, above) is out of scope.

Roadmap

  • Frequency-dependent absorption — replace scalar γ with per-line one-pole / graphic-EQ attenuation filters so T60(f) is matched band-by-band.
  • Real RIR datasets — turnkey loaders + benchmarks on public corpora (Motus / MIT Acoustical Reverberation, OpenAIR, ARNI, dEchorate) reporting T60, EDT, C50 and echo-density error.
  • Hugging Face Space demo — upload a RIR → fit → hear and see the reverb in the browser, so the project is discoverable via HF Papers (see HF_SPACE_PLAN.md).
  • Differentiable-acoustics family — this FDN sits alongside differentiable Scattering Delay Networks and other data-driven reverberators; shared loss and RIR-analysis tooling could grow into a small library.

Citation

If you use this implementation or the accompanying paper, please cite the paper (Zenodo, DOI 10.5281/zenodo.22683508):

@misc{martins2026inverting,
  title     = {Inverting the Room: Differentiable Feedback Delay Networks for
               Reverb Extraction and Dereverberation},
  author    = {Martins, Nicholas},
  year      = {2026},
  publisher = {Zenodo},
  doi       = {10.5281/zenodo.22683508},
  url       = {https://doi.org/10.5281/zenodo.22683508}
}

…and the original paper this work builds on:

@article{mezza2024fdn,
  title   = {Data-driven room acoustic modeling via differentiable feedback
             delay networks with learnable delay lines},
  author  = {Mezza, Alessandro Ilic and Giampiccolo, Riccardo and
             De Sena, Enzo and Bernardini, Alberto},
  journal = {EURASIP Journal on Audio, Speech, and Music Processing},
  volume  = {2024}, number = {1}, pages = {51}, year = {2024},
  doi     = {10.1186/s13636-024-00371-5}
}

This is an independent, third-party reimplementation for research and educational use; it is not affiliated with or endorsed by the original authors. Method credit is theirs; any bugs here are mine.

License

MIT.

About

Reverb Extractor — differentiable Feedback Delay Network with learnable delay lines (PyTorch reimpl of Mezza et al. 2024)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages