# `audio`

Audio devices and the programs' streams, from PipeWire, and levels for
a visualiser of one's own (`audio.levels`).

| Field | Type | |
| --- | --- | --- |
| `sink` | `AudioDevice` | The default output: `audio.sink.volume`, `audio.sink.muted`. |
| `source` | `AudioDevice` | The default input. |
| `sinks` | `[AudioDevice]` | Every output, keyed by `id`. |
| `sources` | `[AudioDevice]` | Every input, keyed by `id`. |
| `streams` | `[AudioStream]` | The programs' streams, keyed by `id`: what plays (a per-app mixer: `for st in audio.streams.filter(s => s.direction == output) key st.id { slider { value: <-> st.volume } }`) and what records (a microphone indicator: `audio.streams.any(s => s.direction == input)`). Followed only while a reader reads it. Peak meters (pavucontrol's, Strand's own) are left out. |
| `meters` | `[AudioMeter]` | The meters `audio.levels` runs, keyed by `device`: each one's latest spectrum, 64 bands from low to high pitch, each 0 to 1 (none while its device is quiet). Read through `audio.levels`, which asks for the meter; reading this field runs none. |

| Method | |
| --- | --- |
| `fn levels(device: AudioDevice, bars: int = 16) -> [float]` | `device`'s sound now, as `bars` levels from low to high pitch, each 0 to 1 (zeros while it is quiet), for a visualiser of one's own (`let v = audio.levels(audio.sink, 32)`, drawn by a `canvas`); `audio.levels(audio.source, 1)[0]` is a microphone's level. Its meter runs while a reader of `audio` is visible and something evaluates `levels` for that device; one no evaluation has asked for within a second stops. `bars` is at most 512. |
