Skip to main content

🎵 sound_rs

sound_rs is a fast, Rust-powered audio library for Python that I built and maintain — decoding with symphonia (plus minimp3 for MP3), resampling with rubato, output through cpal.


🚀 Features

  • Formats: WAV, MP3, FLAC, OGG/Vorbis, M4A, AAC — any bit depth, including 24-bit
  • Streaming playback: a two-hour file costs ~4 MB of RAM, not gigabytes, and the first sound arrives in ~9 ms instead of after the whole decode
  • Player: one output stream stays open — play, pause, resume, seek, stop, volume, position, duration
  • Decode to NumPy: load(path) -> (ndarray, sample_rate), shape (frames, channels)
  • Parallel decode: load_many(paths) uses every core, with the GIL released
  • Gapless (MP3, OGG, AAC/MP4): encoder delay and padding are trimmed, so decoded audio lines up with the original
  • Fast metadata: get_audio_info reads the container header, ~1 ms regardless of file length
  • Resampling: rubato's FFT resampler with a proper anti-aliasing filter
  • Device-native output: the stream opens in whatever sample format the device wants (f32, f64, i16, i32, u8, u16)
  • Errors: everything raises sound_rs.SoundRsError (a RuntimeError subclass)

🧠 Installation

pip install sound_rs

Wheels are built for Linux (x86_64), Windows (amd64) and macOS (arm64) for Python 3.10–3.14. Other platforms build from source.


💻 Usage

One-shot playback

import sound_rs

sound_rs.play_audio("sound.wav")          # blocks, GIL released
sound_rs.play_audio("sound.mp3", device="MacBook Pro Speakers")

The player

import sound_rs

with sound_rs.Player() as player:
    player.play_file("music.flac")   # returns immediately, streams from disk
    player.volume = 0.7
    player.seek(42.0)
    player.pause()
    player.resume()
    print(player.position, player.duration)
    player.wait()                    # block until it ends

sound_rs.list_devices()              # [(0, "MacBook Pro Speakers", True), ...]

Inspect and decode

sample_rate, channels, duration = sound_rs.get_audio_info("music.mp3")  # no decode
audio, rate = sound_rs.load("music.flac")                               # (frames, channels) float32

pairs = sound_rs.load_many(["a.flac", "b.flac", "c.flac"])              # parallel

From a NumPy array

import numpy as np

rate = 44100
t = np.linspace(0, 2.0, rate * 2, endpoint=False, dtype=np.float32)
sound_rs.play_array(np.sin(2 * np.pi * 440 * t), rate)   # mono, 1D
sound_rs.play_array(np.stack([left, right]), rate)       # 2D, channels first
sound_rs.play_sine_wave(440.0, 1.0, 44100)

🧩 Benchmark

Every measurement runs in its own process: peak RSS is process-wide, so timing and memory cannot share one. Median and p95 over repeated runs, competitors run side by side on the same files.

python bench/run.py                 # sound_rs only
python bench/run.py --compare       # + soundfile / sounddevice
python bench/run.py --reps 9

Hardware I measured on: Apple M5 Pro, macOS 26.6.2, Python 3.14.7, release build (lto = "fat", opt-level = 3). Competitors: libsndfile 1.2 (soundfile 0.14), PortAudio (sounddevice). Corpus: 3 s and 10 min stereo 44.1 kHz, generated by the harness.

Scoreboard — every axis in this section, side by side:

axis sound_rs best competitor ratio
import 1.1 ms 31.8 ms (soundfile) 29×
metadata (60 s file) 1.2 ms 31.7 ms (soundfile) 26×
decode WAV 131 ms 155 ms 1.2×
decode FLAC 265 ms 465 ms 1.8×
decode MP3 247 ms 272 ms 1.1×
decode AAC 361 ms not supported —
time to first sound (10 min) 8.8 ms 492 ms 56×
peak RAM (10 min file) 43 MB 255 MB 6×
playback overhead 32 ms 148 ms 4.6×
batch decode (2 files) 272 ms 448 ms 1.6×

Import time (cold process):

time peak RSS
sound_rs 1.1 ms 25 MB
soundfile 31.8 ms 34 MB
sounddevice 75.3 ms 32 MB

Metadata (60 s file): sound_rs 1.2 ms, soundfile 31.7 ms.

Decode 60 s stereo, median / p95:

format sound_rs libsndfile result PCM check
WAV 131 / 160 ms 155 ms 1.2× faster identical
FLAC 265 / 267 ms 465 ms 1.8× faster identical
MP3 247 / 249 ms 272 ms 1.1× faster 1.6e-05, 47-sample offset
M4A (AAC) 361 / 365 ms unsupported sound_rs only matches ffmpeg to 8e-08

Streaming a 10-minute FLAC — time to the first sound and peak memory:

first sound peak RSS
sound_rs Player 8.8 ms 43 MB
soundfile + sounddevice 492 ms 255 MB

Playback of a 3 s tone — overhead over the track duration:

overhead
sound_rs Player (stream kept open) +32 ms
sounddevice.play (opens a stream per call) +148 ms
sound_rs.play_array (one-shot, opens a stream) +182 ms

Batch decode two FLAC files: load_many 272 ms vs a soundfile loop 448 ms.

What the numbers do not hide:

  • MP3 output is offset by 47 samples (~1 ms) versus libsndfile and ffmpeg. Sample values agree to 1.6e-05 once aligned; the offset comes from how the decoder delay is trimmed, and the length matches exactly.
  • WAV decode is a memcpy race with libsndfile; the gap there is small by nature, the real wins are FLAC, metadata, memory and latency.
  • AAC decoding is slower than everything else — it is a newer, less tuned decoder — but libsndfile cannot read AAC at all.

🛠️ Roadmap

Step Feature Description
✅ 1 Playback + formats WAV, MP3, FLAC, OGG, M4A, 24-bit
✅ 2 NumPy integration 1D/2D arrays, load, load_many
✅ 3 Player Persistent stream: pause, seek, volume, position
✅ 4 Streaming decode Constant memory, ~9 ms to first sound
🔜 5 Device selection UI Input devices, hot-swap on disconnect
🔜 6 Recording Microphone to array or WAV
🔜 7 Effects Basic gain/fade/mix utilities

🧪 Development

cargo test                      # resampler, channel conversion, gapless, seek
maturin develop --release       # build into your venv
python tests/smoke.py           # end-to-end decode + API checks
SOUND_RS_PLAY=1 python tests/smoke.py   # also plays (needs an audio device)
python bench/run.py --compare   # full benchmark

⚙️ Built With

  • 🦀 Rust — performance and safety
  • 🔗 PyO3 — Python bridge
  • 🧰 Maturin — building and publishing
  • 🔊 cpal, symphonia, minimp3, rubato — output, decoding, resampling

👨‍💻 Author

Nurassyl Mussainov Kazakhstan 🇰🇿 Python / Rust Developer

🔗 GitHub: Neksand 📦 PyPI: sound_rs


📜 License

Licensed under the MIT License — free for personal and commercial use.

Metadata

Release files for sound-rs 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sound-rs 0.2.0
File Size Uploaded Provenance Actions
sound_rs-0.2.0.tar.gz 44.6 kB Without provenance Details for sound_rs-0.2.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for sound-rs 0.2.0
File Actions
sound_rs-0.2.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details for sound_rs-0.2.0-cp314-cp314-win_amd64.whl
sound_rs-0.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ x86-64 Details for sound_rs-0.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
sound_rs-0.2.0-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details for sound_rs-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
sound_rs-0.2.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details for sound_rs-0.2.0-cp313-cp313-win_amd64.whl
sound_rs-0.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details for sound_rs-0.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
sound_rs-0.2.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details for sound_rs-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
sound_rs-0.2.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details for sound_rs-0.2.0-cp312-cp312-win_amd64.whl
sound_rs-0.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details for sound_rs-0.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
sound_rs-0.2.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details for sound_rs-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
sound_rs-0.2.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details for sound_rs-0.2.0-cp311-cp311-win_amd64.whl
sound_rs-0.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details for sound_rs-0.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
sound_rs-0.2.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for sound_rs-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
sound_rs-0.2.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details for sound_rs-0.2.0-cp310-cp310-win_amd64.whl
sound_rs-0.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details for sound_rs-0.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
sound_rs-0.2.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details for sound_rs-0.2.0-cp310-cp310-macosx_11_0_arm64.whl

Total release size: 21.2 MB

Release files / sound_rs-0.2.0.tar.gz

Download URL sound_rs-0.2.0.tar.gz
Size 44.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fc27f58c56002c479931335834951306217c42f6337f07a66059272f75470f23
BLAKE2b-256 checksum
How to use checksums
7d01ad72ed004c8aa2674a2ed25124ef302c34e067f8b74af21b3ce9ce2c7eb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp314-cp314-win_amd64.whl

Download URL sound_rs-0.2.0-cp314-cp314-win_amd64.whl
Size 1.3 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
03d3d3e16fbeb35dc24071cf9b71e9ad32ec4e7bf7620f58e049083ba08c35af
BLAKE2b-256 checksum
How to use checksums
39ed2c3f9fc3eb0519e31007d386a7a03a25549fbb6a06014599c1420e643306
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL sound_rs-0.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.8 MB
Tags CPython 3.14 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
e7ce8a39d2199a11dfc294ccf3b0ea8e95316966ddad8a8a69908b4aeeba8e0f
BLAKE2b-256 checksum
How to use checksums
2c773ac6cdde4e4df782732fe0ecbfbb5f3c3bdc89ed9e9d168630aafeb64963
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp314-cp314-macosx_11_0_arm64.whl

Download URL sound_rs-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
67128a7f70c792bd9d8b4d148f7d43eb1dd2582c5ca91e55d3a9a35150975c19
BLAKE2b-256 checksum
How to use checksums
34a1155fcec21d406c6fd642aa944f557f88e735a50f3b17d62d2138b755cde0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp313-cp313-win_amd64.whl

Download URL sound_rs-0.2.0-cp313-cp313-win_amd64.whl
Size 1.3 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
e2cd1a22bfc97bd89165fabbe049aa85c901b14046a90fd268aac8ac64707f8f
BLAKE2b-256 checksum
How to use checksums
40a14cbf9a56fbedc01b10fac7bb8ffdb6ee814a9b6f910aa6472ee1ce9c2e22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL sound_rs-0.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.8 MB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
cd8a563035ffd844bd329af6339f2680489358dd4e97c7fe271393d49fccd308
BLAKE2b-256 checksum
How to use checksums
8c3c57f54b9d6d995f14ec4b3d636eb335f86ec29b9c8d0687b1ed50e12f0a5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL sound_rs-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d91dc14e330255a1299a2f1054e6534967ff45acf8c2bb812e38f5ca4b65b27e
BLAKE2b-256 checksum
How to use checksums
6a61687f2c962de9a5e85803a7edab9d0dde19b7183a9a80a197a5997312692c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp312-cp312-win_amd64.whl

Download URL sound_rs-0.2.0-cp312-cp312-win_amd64.whl
Size 1.3 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
b7792d0ee219c7fa4805560e72c446984ba67d0db8548b953dafeeb5e1a4b662
BLAKE2b-256 checksum
How to use checksums
77e5baa58ba8867c616b248dd53a2f44624fa9a1622ac5fe83ff13a89fe6c656
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL sound_rs-0.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.8 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
9f7ad34f5f1ab6d2a1c788c393130d182ee44a00ed83376cdd78232e12919760
BLAKE2b-256 checksum
How to use checksums
e33b73994570f2d0419b34036d45a510ef49e87f1309e7658a40b9bded6d591d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL sound_rs-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e1154bf9bd266d4d071be29ef837216bb71873b6771aa0d5ef4b7e7c51ed95d3
BLAKE2b-256 checksum
How to use checksums
238f1d8d8da45260ecbade9e55f02262a2cd812321b9a1267f14ab74045a9293
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp311-cp311-win_amd64.whl

Download URL sound_rs-0.2.0-cp311-cp311-win_amd64.whl
Size 1.3 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
e7dfe83ca2d776704cfbb1fdab5ed6b397aeaa245dc76ae9b0e8787889b710ee
BLAKE2b-256 checksum
How to use checksums
9e0d093c723e14bb42d2b0d227c9f3120ddc6916fed785a2741cd114118c78cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL sound_rs-0.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.8 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
4a7c5ab3b7281c93e3e92fa902f4132f968e9272fe840ad1d24481fc2cd0ba2a
BLAKE2b-256 checksum
How to use checksums
f00a8af4020ccfa1f3c6b45dc7e08f0a3d548d674876a54a41378ba10e52450d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL sound_rs-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8166c9727c72788b4ce4ae0c0aac30956f7d96e89ae5022015e019d370ca3877
BLAKE2b-256 checksum
How to use checksums
8f118f0db8e28ad4c9b04fe4019e38314c7ce26297bb9ba2b3e0e9099b30787e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp310-cp310-win_amd64.whl

Download URL sound_rs-0.2.0-cp310-cp310-win_amd64.whl
Size 1.3 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
6332aace5889833066e23dd812b8ed1c911e79ede6d15a8ddd6b1d28d6664afd
BLAKE2b-256 checksum
How to use checksums
adf72d1eb72862282f1fb1fc83ed0cac8cb9feab308ce99a6ba8978631c4fe69
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL sound_rs-0.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.8 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
e8ae9d8b6207381f35b05f20ab9d2cc9132ce94bd7a281d635fbcbca1bc3cb7c
BLAKE2b-256 checksum
How to use checksums
3b1d477cf653b3a14ddb4bd0f86b73495618bfdb22f5bdd0bfc8bafa2b4f745a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / sound_rs-0.2.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL sound_rs-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Size 1.1 MB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d75c0bd62dc8485cf495ef3a2722611de0c2abdb09e606b5c52534adf5adba4c
BLAKE2b-256 checksum
How to use checksums
c84a476fd24346f79e82bec7d67a1b1dfbb7692157ed67fa1a94d4fdd7e0f35c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for sound-rs 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page