# synth
The DSP bench Helsinki Life's sounds are computed on. It renders mono f32
tracks out of arithmetic - oscillator stacks, filtered noise, envelopes,
pitch names - and encodes them into the ZAUD payload a `.soundClip` stores.
No network, no host file, no service: it runs headless and costs only CPU.
Consumed by `game.sound.bank`, which holds one recipe per sound in the game.
## Tracks wrap, and that is the point
`Synth.track(seconds, rate)` is a fixed-length buffer, and every generator
writes **wrapped**: a note starting near the end continues at the head. A
track rendered this way is one period of an infinite periodic signal, so
its last frame runs into its first with no step - whatever frequencies it
holds and however long the tails are. That is what makes the looping beds
seamless, and `clipRef:loopSeam()` reads the result back.
## What it offers
| Call | What it makes |
|---|---|
| `Synth.track(seconds, rate?)` | An empty track. `RATE_SFX` is 48 kHz, `RATE_BED` 24 kHz. |
| `Synth.tone(tr, start, dur, freq, amp, opts)` | One note. `opts.wave` picks a partial stack; glide, vibrato and detune are there too. |
| `Synth.noise(tr, start, dur, amp, opts)` | A noise burst through a low-pass, high-pass or swept band-pass. |
| `Synth.chord(tr, start, dur, freqs, amp, opts)` | The same note shape at several frequencies. |
| `Synth.hz("F#3")` | A pitch name as a frequency. |
| `Synth.fromPcm(pcm, srcRate, channels, dstRate)` | Audio from elsewhere, folded to mono and resampled through a pre-filter. |
| `Synth.loopify(tr, loopSeconds, fadeSeconds)` | A seamless loop cut out of a longer take by equal-power crossfade. |
| `Synth.blend` / `gain` / `normalize` / `peak` / `rms` | Mixing and finishing. |
| `Synth.encode(tr, opts?)` | The ZAUD payload; `pcm` by default. |
`wave` names: `sine`, `tri`, `square`, `saw`, `reed`, `celesta`, `pluck`,
`bell`, `gong`, `horn`. A partial carrying a `decay` above 1 fades faster
than the note body, which is what makes a struck bell sound struck.
```lua
local Synth = require("game.sound.synth")
local tr = Synth.track(1.0, Synth.RATE_SFX)
Synth.tone(tr, 0, 0.9, Synth.hz("A5"), 0.5, { wave = "gong", decay = 3.2 })
Synth.normalize(tr, 0.88)
local zaud = Synth.encode(tr)
```
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# HL
The shared spine of *Helsinki Life*: constants, the board graph (43 tiles with
positions, kinds, districts and successors), landmark anchors, camera framing
numbers, the game state container, the event bus the slices talk over, the
`HL.actions` table the rules fill in, the pacing (`HL.TIMING`) and the sound
names (`HL.SFX`).
```lua
local HL = require("game.core.HL")
HL.tile(6).next -- { 7, 101 }: the fork at Pasila station
HL.pawnSlot(22, 2) -- where pawn 2 stands on the Cathedral tile
HL.on("moveStep", function(ev) ... end)
HL.emit("sfx", { name = "hop" })
HL.state().players[1].money
```
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
# SoundClip
Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).