soundobj
Sometimes you want to play a sound in Python and get on with your life. Sometimes that sound needs to move through a three dimensional world, fade with distance, change pitch while it is playing, or stream from an internet radio station.
I wanted one library that could do both without weird licensing restrictions (hello Bass), large binaries (hello FMOD), entire windowing systems (hello pygame/SDL/OpenGL/pyglet/ugh), or any other other funny business.
soundobj is a high level Python interface to miniaudio. The easy path takes one line. If the project grows into something more demanding, the same library exposes the playback engine, individual sounds, listeners, positioning, attenuation, and other controls without forcing you to replace the audio layer.
Why I made another audio library
Python has no shortage of ways to play sound, but each option I tried came with a catch. Some only play files. Others pull in an entire game or graphics framework. A few use restrictive licenses, have reached the end of their lives, or expose an API so low level that playing a file becomes a project of its own.
Those libraries still have their uses, and several are admittedly far more battle tested. I wanted something portable and permissively licensed that I could install, understand quickly, and start hacking on.
Start small
Install soundobj from PyPI:
pip install soundobj
If all you need is an earcon or notification sound, this starts playback and cleans up when the file ends:
import soundobj
soundobj.play_sound("click.wav")
Create a Sound when you want to keep control of it:
import soundobj
music = soundobj.Sound(source="music.ogg")
music.looping = True
music.volume = 0.8
music.play()
Properties such as volume, pitch, pan, playback position, looping, and spatial placement can be changed while the sound is running. WAV, MP3, FLAC, Ogg Vorbis, Opus, and the other formats supported by miniaudio all go through the same interface.
Streams and spatial sound
A web address works like a local file. soundobj can play an ordinary audio download or stay connected to a live HTTP, HTTPS, or FTP stream, which makes it useful for internet radio and other sources with no known duration.
For games and simulations, sounds can be placed at coordinates in a three dimensional world. You control where each sound is, which direction it faces, how quickly it loses volume over distance, and whether movement should produce a Doppler effect. Directional sound cones let something be louder in front than behind. Multiple listeners are supported too, which is useful for split screen games, monitoring, and less conventional audio setups.
Most projects can use the default global engine. If you need different channel counts, sample rates, device behavior, or several listeners, create and configure an engine directly. The API stays property based either way.
How it is put together
Miniaudio already provides a small, cross platform engine for decoding, playback, streaming, and spatialization. soundobj wraps its engine API through CFFI and turns the lower level C interface into ordinary Python objects.
That keeps the install focused on audio and leaves room to get closer to miniaudio when necessary. If you know a little C and are comfortable adding an FFI declaration, the wrapper is intentionally straightforward to extend.
soundobj currently requires Python 3.13 or newer. It is still a young library, so I am especially interested in reports from people using different devices, file formats, and operating systems. The README and API reference include streaming examples, spatial audio setup, every property exposed by Engine and Sound, build instructions, and the current roadmap.
The library is released under the MIT license and into the public domain. Pick whichever terms work better for your project.