Skip to main content

Nice DSP sweets: resampling, FFT Convolutions — a TensorFlow port of Alexandre Défossez's julius, differentiable and with GPU support.

Project description

Julius, fast TensorFlow based DSP for audio and 1D signals

linter badge tests badge cov badge

Julius contains different Digital Signal Processing algorithms implemented with TensorFlow, so that they are differentiable and available on GPU. Note that all the modules implemented here can be used inside a tf.function.

julius-tf is a TensorFlow port of julius, the PyTorch DSP library by Alexandre Défossez. The DSP algorithms and the public API are his work; this project re-implements them on top of TensorFlow. See Credits for full attribution.

For now, I have implemented:

Along that, you might found useful utilities in:

Representation of the convolutions filters used for the efficient resampling.

News

  • julius-tf ports the whole library from PyTorch to TensorFlow. The public API of the original julius is preserved: modules are tf.Modules, callable just like before, and usable inside a tf.function. The dated entries below are the upstream julius releases whose behavior this port reproduces.
  • 23/06/2026: julius-tf 0.1.0: first release on PyPI — TensorFlow port reproducing upstream julius 0.2.8. Install with pip install julius-tf.
  • 03/06/2026: julius 0.2.8 released:: Switching to pyproject.toml, now requires python >= 3.9. Bug fix with -O flag (thanks @aiknownc)
  • 19/09/2022: julius 0.2.7 released:: fixed ONNX compat (thanks @iver56). I know I missed the 0.2.6 one...
  • 28/07/2021: julius 0.2.5 released:: support for setting a custom output length when resampling.
  • 22/06/2021: julius 0.2.4 released:: adding highpass and band passfilters. Extra linting and type checking of the code. New unfold implemention, up to x6 faster FFT convolutions and more efficient memory usage.
  • 26/01/2021: julius 0.2.2 released: fixing normalization of filters in lowpass and resample to avoid very low frequencies to be leaked. Switch from zero padding to replicate padding (uses first/last value instead of 0) to avoid discontinuities with strong artifacts.
  • 20/01/2021: julius implementation of resampling is now officially part of Torchaudio.

Installation

julius-tf requires python >= 3.9 and TensorFlow >= 2.11. To install:

pip3 install -U julius-tf

The import name stays julius (i.e. pip install julius-tf then import julius).

Usage

See the Julius documentation for the usage of Julius. Hereafter you will find a few examples to get you quickly started:

import julius
import tensorflow as tf

signal = tf.random.normal((6, 4, 1024))
# Resample from a sample rate of 100 to 70. The old and new sample rate must be integers,
# and resampling will be fast if they form an irreductible fraction with small numerator
# and denominator (here 10 and 7). Any shape is supported, last dim is time.
resampled_signal = julius.resample_frac(signal, 100, 70)

# Low pass filter with a `0.1 * sample_rate` cutoff frequency.
low_freqs = julius.lowpass_filter(signal, 0.1)

# Fast convolutions with FFT, useful for large kernels
conv = julius.FFTConv1d(4, 10, 512)
convolved = conv(signal)

# Decomposition over frequency bands in the Waveform domain
bands = julius.split_bands(signal, n_bands=10, sample_rate=100)
# Decomposition with n_bands frequency bands evenly spaced in mel space.
# Input shape can be `[*, T]`, output will be `[n_bands, *, T]`.
random_eq = tf.reduce_sum(tf.random.uniform((10, 1, 1, 1)) * bands, axis=0)

Algorithms

Resample

This is an implementation of the sinc resample algorithm by Julius O. Smith. It is the same algorithm than the one used in resampy but to run efficiently on GPU it is limited to fractional changes of the sample rate. It will be fast if the old and new sample rate are small after dividing them by their GCD. For instance going from a sample rate of 2000 to 3000 (2, 3 after removing the GCD) will be extremely fast, while going from 20001 to 30001 will not. Julius resampling is faster than resampy even on CPU, and when running on GPU it makes resampling a completely negligible part of your pipeline (except of course for weird cases like going from a sample rate of 20001 to 30001).

FFTConv1d

Computing convolutions with very large kernels (>= 128) and a stride of 1 can be much faster using FFT. This implements the same API as tf.keras.layers.Conv1D / tf.nn.conv1d (using the channels-first [B, C, T] convention) but with a FFT backend. Dilation and groups are not supported. FFTConv will be faster on CPU even for relatively small tensors (a few dozen channels, kernel size of 128). On CUDA, due to the higher parallelism, regular convolution can be faster in many cases, but for kernel sizes above 128, for a large number of channels or batch size, FFTConv1d will eventually be faster (basically when you no longer have idle cores that can hide the true complexity of the operation).

LowPass

Classical Finite Impulse Reponse windowed sinc lowpass filter. It will use FFT convolutions automatically if the filter size is large enough. This is the basic block from which you can build high pass and band pass filters (see julius.filters).

Bands

Decomposition of a signal over frequency bands in the waveform domain. This can be useful for instance to perform parametric EQ (see Usage above).

Benchmarks

You can find speed tests (and comparisons to reference implementations) on the benchmark. The CPU benchmarks are run on a Mac Book Pro 2020, with a 2.4 GHz 8-core intel CPU i9. The GPUs benchmark are run on Nvidia V100 with 16GB of memory. We also compare the validity of our implementations, as compared to reference ones like resampy or tf.nn.conv1d.

Running tests

Clone this repository, then

pip3 install '.[dev]'
python3 -m unittest discover -s tests

To run the benchmarks:

pip3 install .[dev]'
python3 -m bench.gen

License

julius-tf is released under the MIT license, the same license as the original julius. The license retains the original copyright of Alexandre Défossez (2020) alongside the copyright for the TensorFlow port (2026). See LICENSE.

Credits

This project is a TensorFlow port of julius by Alexandre Défossez. All of the DSP algorithms, the overall design, and the public API originate from his original PyTorch implementation — full credit for the underlying work goes to him. This repository only re-implements those algorithms on top of TensorFlow.

Thanks

This package is named in the honor of Julius O. Smith, whose books and website were a gold mine of information for learning about DSP. Go checkout his website if you want to learn more about DSP.

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

julius_tf-0.1.0.tar.gz (24.2 kB view details)

Uploaded Source

Built Distribution

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

julius_tf-0.1.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file julius_tf-0.1.0.tar.gz.

File metadata

  • Download URL: julius_tf-0.1.0.tar.gz
  • Upload date:
  • Size: 24.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for julius_tf-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c5b86411529a45267013ca8f3241aaa6f572bbf6bedfe431a9dd66c1678f826d
MD5 2d57a7ff982ca914d011a77703f0d585
BLAKE2b-256 803b205c65404a61c60260218dc6806bda79f57b6b048c7c8e3a54c43dc73c5a

See more details on using hashes here.

File details

Details for the file julius_tf-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: julius_tf-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for julius_tf-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c868c5eb74ca8436a858cb23ef69c0369accdd8975ed3bf7db7d391b54fa957a
MD5 20da27d5d0201ff774ef8c887a9aa1a1
BLAKE2b-256 eed075a9d6c701c7bb69dddcce7895b2d57d558e14c6a221fe7da6a3e313555d

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