Skip to main content

An Open-Source Library for Frequency-Domain Differentiable Audio Processing

Project description

flamo

Docs | PyPI | ICASSP25-arXiv

Open-source library for frequency-domain differentiable audio processing.

It contains differentiable implementation of common LTI audio system modules with learnable parameters.


⚙️ Optimization of audio LTI systems

Available differentiable audio signal processors - in flamo.processor.dsp:

  • Gains : Gains, Matrices, Householder Matrices
  • Filters : Biquads, State Variable Filters (SVF), Graphic Equalizers (GEQ), Parametric Equalizers (PEQ - not released yet)
  • Delays : Integer Delays, Fractional Delays

Transforms - in flamo.processor.dsp:

  • Transform : FFT, iFFT, time anti-aliasing enabled FFT and iFFT

Utilities, system designers, and optimization - in flamo.processor.system:

  • Series : Serial chaining of differentiable systems
  • Recursion : Closed loop with assignable feedforward and feedback paths
  • Shell: Container class for safe interaction between system, dataset, and loss functions

Optimization - in flamo.optimize:

  • Trainer : Handling of the training and validation steps
  • Dataset : Customizable dataset class and helper methods

🛠️ Installation

To install it via pip, on a new Python virtual environment flamo-env

python3.10 -m venv .flamo-env
source .flamo-env/bin/activate
pip install flamo

If you are using conda, you might need to install libsndfile manually

conda create -n flamo-env python=3.10
conda activate flamo-env
pip install flamo
conda install -c conda-forge libsndfile

For local installation: clone and install dependencies on a new Python virtual environment flamo-env

git clone https://github.com/gdalsanto/flamo
cd flamo
python3.10 -m venv .flamo-env
source .flamo-env/bin/activate
pip install -e .

Note that it requires python>=3.10


💻 How to use the library

We included a few examples in ./examples that take you through the library's API.

The following example demonstrates how to optimize the parameters of Biquad filters to match a target magnitude response. This is just a toy example; you can create and optimize much more complex systems by cascading modules either serially or recursively.

Import modules

import torch
import torch.nn as nn
from flamo.optimize.dataset import Dataset, load_dataset
from flamo.optimize.trainer import Trainer
from flamo.processor import dsp, system
from flamo.functional import signal_gallery, highpass_filter

Define parameters and target response with randomized cutoff frequency and gains

in_ch, out_ch = 1, 2    # input and output channels
n_sections = 2  # number of cascaded biquad sections
fs = 48000      # sampling frequency
nfft = fs*2     # number of fft points

b, a = highpass_filter(
    fc=torch.tensor(fs/2)*torch.rand(size=(n_sections, out_ch, in_ch)), 
    gain=torch.tensor(-1) + (torch.tensor(2))*torch.rand(size=(n_sections, out_ch, in_ch)), 
    fs=fs)
B = torch.fft.rfft(b, nfft, dim=0)
A = torch.fft.rfft(a, nfft, dim=0)
target_filter = torch.prod(B, dim=1) / torch.prod(A, dim=1)

Define an instance of learnable Biquads

filt = dsp.Biquad(
    size=(out_ch, in_ch), 
    n_sections=n_sections,
    filter_type='highpass',
    nfft=nfft,
    fs=fs,
    requires_grad=True,
    alias_decay_db=0,
)   

Use the Shell class to add input and output layers and to get the magnitude response at initialization Optimization is done in the frequency domain. The input will be an impulse in the time domain, thus the input layer should perform the Fourier transform. The target is the magnitude response, so the output layer takes the absolute value of the filter's output.

input_layer = dsp.FFT(nfft)
output_layer = dsp.Transform(transform=lambda x : torch.abs(x))
model = system.Shell(core=filt, input_layer=input_layer, output_layer=output_layer)    
estimation_init = model.get_freq_response()

Set up the optimization framework and launch it. The Trainer class is used to contain the model, training parameters, and training/valid steps in one class.

input = signal_gallery(1, n_samples=nfft, n=in_ch, signal_type='impulse', fs=fs)
target = torch.einsum('...ji,...i->...j', target_filter, input_layer(input))

dataset = Dataset(
    input=input,
    target=torch.abs(target),
    expand=100,
)
train_loader, valid_loader = load_dataset(dataset, batch_size=1)

trainer = Trainer(model, max_epochs=10, lr=1e-2, train_dir="./output")
trainer.register_criterion(nn.MSELoss(), 1)

trainer.train(train_loader, valid_loader)

end get the resulting response after optimization!

estimation = model.get_freq_response()

📖 Documentation

A first version of the documentation is available on the repo's Github Page. Note that we are currently working on improving the documentation to include examples, images, and a more pleasant template.


📖 Reference

This work has been submitted to ICASSP 2025. Pre-print is available on arxiv.

Dal Santo, G., De Bortoli, G. M., Prawda, K., Schlecht, S. J., & Välimäki, V. (2024). FLAMO: An Open-Source Library for Frequency-Domain Differentiable Audio Processing. arXiv preprint arXiv:2409.08723.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flamo-0.2.13.tar.gz (23.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flamo-0.2.13-py3-none-any.whl (79.4 kB view details)

Uploaded Python 3

File details

Details for the file flamo-0.2.13.tar.gz.

File metadata

  • Download URL: flamo-0.2.13.tar.gz
  • Upload date:
  • Size: 23.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.15

File hashes

Hashes for flamo-0.2.13.tar.gz
Algorithm Hash digest
SHA256 f29995e18caefa3c9347b7d66dc0d6666635f51c694d4b97d19cff64524b1feb
MD5 67108a35fbb0ff3e779a1f8312a33667
BLAKE2b-256 1e7eb1b9e05e0087160358afde3762cff27123098beaa839813dfa18c773181e

See more details on using hashes here.

File details

Details for the file flamo-0.2.13-py3-none-any.whl.

File metadata

  • Download URL: flamo-0.2.13-py3-none-any.whl
  • Upload date:
  • Size: 79.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.15

File hashes

Hashes for flamo-0.2.13-py3-none-any.whl
Algorithm Hash digest
SHA256 7261ce86a966f208402ed6d1709d610d2ff178b23fbaf9e9d9dee87d08f84bbf
MD5 3ba229d3f670e3c47e1e23198b96b1c7
BLAKE2b-256 838bdadf1c3fdb4678dac46a28e111215637c7705cf6458b5890965b28af474f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page