julius-tf 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ __pycache__
2
+ *.egg-info
3
+ build
4
+ env
5
+ env_old
6
+ dist
7
+ .ipynb_checkpoints
8
+ *.ipynb
9
+ .coverage
10
+ htmlcov
11
+ docs
@@ -0,0 +1,17 @@
1
+ Copyright 2020 Alexandre Défossez (original PyTorch implementation)
2
+ Copyright 2026 Clément Laroche (TensorFlow port)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: julius-tf
3
+ Version: 0.1.0
4
+ Summary: Nice DSP sweets: resampling, FFT Convolutions — a TensorFlow port of Alexandre Défossez's julius, differentiable and with GPU support.
5
+ Project-URL: Homepage, https://github.com/LarocheC/julius-tf
6
+ Project-URL: Repository, https://github.com/LarocheC/julius-tf
7
+ Project-URL: Original project (PyTorch), https://github.com/adefossez/julius
8
+ Author-email: Alexandre Défossez <alexandre.defossez@gmail.com>, Clément Laroche <clement.laroche@gmail.com>
9
+ Maintainer-email: Clément Laroche <clement.laroche@gmail.com>
10
+ License: MIT License
11
+ License-File: LICENSE
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Topic :: Multimedia :: Sound/Audio
14
+ Classifier: Topic :: Scientific/Engineering
15
+ Requires-Python: >=3.9.0
16
+ Requires-Dist: tensorflow>=2.11.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: coverage>=7.0; extra == 'dev'
19
+ Requires-Dist: flake8>=5.0; extra == 'dev'
20
+ Requires-Dist: mypy>=1.0; extra == 'dev'
21
+ Requires-Dist: numpy>=1.21; extra == 'dev'
22
+ Requires-Dist: pdoc3>=0.10; extra == 'dev'
23
+ Requires-Dist: resampy==0.4.3; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Julius, fast TensorFlow based DSP for audio and 1D signals
27
+
28
+ ![linter badge](https://github.com/LarocheC/julius-tf/workflows/linter/badge.svg)
29
+ ![tests badge](https://github.com/LarocheC/julius-tf/workflows/tests/badge.svg)
30
+ ![cov badge](https://github.com/LarocheC/julius-tf/workflows/cov%3E90%25/badge.svg)
31
+
32
+ Julius contains different Digital Signal Processing algorithms implemented
33
+ with TensorFlow, so that they are differentiable and available on GPU.
34
+ Note that all the modules implemented here can be used inside a `tf.function`.
35
+
36
+ > **`julius-tf` is a TensorFlow port of [`julius`](https://github.com/adefossez/julius),
37
+ > the PyTorch DSP library by [Alexandre Défossez](https://github.com/adefossez).** The DSP
38
+ > algorithms and the public API are his work; this project re-implements them on top of
39
+ > TensorFlow. See [Credits](#credits) for full attribution.
40
+
41
+ For now, I have implemented:
42
+
43
+ - [julius.resample](https://LarocheC.github.io/julius-tf/julius/resample.html): fast sinc resampling.
44
+ - [julius.fftconv](https://LarocheC.github.io/julius-tf/julius/fftconv.html): FFT based convolutions.
45
+ - [julius.lowpass](https://LarocheC.github.io/julius-tf/julius/lowpass.html): FIR low pass filter banks.
46
+ - [julius.filters](https://LarocheC.github.io/julius-tf/julius/filters.html): FIR high pass and band pass filters.
47
+ - [julius.bands](https://LarocheC.github.io/julius-tf/julius/bands.html): Decomposition of a waveform signal over mel-scale frequency bands.
48
+
49
+ Along that, you might found useful utilities in:
50
+
51
+ - [julius.core](https://LarocheC.github.io/julius-tf/julius/core.html): DSP related functions.
52
+ - [julius.utils](https://LarocheC.github.io/julius-tf/julius/utils.html): Generic utilities.
53
+
54
+ <p align="center">
55
+ <img src="./logo.png" alt="Representation of the convolutions filters used for the efficient resampling."
56
+ width="500px"></p>
57
+
58
+ ## News
59
+
60
+ - `julius-tf` ports the whole library from PyTorch to __TensorFlow__. The public API of the
61
+ original `julius` is preserved: modules are `tf.Module`s, callable just like before, and
62
+ usable inside a `tf.function`. The dated entries below are the upstream `julius` releases
63
+ whose behavior this port reproduces.
64
+ - 23/06/2026: __`julius-tf` 0.1.0:__ first release on PyPI — TensorFlow port reproducing
65
+ upstream `julius` 0.2.8. Install with `pip install julius-tf`.
66
+ - 03/06/2026: __`julius` 0.2.8 released:__: Switching to pyproject.toml, now requires python >= 3.9. Bug fix with -O flag (thanks @aiknownc)
67
+ - 19/09/2022: __`julius` 0.2.7 released:__: fixed ONNX compat (thanks @iver56). I know I missed the 0.2.6 one...
68
+ - 28/07/2021: __`julius` 0.2.5 released:__: support for setting a custom output length when resampling.
69
+ - 22/06/2021: __`julius` 0.2.4 released:__: adding highpass and band passfilters.
70
+ Extra linting and type checking of the code. New `unfold` implemention, up to
71
+ x6 faster FFT convolutions and more efficient memory usage.
72
+ - 26/01/2021: __`julius` 0.2.2 released:__ fixing normalization of filters in lowpass and resample to avoid very low frequencies to be leaked.
73
+ Switch from zero padding to replicate padding (uses first/last value instead of 0) to avoid discontinuities with strong artifacts.
74
+ - 20/01/2021: `julius` implementation of resampling is now officially <a href="https://github.com/pytorch/audio/pull/1087">part of Torchaudio.</a>
75
+
76
+ ## Installation
77
+
78
+ `julius-tf` requires python >= 3.9 and TensorFlow >= 2.11. To install:
79
+ ```bash
80
+ pip3 install -U julius-tf
81
+ ```
82
+ The import name stays `julius` (i.e. `pip install julius-tf` then `import julius`).
83
+
84
+
85
+ ## Usage
86
+
87
+ See the [Julius documentation][docs] for the usage of Julius. Hereafter you will find a few examples
88
+ to get you quickly started:
89
+
90
+ ```python3
91
+ import julius
92
+ import tensorflow as tf
93
+
94
+ signal = tf.random.normal((6, 4, 1024))
95
+ # Resample from a sample rate of 100 to 70. The old and new sample rate must be integers,
96
+ # and resampling will be fast if they form an irreductible fraction with small numerator
97
+ # and denominator (here 10 and 7). Any shape is supported, last dim is time.
98
+ resampled_signal = julius.resample_frac(signal, 100, 70)
99
+
100
+ # Low pass filter with a `0.1 * sample_rate` cutoff frequency.
101
+ low_freqs = julius.lowpass_filter(signal, 0.1)
102
+
103
+ # Fast convolutions with FFT, useful for large kernels
104
+ conv = julius.FFTConv1d(4, 10, 512)
105
+ convolved = conv(signal)
106
+
107
+ # Decomposition over frequency bands in the Waveform domain
108
+ bands = julius.split_bands(signal, n_bands=10, sample_rate=100)
109
+ # Decomposition with n_bands frequency bands evenly spaced in mel space.
110
+ # Input shape can be `[*, T]`, output will be `[n_bands, *, T]`.
111
+ random_eq = tf.reduce_sum(tf.random.uniform((10, 1, 1, 1)) * bands, axis=0)
112
+ ```
113
+
114
+ ## Algorithms
115
+
116
+ ### Resample
117
+
118
+ This is an implementation of the [sinc resample algorithm][resample] by Julius O. Smith.
119
+ It is the same algorithm than the one used in [resampy][resampy] but to run efficiently on GPU it
120
+ is limited to fractional changes of the sample rate. It will be fast if the old and new sample rate
121
+ 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)
122
+ will be extremely fast, while going from 20001 to 30001 will not.
123
+ Julius resampling is faster than resampy even on CPU, and when running on GPU it makes resampling a completely negligible part of your pipeline
124
+ (except of course for weird cases like going from a sample rate of 20001 to 30001).
125
+
126
+
127
+ ### FFTConv1d
128
+
129
+ Computing convolutions with very large kernels (>= 128) and a stride of 1 can be much faster
130
+ using FFT. This implements the same API as `tf.keras.layers.Conv1D` / `tf.nn.conv1d`
131
+ (using the channels-first `[B, C, T]` convention) but with a FFT backend. Dilation and groups
132
+ are not supported.
133
+ FFTConv will be faster on CPU even for relatively small tensors (a few dozen channels, kernel size
134
+ of 128). On CUDA, due to the higher parallelism, regular convolution can be faster in many cases,
135
+ but for kernel sizes above 128, for a large number of channels or batch size, FFTConv1d
136
+ will eventually be faster (basically when you no longer have idle cores that can hide
137
+ the true complexity of the operation).
138
+
139
+ ### LowPass
140
+
141
+ Classical Finite Impulse Reponse windowed sinc lowpass filter. It will use FFT convolutions automatically
142
+ if the filter size is large enough. This is the basic block from which you can build
143
+ high pass and band pass filters (see `julius.filters`).
144
+
145
+ ### Bands
146
+
147
+ Decomposition of a signal over frequency bands in the waveform domain. This can be useful for
148
+ instance to perform parametric EQ (see [Usage](#usage) above).
149
+
150
+ ## Benchmarks
151
+
152
+ You can find speed tests (and comparisons to reference implementations) on the
153
+ [benchmark][bench]. The CPU benchmarks are run on a Mac Book Pro 2020, with a 2.4 GHz
154
+ 8-core intel CPU i9. The GPUs benchmark are run on Nvidia V100 with 16GB of memory.
155
+ We also compare the validity of our implementations, as compared to reference ones like `resampy`
156
+ or `tf.nn.conv1d`.
157
+
158
+
159
+
160
+ ## Running tests
161
+
162
+ Clone this repository, then
163
+ ```bash
164
+ pip3 install '.[dev]'
165
+ python3 -m unittest discover -s tests
166
+ ```
167
+
168
+ To run the benchmarks:
169
+ ```
170
+ pip3 install .[dev]'
171
+ python3 -m bench.gen
172
+ ```
173
+
174
+
175
+ ## License
176
+
177
+ `julius-tf` is released under the MIT license, the same license as the original `julius`.
178
+ The license retains the original copyright of Alexandre Défossez (2020) alongside the
179
+ copyright for the TensorFlow port (2026). See [LICENSE](./LICENSE).
180
+
181
+ ## Credits
182
+
183
+ This project is a TensorFlow port of [`julius`](https://github.com/adefossez/julius) by
184
+ [**Alexandre Défossez**](https://github.com/adefossez). All of the DSP algorithms, the
185
+ overall design, and the public API originate from his original PyTorch implementation —
186
+ full credit for the underlying work goes to him. This repository only re-implements those
187
+ algorithms on top of TensorFlow.
188
+
189
+ - Original project: https://github.com/adefossez/julius (MIT, © 2020 Alexandre Défossez)
190
+ - TensorFlow port: Clément Laroche ([@LarocheC](https://github.com/LarocheC))
191
+
192
+ ## Thanks
193
+
194
+ This package is named in the honor of
195
+ [Julius O. Smith](https://ccrma.stanford.edu/~jos/),
196
+ whose books and website were a gold mine of information for learning about DSP. Go checkout his website if you want
197
+ to learn more about DSP.
198
+
199
+
200
+ [resample]: https://ccrma.stanford.edu/~jos/resample/resample.html
201
+ [resampy]: https://resampy.readthedocs.io/
202
+ [docs]: https://LarocheC.github.io/julius-tf/julius/index.html
203
+ [bench]: ./bench.md
@@ -0,0 +1,178 @@
1
+ # Julius, fast TensorFlow based DSP for audio and 1D signals
2
+
3
+ ![linter badge](https://github.com/LarocheC/julius-tf/workflows/linter/badge.svg)
4
+ ![tests badge](https://github.com/LarocheC/julius-tf/workflows/tests/badge.svg)
5
+ ![cov badge](https://github.com/LarocheC/julius-tf/workflows/cov%3E90%25/badge.svg)
6
+
7
+ Julius contains different Digital Signal Processing algorithms implemented
8
+ with TensorFlow, so that they are differentiable and available on GPU.
9
+ Note that all the modules implemented here can be used inside a `tf.function`.
10
+
11
+ > **`julius-tf` is a TensorFlow port of [`julius`](https://github.com/adefossez/julius),
12
+ > the PyTorch DSP library by [Alexandre Défossez](https://github.com/adefossez).** The DSP
13
+ > algorithms and the public API are his work; this project re-implements them on top of
14
+ > TensorFlow. See [Credits](#credits) for full attribution.
15
+
16
+ For now, I have implemented:
17
+
18
+ - [julius.resample](https://LarocheC.github.io/julius-tf/julius/resample.html): fast sinc resampling.
19
+ - [julius.fftconv](https://LarocheC.github.io/julius-tf/julius/fftconv.html): FFT based convolutions.
20
+ - [julius.lowpass](https://LarocheC.github.io/julius-tf/julius/lowpass.html): FIR low pass filter banks.
21
+ - [julius.filters](https://LarocheC.github.io/julius-tf/julius/filters.html): FIR high pass and band pass filters.
22
+ - [julius.bands](https://LarocheC.github.io/julius-tf/julius/bands.html): Decomposition of a waveform signal over mel-scale frequency bands.
23
+
24
+ Along that, you might found useful utilities in:
25
+
26
+ - [julius.core](https://LarocheC.github.io/julius-tf/julius/core.html): DSP related functions.
27
+ - [julius.utils](https://LarocheC.github.io/julius-tf/julius/utils.html): Generic utilities.
28
+
29
+ <p align="center">
30
+ <img src="./logo.png" alt="Representation of the convolutions filters used for the efficient resampling."
31
+ width="500px"></p>
32
+
33
+ ## News
34
+
35
+ - `julius-tf` ports the whole library from PyTorch to __TensorFlow__. The public API of the
36
+ original `julius` is preserved: modules are `tf.Module`s, callable just like before, and
37
+ usable inside a `tf.function`. The dated entries below are the upstream `julius` releases
38
+ whose behavior this port reproduces.
39
+ - 23/06/2026: __`julius-tf` 0.1.0:__ first release on PyPI — TensorFlow port reproducing
40
+ upstream `julius` 0.2.8. Install with `pip install julius-tf`.
41
+ - 03/06/2026: __`julius` 0.2.8 released:__: Switching to pyproject.toml, now requires python >= 3.9. Bug fix with -O flag (thanks @aiknownc)
42
+ - 19/09/2022: __`julius` 0.2.7 released:__: fixed ONNX compat (thanks @iver56). I know I missed the 0.2.6 one...
43
+ - 28/07/2021: __`julius` 0.2.5 released:__: support for setting a custom output length when resampling.
44
+ - 22/06/2021: __`julius` 0.2.4 released:__: adding highpass and band passfilters.
45
+ Extra linting and type checking of the code. New `unfold` implemention, up to
46
+ x6 faster FFT convolutions and more efficient memory usage.
47
+ - 26/01/2021: __`julius` 0.2.2 released:__ fixing normalization of filters in lowpass and resample to avoid very low frequencies to be leaked.
48
+ Switch from zero padding to replicate padding (uses first/last value instead of 0) to avoid discontinuities with strong artifacts.
49
+ - 20/01/2021: `julius` implementation of resampling is now officially <a href="https://github.com/pytorch/audio/pull/1087">part of Torchaudio.</a>
50
+
51
+ ## Installation
52
+
53
+ `julius-tf` requires python >= 3.9 and TensorFlow >= 2.11. To install:
54
+ ```bash
55
+ pip3 install -U julius-tf
56
+ ```
57
+ The import name stays `julius` (i.e. `pip install julius-tf` then `import julius`).
58
+
59
+
60
+ ## Usage
61
+
62
+ See the [Julius documentation][docs] for the usage of Julius. Hereafter you will find a few examples
63
+ to get you quickly started:
64
+
65
+ ```python3
66
+ import julius
67
+ import tensorflow as tf
68
+
69
+ signal = tf.random.normal((6, 4, 1024))
70
+ # Resample from a sample rate of 100 to 70. The old and new sample rate must be integers,
71
+ # and resampling will be fast if they form an irreductible fraction with small numerator
72
+ # and denominator (here 10 and 7). Any shape is supported, last dim is time.
73
+ resampled_signal = julius.resample_frac(signal, 100, 70)
74
+
75
+ # Low pass filter with a `0.1 * sample_rate` cutoff frequency.
76
+ low_freqs = julius.lowpass_filter(signal, 0.1)
77
+
78
+ # Fast convolutions with FFT, useful for large kernels
79
+ conv = julius.FFTConv1d(4, 10, 512)
80
+ convolved = conv(signal)
81
+
82
+ # Decomposition over frequency bands in the Waveform domain
83
+ bands = julius.split_bands(signal, n_bands=10, sample_rate=100)
84
+ # Decomposition with n_bands frequency bands evenly spaced in mel space.
85
+ # Input shape can be `[*, T]`, output will be `[n_bands, *, T]`.
86
+ random_eq = tf.reduce_sum(tf.random.uniform((10, 1, 1, 1)) * bands, axis=0)
87
+ ```
88
+
89
+ ## Algorithms
90
+
91
+ ### Resample
92
+
93
+ This is an implementation of the [sinc resample algorithm][resample] by Julius O. Smith.
94
+ It is the same algorithm than the one used in [resampy][resampy] but to run efficiently on GPU it
95
+ is limited to fractional changes of the sample rate. It will be fast if the old and new sample rate
96
+ 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)
97
+ will be extremely fast, while going from 20001 to 30001 will not.
98
+ Julius resampling is faster than resampy even on CPU, and when running on GPU it makes resampling a completely negligible part of your pipeline
99
+ (except of course for weird cases like going from a sample rate of 20001 to 30001).
100
+
101
+
102
+ ### FFTConv1d
103
+
104
+ Computing convolutions with very large kernels (>= 128) and a stride of 1 can be much faster
105
+ using FFT. This implements the same API as `tf.keras.layers.Conv1D` / `tf.nn.conv1d`
106
+ (using the channels-first `[B, C, T]` convention) but with a FFT backend. Dilation and groups
107
+ are not supported.
108
+ FFTConv will be faster on CPU even for relatively small tensors (a few dozen channels, kernel size
109
+ of 128). On CUDA, due to the higher parallelism, regular convolution can be faster in many cases,
110
+ but for kernel sizes above 128, for a large number of channels or batch size, FFTConv1d
111
+ will eventually be faster (basically when you no longer have idle cores that can hide
112
+ the true complexity of the operation).
113
+
114
+ ### LowPass
115
+
116
+ Classical Finite Impulse Reponse windowed sinc lowpass filter. It will use FFT convolutions automatically
117
+ if the filter size is large enough. This is the basic block from which you can build
118
+ high pass and band pass filters (see `julius.filters`).
119
+
120
+ ### Bands
121
+
122
+ Decomposition of a signal over frequency bands in the waveform domain. This can be useful for
123
+ instance to perform parametric EQ (see [Usage](#usage) above).
124
+
125
+ ## Benchmarks
126
+
127
+ You can find speed tests (and comparisons to reference implementations) on the
128
+ [benchmark][bench]. The CPU benchmarks are run on a Mac Book Pro 2020, with a 2.4 GHz
129
+ 8-core intel CPU i9. The GPUs benchmark are run on Nvidia V100 with 16GB of memory.
130
+ We also compare the validity of our implementations, as compared to reference ones like `resampy`
131
+ or `tf.nn.conv1d`.
132
+
133
+
134
+
135
+ ## Running tests
136
+
137
+ Clone this repository, then
138
+ ```bash
139
+ pip3 install '.[dev]'
140
+ python3 -m unittest discover -s tests
141
+ ```
142
+
143
+ To run the benchmarks:
144
+ ```
145
+ pip3 install .[dev]'
146
+ python3 -m bench.gen
147
+ ```
148
+
149
+
150
+ ## License
151
+
152
+ `julius-tf` is released under the MIT license, the same license as the original `julius`.
153
+ The license retains the original copyright of Alexandre Défossez (2020) alongside the
154
+ copyright for the TensorFlow port (2026). See [LICENSE](./LICENSE).
155
+
156
+ ## Credits
157
+
158
+ This project is a TensorFlow port of [`julius`](https://github.com/adefossez/julius) by
159
+ [**Alexandre Défossez**](https://github.com/adefossez). All of the DSP algorithms, the
160
+ overall design, and the public API originate from his original PyTorch implementation —
161
+ full credit for the underlying work goes to him. This repository only re-implements those
162
+ algorithms on top of TensorFlow.
163
+
164
+ - Original project: https://github.com/adefossez/julius (MIT, © 2020 Alexandre Défossez)
165
+ - TensorFlow port: Clément Laroche ([@LarocheC](https://github.com/LarocheC))
166
+
167
+ ## Thanks
168
+
169
+ This package is named in the honor of
170
+ [Julius O. Smith](https://ccrma.stanford.edu/~jos/),
171
+ whose books and website were a gold mine of information for learning about DSP. Go checkout his website if you want
172
+ to learn more about DSP.
173
+
174
+
175
+ [resample]: https://ccrma.stanford.edu/~jos/resample/resample.html
176
+ [resampy]: https://resampy.readthedocs.io/
177
+ [docs]: https://LarocheC.github.io/julius-tf/julius/index.html
178
+ [bench]: ./bench.md
@@ -0,0 +1,6 @@
1
+ """
2
+ This package contains benchmarking code.
3
+ The following content is automatically generated from `bench.gen`
4
+
5
+ .. include:: ../bench.md
6
+ """
@@ -0,0 +1,46 @@
1
+ # File under the MIT license, see the LICENSE file for details.
2
+ # Original author: Alexandre Défossez (adefossez), 2020
3
+ # TensorFlow port: Clément Laroche (LarocheC), 2026
4
+
5
+ import argparse
6
+
7
+ import tensorflow as tf
8
+
9
+ from julius import fft_conv1d
10
+ from julius.core import conv1d
11
+ from julius.utils import Chrono, MarkdownTable
12
+
13
+
14
+ def test(table, kernel_size, block_ratio=5, device="cpu"):
15
+ tf_device = "/GPU:0" if device == "cuda" else "/CPU:0"
16
+ with tf.device(tf_device):
17
+ x = tf.random.normal((32, 32, 1024 * 10))
18
+ w = tf.random.normal((64, 32, kernel_size))
19
+
20
+ with Chrono() as chrono_ref:
21
+ y_ref = conv1d(x, w)
22
+
23
+ with Chrono() as chrono_fft:
24
+ y_fft = fft_conv1d(x, w, block_ratio=block_ratio)
25
+
26
+ delta = format(float(tf.reduce_mean(tf.abs(y_ref - y_fft))), ".1e")
27
+ table.line(
28
+ [kernel_size, int(1000 * chrono_fft.duration), int(1000 * chrono_ref.duration), delta])
29
+
30
+
31
+ def main():
32
+ parser = argparse.ArgumentParser("fftconv.py")
33
+ parser.add_argument("-d", "--device", default="cpu")
34
+ parser.add_argument("-b", "--block_ratio", default=5, type=float)
35
+ args = parser.parse_args()
36
+
37
+ table = MarkdownTable(
38
+ ["Kernel size", "FFT (ms)", "No FFT (ms)", " Delta"])
39
+ table.header()
40
+
41
+ for kernel_size in [8, 32, 64, 128, 256, 1024, 2048]:
42
+ test(table, kernel_size, block_ratio=args.block_ratio, device=args.device)
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
@@ -0,0 +1,70 @@
1
+ import subprocess as sp
2
+ import tensorflow as tf
3
+
4
+
5
+ def run_bench(name, *args, device="cpu"):
6
+ args = list(args)
7
+ args += ["-d", device]
8
+ if device == "cuda" and not tf.config.list_physical_devices('GPU'):
9
+ return "Not available /!\\"
10
+ return sp.check_output(["python3", "-m", f"bench.{name}"] + args).decode('utf8')
11
+
12
+
13
+ def main():
14
+ template = f"""\
15
+ ## Benchmarking and verification of Julius
16
+
17
+ In order to verify the correctness and speed of the implementations in Julius,
18
+ we compare ourselves to different reference implementations, comparing speed and
19
+ checking how far we are.
20
+
21
+ ### ResampleFrac
22
+
23
+ We compare `julius.resample` to `resampy`, on an input of size (32, 8 * 44100),
24
+ i.e. a batch of size 16 of 8 second of audio at 44.1kHz.
25
+ We use the same number of zero crossing as `resampy` for this benchmark.
26
+ The small delta is probably
27
+ due to the different window function used.
28
+
29
+
30
+ On CPU we have:
31
+
32
+ {run_bench('resample')}
33
+
34
+ On GPU we have:
35
+
36
+ {run_bench('resample', device='cuda')}
37
+
38
+ ### FFTConv1d
39
+
40
+ We compare to `tf.nn.conv1d`, on a input of size [32, 32, 10240],
41
+ for a convolution with 32 input channels, 64 output channels and various kernel sizes.
42
+
43
+ On CPU we have:
44
+
45
+ {run_bench('fftconv')}
46
+
47
+ On GPU we have:
48
+
49
+ {run_bench('fftconv', device='cuda')}
50
+
51
+ ### LowPassFilter
52
+
53
+ We do not compare to anything, but measure the attenuation in dB of a pure tone
54
+ at `0.9 * cutoff`, at the `cutoff`, and at `1.1 * cutoff`.
55
+ Note that our implementation automatically choses to use FFTConv1d or not when appropriate.
56
+
57
+ On CPU we have:
58
+
59
+ {run_bench('lowpass')}
60
+
61
+ On GPU we have:
62
+
63
+ {run_bench('lowpass', device='cuda')}
64
+
65
+ """
66
+ print(template)
67
+
68
+
69
+ if __name__ == "__main__":
70
+ main()
@@ -0,0 +1,45 @@
1
+ # File under the MIT license, see the LICENSE file for details.
2
+ # Original author: Alexandre Défossez (adefossez), 2020
3
+ # TensorFlow port: Clément Laroche (LarocheC), 2026
4
+
5
+ import argparse
6
+
7
+ import tensorflow as tf
8
+
9
+ from julius import lowpass_filter
10
+ from julius.core import pure_tone, volume
11
+ from julius.utils import Chrono, MarkdownTable
12
+
13
+
14
+ def test(table, freq, zeros, fft=None, device="cpu"):
15
+ sr = 44_100
16
+ tf_device = "/GPU:0" if device == "cuda" else "/CPU:0"
17
+
18
+ attns = []
19
+ for ratio in [0.9, 1, 1.1]:
20
+ with tf.device(tf_device):
21
+ x = pure_tone(ratio * freq * sr, sr, 4)
22
+ with Chrono() as chrono:
23
+ y = lowpass_filter(x, freq, fft=fft, zeros=zeros)
24
+ attns.append(format(float(volume(y) - volume(x)), ".2f"))
25
+
26
+ table.line([freq] + attns + [int(1000 * chrono.duration)])
27
+
28
+
29
+ def main():
30
+ parser = argparse.ArgumentParser("lowpass.py")
31
+ parser.add_argument("-d", "--device", default="cpu")
32
+ parser.add_argument("--fft", action="store_true", default=None)
33
+ parser.add_argument("--no_fft", action="store_false", dest="fft")
34
+ parser.add_argument("--zeros", default=8, type=float)
35
+ args = parser.parse_args()
36
+
37
+ table = MarkdownTable(
38
+ ["Freq.", "Attn. 0.9 (dB)", "Attn 1.0 (dB)", "Attn 1.1 (dB)", "Time (ms)"])
39
+ table.header()
40
+ for freq in [0.005, 0.01, 0.1, 0.2, 0.4]:
41
+ test(table, freq, zeros=args.zeros, fft=args.fft, device=args.device)
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -0,0 +1,53 @@
1
+ # File under the MIT license, see the LICENSE file for details.
2
+ # Original author: Alexandre Défossez (adefossez), 2020
3
+ # TensorFlow port: Clément Laroche (LarocheC), 2026
4
+
5
+ import argparse
6
+ import math
7
+
8
+ import resampy
9
+ import tensorflow as tf
10
+
11
+ from julius import resample_frac
12
+ from julius.utils import Chrono, MarkdownTable
13
+
14
+
15
+ def test(table, old_sr, new_sr, device="cpu"):
16
+ tf_device = "/GPU:0" if device == "cuda" else "/CPU:0"
17
+ with tf.device(tf_device):
18
+ x = tf.random.normal((16, 8 * old_sr * int(math.ceil(44_100 / old_sr))))
19
+
20
+ with Chrono() as chrono:
21
+ y = resample_frac(x, old_sr, new_sr, zeros=56)
22
+ dur_julius = int(1000 * chrono.duration)
23
+
24
+ if device == "cpu":
25
+ with Chrono() as chrono:
26
+ y_resampy = tf.constant(
27
+ resampy.resample(x.numpy(), old_sr, new_sr), dtype=tf.float32)
28
+ dur_resampy = int(1000 * chrono.duration)
29
+
30
+ delta = float(tf.reduce_mean(tf.abs(y_resampy - y)))
31
+ table.line([old_sr, new_sr, dur_julius, dur_resampy, format(delta, ".1%")])
32
+ else:
33
+ table.line([old_sr, new_sr, dur_julius])
34
+
35
+
36
+ def main():
37
+ parser = argparse.ArgumentParser("resample.py")
38
+ parser.add_argument("-d", "--device", default="cpu")
39
+ args = parser.parse_args()
40
+
41
+ if args.device == "cpu":
42
+ table = MarkdownTable(["Old sr", "New sr", "Julius (ms)", "Resampy (ms)", "Delta (%)"])
43
+ else:
44
+ table = MarkdownTable(["Old sr", "New sr", "Julius (ms)"])
45
+ table.header()
46
+
47
+ rates = [(2, 1), (1, 2), (4, 5), (10, 11), (44100, 16000), (20001, 30001)]
48
+ for old_sr, new_sr in rates:
49
+ test(table, old_sr, new_sr, device=args.device)
50
+
51
+
52
+ if __name__ == "__main__":
53
+ main()
@@ -0,0 +1,42 @@
1
+ # File under the MIT license, see the LICENSE file for details.
2
+ # Original author: Alexandre Défossez (adefossez), 2020
3
+ # TensorFlow port: Clément Laroche (LarocheC), 2026
4
+
5
+ # flake8: noqa
6
+ """
7
+ .. image:: ../logo.png
8
+
9
+ Julius contains different Digital Signal Processing algorithms implemented
10
+ with TensorFlow, so that they are differentiable and available on GPU.
11
+ Note that all the modules implemented here can be used inside a `tf.function`.
12
+
13
+ For now, I have implemented:
14
+
15
+ - `julius.resample`: fast sinc resampling.
16
+ - `julius.fftconv`: FFT based convolutions.
17
+ - `julius.lowpass`: FIR low pass filter banks.
18
+ - `julius.filters`: FIR high pass and band pass filters.
19
+ - `julius.bands`: Decomposition of a waveform signal over mel-scale frequency bands.
20
+
21
+ Along that, you might found useful utilities in:
22
+
23
+ - `julius.core`: DSP related functions.
24
+ - `julius.utils`: Generic utilities.
25
+
26
+
27
+ Please checkout [the Github repository](https://github.com/LarocheC/julius-tf) for other informations.
28
+ For a verification of the speed and correctness of Julius, check the benchmark module `bench`.
29
+
30
+
31
+ This package is named in this honor of
32
+ [Julius O. Smith](https://ccrma.stanford.edu/~jos/),
33
+ whose books and website were a gold mine of information for me to learn about DSP. Go checkout his website if you want
34
+ to learn more about DSP.
35
+ """
36
+
37
+ from .bands import SplitBands, split_bands
38
+ from .fftconv import fft_conv1d, FFTConv1d
39
+ from .filters import bandpass_filter, BandPassFilter
40
+ from .filters import highpass_filter, highpass_filters, HighPassFilter, HighPassFilters
41
+ from .lowpass import lowpass_filter, lowpass_filters, LowPassFilters, LowPassFilter
42
+ from .resample import resample_frac, ResampleFrac