FFTConvolve
Convolution along the last axis via the FFT, built on rfft / irfft (or the
complex pair when either input is complex). O(n log n) instead of O(n·m):
the fast path for long kernels like room impulse responses.
specux.fftconvolve(a, b, mode="full", backend="auto")x = np.random.randn(48000).astype(np.float32)impulse_response = np.random.randn(8000).astype(np.float32)wet = specux.fftconvolve(x, impulse_response, mode="same") # reverb, x's length
specux.fftconvolve(np.ones(4), np.ones(3))# array([1., 2., 3., 3., 2., 1.])mode="full": the wholen + m - 1response.mode="same": the central part, the size ofa.mode="valid": only samples with full overlap.
Leading dimensions broadcast; the transforms pad to an even 5-smooth length
internally. Differentiable end to end on torch (gradients flow to both
inputs), resident on the GPU for torch/cupy inputs: CUDA, and Metal on both
mps transports (DLPack from torch 2.9, compile_shader on 2.7/2.8),
forward and backward.
The configured form
x = np.random.randn(48000).astype(np.float32)impulse_response = np.random.randn(8000).astype(np.float32)reverb = specux.FFTConvolve(mode="same")wet = reverb(x, impulse_response)