AtlatestRepositorysigil-audio
sigil-audio / treeCHANGELOG.md
1
# Changelog3
All notable changes to this project will be documented in this file.5
The format is based on [Keep a Changelog](https://keepachangelog.com/),6
and this project adheres to [Semantic Versioning](https://semver.org/).8
## [Unreleased]10
### Added12
- **`(sigil audio ladder)`**: steps a producer's render rate down a rung when13
its steady cost per frame is over budget, the policy Crash the Stack tuned on14
a phone. The median of a 60-pull window decides; pulls within 150 ms of a15
cue, and the 30 after an open or a step, are not measured; the rate only goes16
down (a pin, or lifting one, is the only way up) and never below the floor; a17
remembered rate carries a buffering key and is ignored under a different one.18
The default clock is the monotonic jiffy clock in fractional ms: a pull costs19
tenths of a millisecond, and a whole-ms clock moves the median across the20
budget. `rate-ladder-report` gives the readout21
line (`48000/24000 BY LADDER@20.2S`). Pure Sigil; `test/test-ladder.sgl`.22
- **Cues in `(sigil audio sink)`**: `load-audio-cue`, `play-audio-cue`,23
`unload-audio-cue!`, `stop-audio-cues!`, `set-audio-cue-volume!`,24
`audio-cue-mode`, `audio-cue-lag`. On the web they come from25
sigil-wasm-audio (mixed in the AudioWorklet in the next render quantum);26
natively a cue is a sound in memory played through `play-sound`, mixed in27
the device callback. Neither waits behind a stream's ring. The web arm needs28
the sigil-wasm-audio released with sigil 0.22.7; an older one lacks these29
names and the web build fails.30
- **Streams below the device's rate**: `open-audio-stream rate:` and31
`set-audio-stream-rate!`, upsampled on the audio thread with a 4-tap cubic;32
a change lands at the write head it was asked at. `audio-stream-rate`.33
- **The underrun split**: `audio-stream-underruns-sounding` (starved frames34
that cut sound off) and `audio-stream-underruns-idle` (a quiet stream35
running dry), natively and on the web. `test/test-sink-rate-split.sgl`.37
### Fixed39
- `play-sound` publishes a slot's `playing` flag with release ordering and40
the device callback reads it with acquire, so the callback never mixes a slot41
whose sound and position were not yet written. (A slot reused by `play-sound`42
while the callback is mixing it after `stop-all-sounds` is still a race; not43
addressed here.)45
## [0.12.2] - 2026-09-2047
### Changed49
- **The playback device is miniaudio 0.11.25** (vendored, unpatched,50
device layer only), replacing sokol_audio. Backends are loaded at run51
time: on Linux PulseAudio (`libpulse.so`, then `.so.0`; pipewire-pulse on a52
PipeWire desktop), then ALSA, then JACK; WASAPI on Windows; CoreAudio53
on macOS. **Nothing audio-related is linked any more**: `-lasound`,54
`AudioToolbox` and `ole32`/`winmm`/`ksuser` are gone from55
`link-flags`. A game's NEEDED list loses `libasound.so.2`.56
- The stream is named after the program (`program_invocation_short_name`),57
so `pactl list sink-inputs` shows the game, not "miniaudio".58
- With no backend library on the machine the mixer runs silent on59
miniaudio's Null backend and one stderr line says so; `audio-setup`60
still succeeds and `(audio-initialized?)` is `#t`, as under sokol_audio.61
- `src/c/dl-search.c`, a byte-identical copy of sigil-desktop's resolver62
(`src/c/DL-SEARCH-ORIGIN.md` records the hash and `test/dl-search-test.sh`63
enforces it), finds backend libraries in Guix and Nix profiles when the64
loader alone cannot; miniaudio's `dlopen` is redirected to it. A program65
that links sigil-desktop too has both copies; only sigil-desktop's66
defines `dlopen` itself.67
- `SIGIL_AUDIO_VERBOSE=1` prints the backend, the device, the format68
conversion miniaudio applies and every resolver hit.69
- `manifest.scm` no longer needs `alsa-lib` to build; it lists `pulseaudio`70
for the test that opens a device (`test/test-device-drain.sgl`, which71
proves the device thread drains a stream).73
### Added75
- `(audio-backend)`: the backend the device runs on as a symbol76
(`'pulseaudio`, also on a PipeWire desktop through pipewire-pulse;77
`'alsa`, `'jack`, `'wasapi`, `'dsound`, `'winmm`, `'coreaudio`, or78
`'null` when frames are consumed in silence), `#f` before `audio-setup`.79
- `(audio-device?)`: `#t` when a real (non-null) device is open, i.e.80
when sound can reach a listener. `audio-initialized?` keeps its meaning81
(`audio-setup` ran; the mixer and streams work on every backend), as it82
had under sokol_audio where an invalid device was silent but83
initialized; the new predicate names the new fact.84
- `SIGIL_AUDIO_BACKEND=pulseaudio|alsa|jack|wasapi|coreaudio|null` picks85
one backend instead of miniaudio's priority walk (tests run the suite86
with `null` too; a desktop whose first choice misbehaves can pin one).87
- `test/test-device-drain.sgl`: opens the real device and proves the88
device thread drains a stream, and checks the two predicates agree.90
### Removed92
- `vendor/sokol` (sokol_audio.h, sokol_log.h) and `src/c/sokol-audio.c`.94
### Requires96
- Sigil 0.20+, unchanged. The Sigil API is unchanged.98
## [0.12.0] - 2026-07-10100
### Added102
- `(sigil audio sink)`, a portable streaming audio-sink facade that selects103
its backend with `cond-expand`. The native arm re-exports the sokol SPSC104
ring from `(sigil audio)`; the WebAssembly arm imports `(sigil browser105
audio-sink)` from the sigil-wasm-audio bridge package, so the same source106
compiles and runs on both native and WebAssembly. The facade adds107
WebAudio-shaped context lifecycle ops (`audio-context-open`,108
`audio-context-resume`, `audio-context-sample-rate`, `audio-context-state`)109
and a portable `make-float-buffer` re-export. On native the context ops are110
thin shims over sokol's single always-running device.112
### Fixed114
- WebAssembly builds that depend on sigil-audio for the `(sigil audio sink)`115
facade no longer fail to compile. The native audio C (sokol_audio, vendored116
libogg/libvorbis) has no wasm32-wasi backend, so its C-compilation steps are117
now gated out of wasm/wasi targets with `skip-on-wasm`; on wasm the facade118
delegates to the WebAudio bridge, so none of that C is needed. Native builds119
are byte-identical (the guard is false).121
## [0.11.0] - 2026-06-25123
### Changed125
- Raised the toolchain requirement to Sigil 0.17. The package now126
declares `sigil: "^0.17"` and pins `sigil-stdlib` to `^0.17`. Sigil127
0.17 makes the package-level `sigil:` field mandatory and derives the128
native codegen runtime (`sigil-lib`) from it, so building under the129
0.17 compiler requires this bump. This is a minor release because130
consumers caret-pinning sigil-audio must move to the 0.17 line.132
### Requires134
- Sigil 0.17+ (`sigil-stdlib` / `sigil-lib` 0.17 line).136
## [0.10.2] - 2026-04-24138
### Fixed140
- `link-flags:` now uses `(lambda (ctx) (case (target-os ctx) ...))`141
instead of a host-based `(case (host-os) ...)` expression. The142
host-based form evaluated at package-load time on the host, so143
Linux link flags leaked into Windows cross-compile builds; a144
`sigil build --config windows-amd64` pass from a Linux host would145
inject `-lasound` into the final link and fail against zig's MinGW146
sysroot. The procedural form re-evaluates at link time with the147
target triple, so cross-compile configs now pick the right branch.148
The OS branches themselves are unchanged (`linux`: `-lasound`;149
`darwin`: `-framework AudioToolbox`; `windows`: `-lole32 -lwinmm150
-lksuser`).152
### Requires154
- `sigil-build` 0.14.0+ (for the `target-os` / `target-arch` helpers155
and the procedural-link-flags dispatch in `collect-native-link-flags`).157
## [0.10.0] - 2026-04-24159
### Added161
- Vendored libogg 1.3.6 + libvorbis 1.3.7 under `vendor/ogg/` and162
`vendor/vorbis/`. OGG Vorbis encoding/decoding is now163
self-contained: no external `-lvorbis` / `-lvorbisenc` / `-logg`164
link dependency, no system `libogg-dev` / `libvorbis-dev`165
packages needed on Linux or macOS.166
- Windows cross-compile target (`sigil build --config167
windows-amd64`) — uses zig with `x86_64-windows-gnu`. WASAPI168
backend links against `-lole32 -lwinmm -lksuser`. Verified by169
building libsigil-audio.a + test-linking a PE32+ Windows .exe.170
- Per-tree `vendor/ogg/README.md` and `vendor/vorbis/README.md`171
recording upstream version + tarball SHA256 + upgrade procedure.173
### Changed175
- `package.sgl` library `link-flags`: dropped176
`-lvorbis -lvorbisenc -logg` from every host branch; added a177
`(windows)` branch with WASAPI link flags.178
- `manifest.scm`: removed `libvorbis` / `libogg` system deps —179
vendored sources cover them.180
- Binary size grows by ~1 MB (libvorbis codebook tables dominate).181
Acceptable trade-off for the install-time ergonomics + cross-182
compile capability.184
## [0.9.0] - 2026-04-18186
### Added188
- Streaming audio sink: `open-audio-stream`, `push-audio-samples`,189
`audio-stream-room`, `audio-stream-depth`, `audio-stream-capacity`,190
`audio-stream-channels`, `audio-stream-underruns`,191
`audio-stream-closed?`, `close-audio-stream!`,192
`set-audio-stream-volume!`, `audio-stream?`. Lockless SPSC ring193
lets Sigil callers feed interleaved float32 PCM from any thread194
to sokol_audio's audio thread; coexists additively with195
`play-sound` / `play-music`. See196
`folio topics/sigil-audio-streaming-sink-architecture`.198
## [0.5.0] - 2026-02-17200
### Added202
- Added test harness generation and build support for packages with native dependencies. Improved native package handling, added c-flags field to library struct. Fixed stdlib inclusion in bundles with custom native runtimes, directory structure preservation in compile-c-sources, and absolute sigil-lib include path resolution.203
- Added test coverage.204
- Added test coverage.205
- Added test coverage for TCP/UDP/address operations and crypto primitives.206
- Added test coverage for TCP/UDP/address operations and crypto primitives.207
- Added test coverage.208
- Added test coverage.209
- Added test coverage.210
- Added test coverage.211
- Added test coverage.212
- Added test coverage.213
- Added opcode-level profiling with --profile flag. Added test harness support for packages with native dependencies. Build safety: warn when replacing the running binary, error on 0-byte output or missing target package. Fixed module cache clearing before running entry points, handling of missing sigil-lib in user-created packages.214
- Added test coverage.215
- Added test coverage.217
### Fixed219
- Fixed random seed initialization crash caused by flonum-to-bignum promotion in modulo. Fixed status command crash when displaying projected versions for packages without changes.220
- Fixed SSE and remove-after initialization on child elements. Added comprehensive test coverage for routing, middleware, cookies, security, SSE, and response helpers.221
- Fixed assq-ref to return values instead of aliasing assq, added assv-ref. Added async-aware process pipe I/O. Fixed REPL string-length error after exception recovery. Added comprehensive error path tests and GC stress tests for dicts.222
- Fixed Scheme module compilation in build task.223
- Fixed re-import of (sigil core) before calling entry main in bundled applications.225
### Other227
- New packages split from sigil-studio. Font and image modules moved to (sigil graphics *) namespace.228
- GC correctness: added write barriers to all heap mutation sites, enabled GC during compilation with full compiler rooting, and added GC stress testing infrastructure. Completed HAMT dict implementation (printing, equality, collision handling, structural removal). Added arbitrary-precision bignum type with full reader/VM/native/serializer integration. Performance: inline caching for module binding lookups, peephole optimizer with 8 superinstruction patterns. Improved error handling: replaced exit(1) with recoverable errors, fixed error propagation in vm_error_abort and OP_ABORT_TO_PROMPT. Added definition location tracking in stack traces. Implemented VFS/bundle directory listing. Fixed number->string precision for exact IEEE 754 roundtrip. Removed dead opcodes.229
- Configured custom mbedTLS for TLS 1.2 only. Added test coverage for connection predicates, failure paths, and error handling.230
- New packages split from sigil-studio. Font and image modules moved to (sigil graphics *) namespace.231
- New package split from sigil-studio. Added playlist support with wait-music-end and play-playlist. Fixed native exports in Scheme module.