oto: add a non-cgo ALSA fallback for the PulseAudio driver#283
oto: add a non-cgo ALSA fallback for the PulseAudio driver#283hajimehoshi wants to merge 1 commit into
Conversation
|
@mcuadros Please try this |
There was a problem hiding this comment.
Pull request overview
Adds a cgo-free ALSA backend as a runtime fallback when the Unix PulseAudio backend can’t connect to a server, improving support for minimal/containerized Unix installs while keeping the default PulseAudio path.
Changes:
- Refactors the Unix driver into an asynchronous dispatcher that tries PulseAudio first, then ALSA (when available).
- Introduces a dedicated PulseAudio backend implementation extracted from the prior Unix driver.
- Adds a purego-based ALSA backend that dlopens
libasoundonly when needed, and documents the fallback/build notes in the README.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| README.md | Documents the new ALSA fallback behavior and FreeBSD CGO-free build note. |
| driver_unix.go | Reworks Unix context initialization into an async dispatcher selecting PulseAudio or ALSA. |
| driver_pulseaudio_unix.go | New PulseAudio backend extracted from the previous Unix driver code. |
| driver_alsa_unix.go | New purego-based ALSA fallback backend with runtime libasound loading and device enumeration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ca48c9c to
ba7a19f
Compare
The PulseAudio driver requires a running PulseAudio server, which is absent on many minimal, container, kiosk, and embedded systems. When no server is reachable, fall back to ALSA by loading libasound dynamically through purego, keeping the fallback Cgo-free and preserving FreeBSD and NetBSD support. The context now picks a backend at startup much like the Windows driver chooses between WASAPI and WinMM. Closes #282 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ba7a19f to
edec6a1
Compare
|
I think it would be nice to have a no_alsa_fallback (or nolibasound) build tag so that if someone wants to have a static binary with just pulse audio then they can do that |
I'd add this feature if someone has an issue in the real world and requests it. Windows also has two drivers and nobody requested a flag to choose a driver so far. |
What
When no PulseAudio server is reachable, the Unix backend now falls back to ALSA instead of failing context creation. The fallback is Cgo-free: it loads
libasound.so.2dynamically (via purego) only when the fallback is actually needed.Why
e3a524creplaced the cgo ALSA driver with a pure-Go PulseAudio driver, which made a running PulseAudio (or PipeWire pulse-shim) server mandatory. That breaks minimal installs, containers, kiosk/embedded setups, and removed the backend FreeBSD historically used. This restores ALSA as a fallback while staying Cgo-free.Closes #282.
How
driver_unix.gobecomes a thin dispatcher: it owns the sharedmux, and in a goroutine tries PulseAudio, then ALSA — the same shape as the Windows driver choosing between WASAPI and WinMM. Both backends satisfy a smallunixBackendinterface.driver_pulseaudio_unix.go(new): the existing PulseAudio code, moved into apulseContextbackend. It now returns its error (the fallback trigger) and closes the client ifNewPlaybackfails.driver_alsa_unix.go(new): a faithful purego port of the pre-e3a524ccgo ALSA driver — same device enumeration (snd_device_name_hint,default/plug:defaultprepended, Input/null filtered),FLOAT_LEsetup, and the blockingsnd_pcm_writei/snd_pcm_recoverloop. libasound isDlopen'd lazily, only when PulseAudio fails.Platform / build notes
((linux && !android) || freebsd || netbsd) && !nintendosdk && !playstation5— purego's supported platforms, excluding the Linux-based console targets that have their own driver. OpenBSD (no purego) keeps PulseAudio only, via a nil dispatcher hook.CGO_ENABLED=0(e.g. cross-compiling) needs-gcflags="github.com/ebitengine/purego/internal/fakecgo=-std"(documented in the README).libasound2-devapt install from CI in a separate commit already onmain.Testing
gofmt,go build, andgo vetclean.go test ./...passes on macOS.example/with PulseAudio stopped (andlibasound.so.2present).🤖 Generated with Claude Code