Skip to main content

Cross-platform audio output for Python, powered by Rust and CPAL

Project description

PyAudioCast

CI PyPI codecov License: MIT

Cross-platform audio output library for Python, powered by Rust and CPAL.

Stream audio to any output device — including PipeWire/PulseAudio virtual sinks on Linux — with a simple Python API backed by a high-performance Rust core.

Features

  • Cross-platform: Linux (ALSA/PipeWire/PulseAudio), Windows (WASAPI), macOS (CoreAudio)
  • Auto-detect: Sample rate and channels are detected from the device — zero config needed
  • Device selection: List and select output devices by name, including PipeWire virtual sinks
  • Streaming audio: Write audio data in chunks via a lock-free ring buffer — ideal for real-time TTS, generative audio, live effects, etc.
  • Unified write(): Accepts bytes, numpy arrays (int16/int32/float32/float64), or list[float] — format is detected automatically
  • Interruption: clear() instantly discards buffered audio and unblocks drain() — perfect for voice assistant barge-in
  • Context manager: Clean resource management with with statement
  • GIL-friendly: Releases the Python GIL during audio writes and drain, so other threads run freely
  • Clean output: ALSA/JACK backend probe noise is automatically suppressed
  • Debug logging: Enable detailed logs with PYAUDIOCAST_LOG=debug

Installation

From source (requires Rust toolchain)

# Install Rust if needed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Linux: install ALSA headers
sudo apt install libasound2-dev  # Debian/Ubuntu
sudo dnf install alsa-lib-devel  # Fedora

# Clone and install
git clone https://github.com/nicokim/PyAudioCast.git
cd PyAudioCast
pip install maturin
maturin develop

Development setup (with uv)

uv venv && source .venv/bin/activate
uv pip install maturin numpy pytest
maturin develop

Quick Start

import pyaudiocast

# List all output devices
for dev in pyaudiocast.list_output_devices():
    print(f"[{dev['index']}] {dev['name']} ({dev['type']})")

# Stream audio — sample rate and channels auto-detected from device
with pyaudiocast.AudioPlayer() as player:
    print(f"Using: {player.sample_rate}Hz, {player.channels}ch")
    player.write(audio_bytes)   # bytes, numpy array, or list[float]
    player.drain()              # wait for playback to finish

# Override sample rate if your source requires it
with pyaudiocast.AudioPlayer(sample_rate=22050) as player:
    player.write(tts_audio)
    player.drain()

# Stream to a specific device
with pyaudiocast.AudioPlayer(device="Virtual-Mic") as player:
    player.write(samples)
    player.drain()

# One-shot WAV playback
pyaudiocast.play_file("audio.wav", device="pulse")

Streaming with Interruption

For real-time applications like voice assistants, you can interrupt playback instantly:

import pyaudiocast
import threading

with pyaudiocast.AudioPlayer(sample_rate=22050) as player:
    # Stream TTS chunks as they arrive
    for chunk in tts_stream:
        player.write(chunk)
    player.drain()  # wait for playback to finish
# Interrupt from another thread (e.g., when user starts speaking)
def on_user_speech_detected(player):
    player.clear()  # instantly stops audio, unblocks drain()

clear() discards all buffered audio immediately. Any blocked drain() returns right away. Calling write() again resumes normal playback.

Supported Audio Formats

write() auto-detects the input format:

Input type Format Conversion
bytes int16 little-endian PCM Converted to float32
numpy.ndarray (int16) int16 samples Converted to float32
numpy.ndarray (int32) int32 samples Converted to float32
numpy.ndarray (float32) float32 samples Direct (no conversion)
numpy.ndarray (float64) float64 samples Converted to float32
list[float] float32 samples (-1.0 to 1.0) Direct
import numpy as np

with pyaudiocast.AudioPlayer(sample_rate=44100) as player:
    # All of these work with the same write() method
    player.write(b"\x00\x00" * 100)                    # bytes (int16 LE)
    player.write(np.zeros(100, dtype=np.int16))         # numpy int16
    player.write(np.zeros(100, dtype=np.float32))       # numpy float32 (fastest)
    player.write(np.zeros(100, dtype=np.float64))       # numpy float64
    player.write(np.zeros(100, dtype=np.int32))         # numpy int32
    player.write([0.0] * 100)                           # list[float]

API Reference

pyaudiocast.list_output_devices() -> list[dict]

Returns a list of available output devices. Each dict contains:

  • name (str): Device name
  • index (int): Device index
  • type (str): "alsa" for ALSA/cpal devices, "pipewire" for PipeWire/PulseAudio sinks

pyaudiocast.AudioPlayer(device=None, sample_rate=None, channels=None)

Streaming audio player with ring buffer.

Parameter Type Default Description
device str | None None Device name (substring match) or None for default
sample_rate int | None None Sample rate in Hz, or None to auto-detect
channels int | None None Number of audio channels, or None to auto-detect

Methods:

Method Description
write(data) Write audio data (bytes, numpy array, or list[float])
drain() Block until all buffered audio is played
clear() Discard buffer and unblock drain() immediately
stop() Stop playback and release resources

Properties: sample_rate, channels, is_active

Context manager: Supports with statement (calls stop() on exit).

pyaudiocast.play_file(path, device=None)

Play a WAV file to completion. Blocks until playback is done.

Device Selection

Default device

player = pyaudiocast.AudioPlayer()  # uses system default

ALSA device (by name substring)

player = pyaudiocast.AudioPlayer(device="pulse")
player = pyaudiocast.AudioPlayer(device="hw:CARD=Audio")

PipeWire/PulseAudio virtual sinks (Linux)

# Virtual sinks are auto-detected via pactl
player = pyaudiocast.AudioPlayer(device="Virtual-Mic")

PipeWire sinks are routed transparently through PULSE_SINK + the pulse ALSA device.

Environment Variables

Variable Description Example
PYAUDIOCAST_LOG Enable debug logging. Uses env_logger filter syntax. PYAUDIOCAST_LOG=debug

Logging

# Show everything (including ALSA/JACK backend messages)
PYAUDIOCAST_LOG=debug python my_script.py

# Show info and above
PYAUDIOCAST_LOG=info python my_script.py

# Default (no env var): warnings only, ALSA/JACK noise suppressed
python my_script.py

Cross-Platform Support

Platform Backend Device listing Virtual sinks
Linux ALSA + PipeWire/Pulse Full Yes (via pactl)
Windows WASAPI cpal devices N/A
macOS CoreAudio cpal devices N/A

The audio engine (cpal) is fully cross-platform. PipeWire/PulseAudio virtual sink detection uses pactl and is automatically compiled out on non-Linux systems via #[cfg(target_os = "linux")].

Architecture

Python (pyaudiocast)
  │
  ├─ write(data)  →  auto-detect format  →  convert to f32
  │     │
  │     ▼
  │  Lock-free Ring Buffer (ringbuf crate)
  │     │
  │     ▼
  │  cpal audio callback (OS audio thread)
  │     │                          ▲
  │     ▼                          │
  └─ Speaker / Virtual Sink    clear() → discard + silence
  • Ring buffer: Lock-free producer/consumer. Python pushes samples, the OS audio callback pulls them — no locks in the audio path.
  • GIL release: write() and drain() release the Python GIL during blocking operations.
  • Sample conversion: All input formats are converted to float32 in Rust before entering the ring buffer.
  • Interruption: clear() sets an atomic flag checked by the audio callback, which discards remaining samples and outputs silence.

Running Tests

# Python tests
pytest tests/ -v

# Rust tests
cargo test

License

MIT

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

pyaudiocast-0.1.7.tar.gz (27.8 kB view details)

Uploaded Source

Built Distributions

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

pyaudiocast-0.1.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

pyaudiocast-0.1.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

pyaudiocast-0.1.7-cp312-cp312-win_amd64.whl (729.8 kB view details)

Uploaded CPython 3.12Windows x86-64

pyaudiocast-0.1.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

pyaudiocast-0.1.7-cp312-cp312-macosx_11_0_arm64.whl (838.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pyaudiocast-0.1.7-cp312-cp312-macosx_10_12_x86_64.whl (892.4 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

pyaudiocast-0.1.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

pyaudiocast-0.1.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

pyaudiocast-0.1.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

File details

Details for the file pyaudiocast-0.1.7.tar.gz.

File metadata

  • Download URL: pyaudiocast-0.1.7.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyaudiocast-0.1.7.tar.gz
Algorithm Hash digest
SHA256 e1a98891f04d312bc682162cb21e2717a039a62aa8b686c978ddde5df32e8db2
MD5 bd527305bb5d73597e6b6ee23139c34c
BLAKE2b-256 e38eab291f18f9341f5ff7bad58e7d410baf052ea2f2c0944416d2571d730868

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7.tar.gz:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 341c7d4d47cdcce5bd58acbfb9fab87210eb7631befee117566230b4637822c8
MD5 3ca0af629e1e3a60ac82fca53eca38dd
BLAKE2b-256 fc1fbcc3e24d1e6dfa79f6515d2ddb39362ebd7facf6f23ce68cd659eb0ec480

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dfc062ca7af044282c2ffc65bdfaece0e1733465509c9efec9056f6d64cb71ce
MD5 3e05cca2988cad1c9ad858f73136017a
BLAKE2b-256 badefa8cfed7f452811deafb58da118adc9e83c0dc7b55e2c84a2990400d890e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pyaudiocast-0.1.7-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 729.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyaudiocast-0.1.7-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 318a5a85e84435f5324720956ec3aeb4a588368a4e3133987a93c7541e2e5178
MD5 0e66ba4377aeeb7ebfccdb63f613ce26
BLAKE2b-256 e5f0f6784af12c4e9087e3a73e4500eb2081a931ce85c4f7f9908450110a5a72

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp312-cp312-win_amd64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 63e7a9719a00c9264cba0aee60a5bd258b25bbf4f9513c262d3dfe82b71d237b
MD5 ebbdb98a9bc3e55709dc5c4fcda33c57
BLAKE2b-256 8ca8c06691f5100f6ca717e998275cf42bf2ffd6b1d330540017ba67feac5309

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cdd8744fab60004403fa0aab057ed8cef0645176193cb38a8a919b62a9eac64b
MD5 c3c304f1f53fc6c544544c52782f5c51
BLAKE2b-256 d87848c32a4f67059510c04559d1e391ecf25705fe6dc8ae425c8ae11fe4768f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f097956de33e8fe3eca1a35ba4f1d235d1e48ab362a09f04d1c891a8dbb9cc1d
MD5 9190b58e773b0fe0c52c3554f3e2e087
BLAKE2b-256 15cbbc6e9abf45d1deac6b8406dd2e52c7ced3e7931ccefb150d8013a3084be4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d7d7fdbfb0284295edf9fe97da4f67d13838bf47b3ee7523d8f60dc644df161c
MD5 b2531f1d0e54472e9a2421b0fed72bbb
BLAKE2b-256 f687a4f098b90ca96bc4a0634588a0e1609524d1b896017c7f26ff1690132781

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f470d5fea9ad451bee71fcece55513dea2fb156a935a7a459b14fdfeb5d24e75
MD5 ac4ed70ed9fc8a2c943f46e1e3484fb9
BLAKE2b-256 b9be283ef9a956c55fbaa586699b800cab0512248180da143c5d54d959da6142

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaudiocast-0.1.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyaudiocast-0.1.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e88d3a2dff9631051059a007d192ed41eed444b38cc63be55643893b2a0c2b6f
MD5 8f71d5323beba5818b4db6940d8f4b54
BLAKE2b-256 67d98db0e9e9ef658150c6218f35f089960be4e9841777eb4bad7874bf69fd3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaudiocast-0.1.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nicokim/PyAudioCast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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