summaryrefslogtreecommitdiff
path: root/docs/chapter31/audio.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/chapter31/audio.md')
-rw-r--r--docs/chapter31/audio.md62
1 files changed, 62 insertions, 0 deletions
diff --git a/docs/chapter31/audio.md b/docs/chapter31/audio.md
new file mode 100644
index 00000000..30817012
--- /dev/null
+++ b/docs/chapter31/audio.md
@@ -0,0 +1,62 @@
+# Optional background audio
+
+`sys.audio` uses [miniaudio](https://github.com/mackron/miniaudio) through an
+optional native C backend. Playback runs on its own thread; the game keeps
+processing input and drawing. No Python, CMake, codec packages, or sound files
+are needed. Default builds/tests never download miniaudio or open a device.
+
+From `chapter31`:
+
+```sh
+make libs CTAGS= # Once while online, or use make init.
+make audio CTAGS=
+make run-graphical-tictactoe CTAGS=
+```
+
+The last command builds both optional backends and runs the game. Accepted
+moves get a quiet 70ms sine boop. A player win gets a 480ms rising C-E-G
+celebration; a CPU win reverses the notes. Invalid input and occupied squares
+are silent. Replay stops any previous cue. Win/loss cues replace the ordinary
+move boop; draws use the ordinary boop.
+
+For direct execution in PowerShell, alongside `SIMPLE_MINIFB`:
+
+```powershell
+$env:SIMPLE_MINIAUDIO = (Resolve-Path build/release/x86_64_v2_win64/simple_miniaudio.dll).Path
+.\build\examples\x86_64_v2_win64\TicTacToeGraphical.exe
+```
+
+Linux uses `libsimple_miniaudio.so` in the corresponding release directory.
+`SIMPLE_MINIAUDIO` must name the full backend path. Unset it or set it to `off`
+for silent play. An unavailable audio device returns `ERROR` and the game
+continues. Audio and graphics can be configured independently.
+
+| Operation | Meaning |
+| --- | --- |
+| `open()` | Open output and generate built-in sounds; `OK` (0) or `ERROR` (-1). Repeated open is safe. |
+| `boop()`, `win()`, `lose()` | Play a built-in cue; same as `play(BOOP/WIN/LOSE)`. |
+| `load(samples)` | Copy `i16[~]` mono PCM at `RATE` (48000Hz); return handle or `ERROR`. |
+| `play(handle)` | Start/restart, replacing the current sound. Return `OK` or `ERROR`. |
+| `stop()` | Stop playback; safe before open/after close. |
+| `playing()` | Whether samples remain to submit; final device buffering may remain. |
+| `close()` | Join the audio thread and free device/buffers; safe to repeat. |
+
+All calls belong on the main/game thread. Load custom sounds at startup:
+there are 28 custom slots, each up to ten seconds, retained until close.
+Custom handles must be reloaded after close/reopen. Signed samples range
+from -32768 to 32767; quiet effects should use much smaller amplitudes.
+Native code copies the array and never retains a Simple heap pointer or calls
+Simple from the audio thread. Playback itself neither allocates nor waits for
+the sound duration. This first interface plays one sound at a time.
+
+`audio.mk` pins miniaudio 0.11.23, cached under `lib/miniaudio-0.11.23/` by
+`make libs` (or `init`; `lib` remains a setup alias). Only these explicit setup
+targets can download dependencies. All builds, runs, and tests use local
+copies, surviving `make clean`; missing cache entries fail promptly with setup
+instructions. Windows uses the existing MinGW-w64 compiler;
+Linux uses GCC and system pthread/math/dl libraries. No audio development
+headers need installing. The upstream header includes its public-domain and
+MIT-0 license options, copied beside the backend as `miniaudio-LICENSE`.
+`make test-audio CTAGS=` builds the backend checks from the local cache
+and runs a real audio thread with miniaudio's silent null
+device; normal tests exercise the loader and game without hardware.