Python bindings for Rubber Band audio pitch shifting and time stretching
Project description
➰ rubband: tensor-friendly bindings to the C++ Rubber Band pitch shifting library ➰
What is this?
Rubber Band is a popular GPL C++ library for pitch shifting and time stretching with a long history, but all the Python bindings for it are old and unsupported.
This new one uses nanobind for the bindings, and DLPack to interoperate with all common tensor types.
You wrote this rather fast. Is this AI slop?
I first started writing digital audio programs in the late 1970s, and I've written a pretty huge number of programs of all types since then - here's some recent stuff. - and until June of 2026, every bit (hah!) was done by hand.
rubband is my first entirely "vibe coded" library. While I carefully guided it at each
point, backed up and tried again a couple of times, and reviewed every line, the code
and all the documentation except this part was written by Codex.
I was positively surprised by the quality, and I think it is quite acceptable. There are copious tests, and I am very responsive to issues filed.
If you're human, why is there an emoji in the description of this project??
I've been using emojis in project descriptions for about six years. They learned it from me.
Nothing below this line was written by a person.
Public release notes
The first public release is intended to be a practical, minimal binding to the Rubber Band stretcher. The Python package wraps the native Rubber Band library; it does not bundle Rubber Band itself.
Installation
Install the platform Rubber Band library first, then install rubband.
On macOS:
brew install rubberband pkg-config
pip install rubband
On Linux, Rubber Band API 3.0 or newer is required. Many stable distributions still package older Rubber Band headers, so build and install Rubber Band 4.x first if your distribution package is too old:
sudo apt-get update
sudo apt-get install -y build-essential curl meson ninja-build pkg-config
curl -L --fail --silent --show-error \
https://github.com/breakfastquay/rubberband/archive/refs/tags/v4.0.0.tar.gz \
| tar -xz
cd rubberband-4.0.0
meson setup build -Dauto_features=disabled -Ddefault_library=shared
ninja -C build
sudo ninja -C build install
sudo ldconfig
pip install rubband
On Windows, install Rubber Band with vcpkg before building from source:
vcpkg install rubberband:x64-windows
$env:CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
pip install rubband
Input contract
Audio input must be:
- CPU memory
- contiguous
float32- mono shape
(frames,)or multichannel shape(frames, channels) - exposed through DLPack or the Python buffer protocol
This means contiguous NumPy arrays, PyTorch CPU tensors, array.array("f"),
and memoryview objects can work. CUDA tensors, non-contiguous views, and
non-float32 arrays are rejected.
Output contract
stretch() and Stretcher.retrieve() return an AudioBuffer.
output = rubband.stretch(audio, 48_000, pitch_scale=2.0)
output.dtype # "float32"
output.shape # (frames,) or (frames, channels)
output.frames
output.channels
output.memoryview()
The conversion helpers are optional and import their array libraries lazily:
numpy_audio = output.numpy()
torch_audio = output.torch()
NumPy and PyTorch are development/test dependencies, not runtime dependencies.
Minimal examples
With the Python standard library:
from array import array
import rubband
audio = array("f", [0.0] * 48_000)
output = rubband.stretch(audio, 48_000, time_ratio=1.25, pitch_scale=1.0)
samples = output.memoryview()
With NumPy:
import numpy as np
import rubband
audio = np.zeros(48_000, dtype=np.float32)
output = rubband.stretch(audio, 48_000, pitch_scale=2.0)
numpy_audio = output.numpy()
With PyTorch CPU tensors:
import torch
import rubband
audio = torch.zeros(48_000, dtype=torch.float32)
output = rubband.stretch(audio, 48_000, pitch_scale=0.5)
torch_audio = output.torch()
For stateful processing:
import rubband
stretcher = rubband.Stretcher(
48_000,
1,
options=rubband.Options(process=rubband.ProcessOption.real_time),
)
stretcher.process(audio, final=True)
output = stretcher.retrieve()
Platform support
Release builds are configured for:
- macOS
- Linux
- Windows
Each platform wheel is built and smoke-tested in GitHub Actions against the
Rubber Band library installed by that platform's package manager or vcpkg.
If a platform-specific release artifact is missing, that platform should be
treated as unsupported for that release.
Documentation
Generated API documentation is published at:
https://rec.github.io/rubband/
License
rubband is licensed under GPL-2.0-or-later. The repository contains the GPL
2.0 license text in LICENSE, and pyproject.toml uses the
GPL-2.0-or-later SPDX identifier.
Rubber Band is a separate native library with its own GPL-compatible license
terms. Users must have the Rubber Band library available at build and runtime
and must comply with Rubber Band's license when building, linking,
distributing, or deploying software that uses rubband.
Known limitations
- Audio input must be CPU, contiguous,
float32memory. - GPU tensors are not supported.
- The Rubber Band native library must be installed separately.
- Dynamic ratio changes are for real-time
Stretcheruse. Offline stretchers reject ratio changes afterstudy()orprocess()starts.
Local release checklist
Before tagging a public release, run:
uv run ruff check --fix --select B,E,F,I rubband tests scripts
uv run ruff format rubband tests scripts
uv run ty check rubband
find tests rubband scripts -name '*.py' | xargs uv run pyupgrade --py311-plus
uv run pytest
uv run mkdocs build --strict
uv build --sdist --wheel --out-dir dist
uv run python scripts/smoke_wheel.py dist/rubband-*.whl
Then confirm the release workflow is green on macOS, Linux, and Windows after pushing the release tag.
Initial release highlights
- Python 3.11+.
- Rubber Band-backed time stretching and pitch shifting.
- Stateful
StretcherAPI close to Rubber Band's original model. - DLPack and Python buffer protocol input support.
- NumPy is not required at runtime.
- PyTorch CPU tensors are supported when PyTorch is installed.
AudioBufferoutput wrapper withmemoryview(),numpy(), andtorch()conversion helpers.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rubband-0.2.2.tar.gz.
File metadata
- Download URL: rubband-0.2.2.tar.gz
- Upload date:
- Size: 6.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f8336ebd584a9a6d5fb475ef29c7e8b492ab78c46f55cb734d2c611cd203734
|
|
| MD5 |
c6e84c808e0d8df93b325ea777ac5372
|
|
| BLAKE2b-256 |
13bc3028f5da532cdb1d802bd0676b6d388296c3b320913f5fedef625804b760
|
File details
Details for the file rubband-0.2.2-cp311-cp311-macosx_14_0_arm64.whl.
File metadata
- Download URL: rubband-0.2.2-cp311-cp311-macosx_14_0_arm64.whl
- Upload date:
- Size: 76.5 kB
- Tags: CPython 3.11, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76d83c825aaebe02e78f469602c5ccc34add44e48306dda7c6d55605480ab974
|
|
| MD5 |
2759af63a5d5699285b6d82e1e80af6e
|
|
| BLAKE2b-256 |
09f8788800588ca8d7aab231bc6e9a99b2b7cb043c91a12aa35c3d20fa00614f
|