Adds the Audio.* namespace and its platform backend, the audio subsystem #22 was blocked on. - runtime/native/audio.ll: the macOS backend, AVAudioPlayer driven through the objc runtime C ABI (no ObjC/C source), same style as cocoa.ll — snd_load / play / stop / playing / set_volume / set_rate. Spliced and linked with AVFoundation only when a windowed build actually uses Audio.* (needed_framework, since AVAudioPlayer is reached by name). - runtime/native/audio.ludic: the Audio.* runtime — a handle table, master volume/pitch, a single music channel. load/play/play_sound/play_music/stop/ stop_music/stop_all/volume/pitch/is_playing. Every native call is is_windowed()-guarded, so a headless build carries the API as no-ops (load returns 0, is_playing false) and needs no audio device. - compiler: Audio.* namespace dispatch, g_uses_audio splice, snd_* intrinsics + declarations, and the conditional AVFoundation link in both the canonical (main.ludic) and dev-runner (x app) paths. - docs: a full docs/language/audio section (10 method pages); check-impl green. - test: examples/library/audio.ludic self-asserts the headless no-op path. Playback is out-of-band and never feeds the deterministic sim, but triggers are frame-driven so replays fire the same sounds. Reseeded; suites green (80 + 29). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15 lines
1,018 B
Markdown
15 lines
1,018 B
Markdown
bump: minor
|
|
type: feat
|
|
**Audio standard library (#22).** `Audio.*` — sound effects and music over a new
|
|
platform audio backend (`runtime/native/audio.ll`, AVAudioPlayer on macOS, spliced
|
|
and linked with AVFoundation only when a windowed build uses it). `Audio.load`
|
|
loads a sound file into a handle; `Audio.play` / `play_sound` fire it one-shot,
|
|
`play_music` loops it on a single music channel; `Audio.stop` / `stop_music` /
|
|
`stop_all` stop them; `Audio.volume` sets the master volume and `Audio.pitch` the
|
|
playback rate, both across every loaded sound; `Audio.is_playing` reports state.
|
|
Playback is out-of-band — the audio device is real-time, explicitly not part of
|
|
the deterministic simulation — but every trigger is an ordinary frame-driven
|
|
call, so a recorded/replayed run fires the same sounds at the same frames.
|
|
Headless builds carry the whole API as no-ops (the native `snd_*` calls are
|
|
`is_windowed()`-guarded and dead-stripped), so the same game code runs under the
|
|
test harness with no audio device.
|