AtlatestRepositorysigil-audio
sigil-audio / treeREADME.md
1
# sigil-audio3
Audio playback and streaming for [Sigil](https://codeberg.org/sigil/sigil).5
Provides audio playback capabilities via sokol_audio. Sound effects are loaded into memory, music is streamed via stb_vorbis.7
## Modules9
| Module | Purpose |10
|--------|---------|11
| `(sigil audio)` | Audio playback, sound effects, and music streaming |13
## System Prerequisites15
- ALSA development headers on Linux (`libasound2-dev` / `alsa-lib-devel`)16
- AudioToolbox framework on macOS (included with Xcode)17
- Windows: nothing extra — sokol_audio drives WASAPI through18
`ole32` / `winmm` / `ksuser`, all bundled with the OS.20
OGG Vorbis encoding/decoding is **vendored** (libogg 1.3.6 +21
libvorbis 1.3.7, see `vendor/ogg/README.md` and22
`vendor/vorbis/README.md`). No system `libogg` / `libvorbis` /23
`libvorbisenc` packages need to be installed — sigil-audio links24
them statically into `libsigil-audio.a`. This adds ~1 MB to the25
final binary and unblocks Windows cross-compile.27
## Dependencies29
- sigil-stdlib31
## Build33
```sh34
sigil deps install35
sigil build # native (host platform)36
sigil build --config windows-amd64 # cross-compile for Windows (zig)37
```39
## Streaming audio sink41
Three playback paths coexist in `(sigil audio)`:43
1. **`load-sound` + `play-sound`** — short SFX, decoded once into44
memory, fired from Sigil, mixed on the audio thread.45
2. **`play-music`** — long OGG, streamed from disk on the audio46
thread via stb_vorbis.47
3. **`open-audio-stream` + `push-audio-samples`** — caller-driven48
streaming sink. The caller produces interleaved float32 PCM49
(any thread) and pushes it into a lockless SPSC ring; the audio50
thread drains the ring into its output buffer. Use this for51
live / generative audio (motif streaming render, live-coded52
synths, etc.).54
Example — play a 440 Hz sine wave for 1 second:56
```scheme57
(import (sigil audio) (sigil math))59
(audio-setup)61
(define stream (open-audio-stream channels: 262
buffer-frames: 8192))64
(define sr 44100)65
(define pi 3.14159265358979)66
(define frames (* sr 1))68
;; Build a stereo float32 bytevector with a 440 Hz sine.69
(define samples70
(let ((v (make-vector (* frames 2) 0.0)))71
(let loop ((i 0))72
(when (< i frames)73
(let ((s (sin (* 2.0 pi 440.0 (/ i sr)))))74
(vector-set! v (* i 2) s)75
(vector-set! v (+ (* i 2) 1) s))76
(loop (+ i 1))))77
v))79
(define pcm (make-float-buffer samples))81
;; Push in chunks of whatever the ring has room for.82
(let loop ((remaining frames) (offset-frames 0))83
(when (> remaining 0)84
(let ((room (audio-stream-room stream)))85
(if (= room 0)86
(begin (sleep 0.005) (loop remaining offset-frames))87
(let ((n (min remaining room)))88
(push-audio-samples stream pcm n)89
(loop (- remaining n) (+ offset-frames n)))))))91
(close-audio-stream! stream)92
```94
Notes:95
- Sample rate is fixed at 44100 to match sokol_audio's96
configured rate; callers MUST match (no resampling).97
- `push-audio-samples` is non-blocking and returns the frame98
count actually accepted — the caller decides whether to99
retry or drop.100
- Streaming sinks coexist with `play-sound` / `play-music` —101
they're an additional mix source, not a replacement.102
- Up to 4 streams may be open simultaneously.103
- Default `buffer-frames: 16384` (~370 ms at 44.1 kHz) is104
safety margin against under-run, not added latency. Live105
producers who want tighter reactivity can open with106
`buffer-frames: 2048` or smaller.108
See `folio topics/sigil-audio-streaming-sink-architecture`109
for the SPSC ring design, threading model, and under-run /110
over-run semantics.112
## License114
BSD-3-Clause.116
Vendored libogg (1.3.6) and libvorbis (1.3.7) are also distributed117
under BSD-3-Clause (see `vendor/ogg/COPYING` and118
`vendor/vorbis/COPYING`). Both licenses are compatible with this119
package's BSD-3-Clause terms.