Low-level audio primitives for tachypy and Python experiments.
Project description
tachyaudio
tachyaudio is a low-level audio package intended to replace tachypy’s direct
dependency on sounddevice/PortAudio over time.
Status: beta. The native backend currently supports macOS through Core Audio and
Linux through vendored miniaudio. Windows support is planned but intentionally
deferred until Windows test hardware is available.
Goals
- install from
pipwithout requiring users to install PortAudio separately - keep real-time audio work out of Python callbacks where possible
- expose explicit latency, underrun, and overrun diagnostics
- support playback, capture, duplex streams, and device enumeration
- keep tachypy’s public API stable while the backend evolves
Non-goals
- full DAW-style audio graph support in the initial release
- replacing OS audio stacks such as Core Audio, WASAPI, ALSA, or PulseAudio
- exposing backend-specific details as the primary user API
Initial API shape
import tachyaudio as ta
devices = ta.list_devices()
stream = ta.OutputStream(sample_rate=48_000, channels=2)
stream.write(samples)
with stream:
...
stats = ta.play(samples, sample_rate=48_000, channels=2)
The native backend currently supports device enumeration, float32 output playback, and nonblocking float32 input capture on macOS and Linux.
OutputStream is currently a continuous stream. Write audio before or during
playback; if the stream runs out of queued frames it outputs silence and counts
an underrun.
Use tachyaudio.play() for finite stimuli that should start, drain, and close
as a single operation.
See examples/play_wav.py for dependency-free playback of WAV files exported
from an editor such as Audacity. The repository example uses a 48 kHz float WAV
to avoid runtime resampling. Pass --eq to show a lightweight five-band
terminal meter during playback.
Use blocking helpers when callers need complete buffer transfer:
OutputStream.write_all(frames, timeout=None): wait until all frames are accepted by the output ringInputStream.read_exactly(frame_count, timeout=None): wait until exactly the requested number of frames has been captured
Full-duplex capture/playback is exposed as DuplexStream. Native macOS and
Linux support is available.
Lifecycle semantics:
stop(): stop playback without discarding queued framesdrain(): wait for queued frames to playflush(): discard queued frames without closing the streamclose(): stop playback and release native resources
StreamStats reports:
frames_processed: frames consumed by the backendunderruns/overruns: buffer starvation or rejected writeshardware_latency: backend-reported device latency in seconds when availablequeued_frames: frames currently waiting in the native ringqueued_latency: queued ring duration in secondsestimated_latency:queued_latency + hardware_latencywhen hardware latency is available, otherwise queued latencybuffer_size: native callback buffer size in frames
Development
Supported Python versions:
- Python 3.10
- Python 3.11
- Python 3.12
- Python 3.13
- Python 3.14
Run the standard-library test suite:
python3 -m unittest discover -s tests
Play a short test tone:
PYTHONPATH=src python3 examples/play_tone.py
Capture a short input buffer and print its RMS level:
PYTHONPATH=src python3 examples/capture_level.py
InputStream.read(frame_count) is nonblocking and returns currently available
frames up to frame_count.
On macOS, a restricted sandbox may hide Core Audio devices. On Linux, sandboxed
processes may be unable to reach the user PipeWire/PulseAudio server. If
tachyaudio.list_devices() returns an empty tuple or only generic ALSA devices
in a sandboxed environment, verify from an unsandboxed terminal before debugging
the backend. Headless Linux containers may return no devices while still being
able to build and import the native extension.
Project details
Release history Release notifications | RSS feed
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 tachyaudio-0.2.0b1.tar.gz.
File metadata
- Download URL: tachyaudio-0.2.0b1.tar.gz
- Upload date:
- Size: 667.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08eacb17c909389d031a255d256e0effbbbaebcc5ac3e0745b79fa40729dab70
|
|
| MD5 |
761e3e071d59ddefa20656883329756b
|
|
| BLAKE2b-256 |
d409da923e4c4a159a3a9feb3b939104febd0d387fef56edb3a5f21a144659a1
|
File details
Details for the file tachyaudio-0.2.0b1-cp314-cp314-macosx_26_0_arm64.whl.
File metadata
- Download URL: tachyaudio-0.2.0b1-cp314-cp314-macosx_26_0_arm64.whl
- Upload date:
- Size: 677.5 kB
- Tags: CPython 3.14, macOS 26.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acffd261da7a68ad622074833972882ee99370561e78769208f2c4728b2fb801
|
|
| MD5 |
023aaeb99e06a3434339bee2ee850bab
|
|
| BLAKE2b-256 |
c4d066d67dc08619625ff43f03bf7a0566847b0fdb26189de05fc8e132b0fabf
|