Skip to main content

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 pip without 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 ring
  • InputStream.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 frames
  • drain(): wait for queued frames to play
  • flush(): discard queued frames without closing the stream
  • close(): stop playback and release native resources

StreamStats reports:

  • frames_processed: frames consumed by the backend
  • underruns / overruns: buffer starvation or rejected writes
  • hardware_latency: backend-reported device latency in seconds when available
  • queued_frames: frames currently waiting in the native ring
  • queued_latency: queued ring duration in seconds
  • estimated_latency: queued_latency + hardware_latency when hardware latency is available, otherwise queued latency
  • buffer_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tachyaudio-0.2.0b1.tar.gz (667.6 kB view details)

Uploaded Source

Built Distribution

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

tachyaudio-0.2.0b1-cp314-cp314-macosx_26_0_arm64.whl (677.5 kB view details)

Uploaded CPython 3.14macOS 26.0+ ARM64

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

Hashes for tachyaudio-0.2.0b1.tar.gz
Algorithm Hash digest
SHA256 08eacb17c909389d031a255d256e0effbbbaebcc5ac3e0745b79fa40729dab70
MD5 761e3e071d59ddefa20656883329756b
BLAKE2b-256 d409da923e4c4a159a3a9feb3b939104febd0d387fef56edb3a5f21a144659a1

See more details on using hashes here.

File details

Details for the file tachyaudio-0.2.0b1-cp314-cp314-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for tachyaudio-0.2.0b1-cp314-cp314-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 acffd261da7a68ad622074833972882ee99370561e78769208f2c4728b2fb801
MD5 023aaeb99e06a3434339bee2ee850bab
BLAKE2b-256 c4d066d67dc08619625ff43f03bf7a0566847b0fdb26189de05fc8e132b0fabf

See more details on using hashes here.

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