# Audio credits

Every file in this directory is **CC0 1.0** (public-domain dedication) — free for commercial use,
no attribution required. Credit is given here anyway because the authors deserve it.

Nothing here is CC-BY, CC-BY-SA, or "free for non-commercial". A file whose licence could not be
proved from the asset's own page was not shipped. If you add a file, add its row here first.

Last full re-master: **2026-08-20**. All 28 files were re-sourced or re-mastered through one
chain and one loudness model in that pass; the numbers below were measured on the shipped files,
not carried over.

---

## Sources

| Source | Author | Licence | Licence proof | URL |
|---|---|---|---|---|
| Impact Sounds 1.0 | Kenney | CC0 1.0 | pack `License.txt`: *"License: (Creative Commons Zero, CC0) http://creativecommons.org/publicdomain/zero/1.0/"* | https://kenney.nl/assets/impact-sounds |
| Music Jingles | Kenney | CC0 1.0 | pack `License.txt`, same wording | https://kenney.nl/assets/music-jingles |
| Car Sound Effects Pack (Low Quality) | GGBotNet | CC0 1.0 | OGA page lists CC0 as its only licence; the pack's Vorbis files also carry `COMMENTS=CC0` in their own tags (verified with `ffprobe`) | https://opengameart.org/content/car-sound-effects-pack-low-quality |
| Screeching Tires #1 (sound 2368, `VEHSkid`) | Dorian CLAIR — BigSoundBank (Joseph SARDIN) | CC0 1.0 | asset page: *"License CC0 (public domain): Free and royalty-free"* | https://bigsoundbank.com/screeching-tires-1-s2368.html |
| Sirens and Alarm Noise | aquinn | CC0 1.0 | OGA page: CC0 is the only licence listed | https://opengameart.org/content/sirens-and-alarm-noise |
| High traffic road sounds | IgnasD | CC0 1.0 | OGA page: CC0 is the only licence listed | https://opengameart.org/content/high-traffic-road-sounds |
| 37 hits/punches | Independent nu ljudbank | CC0 1.0 | OGA page: *"License(s): CC0"*, nothing else listed | https://opengameart.org/content/37-hitspunches |
| Female Scream 1 | Nocturnal_Vanguard | CC0 1.0 | OGA page: *"License(s): CC0"*, nothing else listed | https://opengameart.org/content/female-scream-1 |

**No longer used:** Kenney *RPG Audio* (was the old `cash.ogg`), domasx2 *racing car engine sound
loops* (was the old `engine.ogg`), Fun Gi Development *Drag Racing SFX* (was the old `skid.ogg`).
Their rows are dropped because nothing in this directory references them any more.

---

## The mastering chain

Twenty-six files pulled from five packs sat at five different loudnesses, five different room
tones and five different EQ curves. That — not fidelity — is what "all over the place" meant.
The fix is one chain applied identically to everything.

- **Format.** 48 kHz. Mono for anything that reaches a `PannerNode`; only `cash` and `sting`, which
  never do, stay stereo. Opus in an `.ogg` container: 64k mono for one-shots and short loops, 40k
  for the 20 s bed, 96k for the two stereo UI files.
- **Filter.** `highpass=f=60` and `lowpass=f=15000` on every file. The high-pass is what removed
  the per-pack DC offset: the worst file used to sit at −0.00671 and the whole set is now within
  **0.000037** of zero, so nothing adds a low-frequency thump of its own on playback any more.
- **Trim.** No more than ~5 ms of lead-in before the onset, and a raised-cosine tail fade instead
  of a hard cut. The old set had twelve files hard-stopping mid-ring between −34.8 and −50.0 dBFS,
  which is an end-click on every crash and every footstep. Nothing stops above −59 dB now.
- **Loudness.** Per class, not per file, and each **variation set is normalised as a set** — one
  shared offset, so the takes keep their relative character. Individually normalising a set is how
  you get a machine gun of identical hits.
- **No reverb, no saturation, no denoise.** `afftdn` was not needed on any file: the two newly
  sourced packs measured a digital-silence floor (< −239 dB relative to peak) and every other
  family comes from a single pack with a single room tone.

### Which loudness number, and why it is not `loudnorm`'s

EBU-R128 **gated** integrated loudness (`loudnorm`'s `input_i`) is **undefined for 13 of these
files** — every file under ~0.42 s returns `-inf`, because the 400 ms gating block never
completes. Every level in this document is therefore an **ungated K-weighted BS.1770**
measurement (`treble=f=1681.97:g=3.999:q=0.7071` + `highpass=f=38.13:q=0.5`, then RMS, −0.691),
which is defined at any length and reproduces `loudnorm` on the files where `loudnorm` works.

Two columns follow from that:

- **`I`** — ungated K-weighted integrated. The right number for a **sustained** sound (the four
  loops, and `engine-start`).
- **`t50`** — the same K-weighting through a 50 ms sliding RMS window, peak-held. The right number
  for a **one-shot**: it is what predicts how loud a 200 ms crash *sounds*, and whole-file average
  does not.

Each file is normalised on the axis that suits its content, and the class targets are expressed on
that axis. Mixing the two axes is exactly what went wrong in the intermediate passes of this
re-master: a door slam normalised to a whole-file target reads 7 dB too loud on the transient.

### Class targets (t50, one-shots)

Relative to a heavy crash, which is the loudest thing in the game:

| Class | Δ vs crash | t50 target | Files |
|---|---|---|---|
| heavy impact / crash | 0 | −12.1 | `hit-heavy-*` |
| punch / kick | −1 | −13.1 | `punch-*` |
| light impact / world scrape | −2 | −14.1 | `hit-light-*` |
| UI | −2 | −14.1 | `cash`, `sting` |
| horn | −3 | −15.1 | `horn` |
| voice | −3 | −15.1 | `scream` |
| glass layer | −5 | −17.1 | `glass-*` |
| doors | −5 | −17.1 | `door-open`, `door-close` |
| footsteps | −8 | −20.1 | `step-*` |

`glass-*` sits 5 LU under the crash rather than level with it because glass is **layered on top of**
a heavy hit, never played alone — at equal level the pair would sum 3 dB above a crash by itself.

### Class targets (I, sustained)

| Class | I target | Files |
|---|---|---|
| engine loop / engine start | −18 | `engine`, `engine-start` |
| skid loop | −18 | `skid` |
| siren | −17 | `siren` |
| ambience bed | −26 | `ambience` |

---

## Files

| File | Event | Origin | Edit |
|---|---|---|---|
| `engine.ogg` | engine loop, `playbackRate` by speed | GGBotNet `Car_Engine_Loop.ogg` @ 0.30–1.90 s | **replaced** (was domasx2). hp60/lp15k, 0.20 s wrap crossfade → 1.40 s loop |
| `engine-start.ogg` | ignition on carjack | GGBotNet `Car_Engine_Start_Up.ogg` | re-mastered from the pack's Vorbis original; 80 ms lead-in trimmed, hp60/lp15k, 5 ms tail fade |
| `horn.ogg` | horn | GGBotNet `Car_Horn.ogg` | re-mastered; 20 ms lead-in trimmed, hp60/lp15k, −2.5 dB shelf above 5 kHz to tame source clipping, 5 ms tail fade, re-normalised on t50 |
| `door-open.ogg` | door yanked open (carjack) | GGBotNet `Car_Door_Open.ogg` | re-mastered; hp60/lp15k, 5 ms tail fade, re-normalised on t50 (no limiting — crest 19.79 preserved) |
| `door-close.ogg` | door shut on exit | GGBotNet `Car_Door_Close.ogg` | re-mastered; 110 ms of handle/latch lead-in trimmed so the slam is the transient, hp60/lp15k, 5 ms tail fade, re-normalised on t50 |
| `skid.ogg` | tyre skid loop | BigSoundBank `2368.wav` @ 0.88–1.82 s | **replaced** (was a drag burnout). hp120/lp15k, natural decay flattened ±5 dB, 0.24 s wrap crossfade → 0.70 s loop |
| `siren.ogg` | police siren loop | aquinn `siren.mp3` @ 3.560–5.065 s | loop end re-trimmed to a slope-matched downward zero crossing, then a 2 ms raised-cosine fade at both ends. hp60/lp15k. 1.5021 s |
| `ambience.ogg` | city bed | IgnasD `gatve Varniu_2.ogg` @ 8.0–28.5 s | **de-evented**: a circular (period-exact) gain curve smoothed over ~1.0 s flattens the recording's own pass-bys. Low shelf −3.5 dB @ 200 Hz, hp60/lp15k through a 1 s circular pad so the IIR transient cannot land on the seam. Opus 40k |
| `hit-light-{0,1,2}.ogg` | light car impact | Kenney `impactMetal_light_{000,002,004}` | re-mastered from the pristine pack files, hp60/lp15k, 8–10 ms tail fade, set-normalised |
| `hit-heavy-{0,1,2}.ogg` | heavy car impact | Kenney `impactMetal_medium_{000,003,004}` + `impactPlate_medium_{001,002,004}` (−2 dB) | **layered** crunch-over-body, both layers from this one pack. hp60/lp15k, 12 ms tail fade, set-normalised |
| `glass-{0,1,2}.ogg` | glass / debris | Kenney `impactGlass_light_{000,003,001}` | replaces the old `impactGlass_heavy` takes. highpass **250 Hz** so the layer sits above the crash body, lp15k, 8 ms tail fade |
| `punch-{0,1,2}.ogg` | punch / kick / ped hit | ljudbank `hit{17,31,32}` | **replaced** (was Kenney `impactPunch`). 44.1→48 kHz mono, hp60/lp15k, lead-in trimmed, 15 ms tail fade, ±2 dB shelf @ 1.5 kHz to converge the set's brightness, set-normalised |
| `step-{0..4}.ogg` | footstep (walk and run) | Kenney `footstep_concrete_{000..004}` | re-mastered from the pristine pack files. hp60/lp15k, lead-in trimmed, 8 ms tail fade, ±4 dB shelf @ 1.5 kHz to converge the set's brightness, set-normalised |
| `scream.ogg` | ped scream (`impact({kind:'scream'})`) | Nocturnal_Vanguard `female_scream_1.ogg` | **new**. hp60/lp15k, 350 ms of leading silence trimmed, 25 ms tail fade |
| `cash.ogg` | cash pickup | Kenney `jingles_STEEL16.ogg` | replaces Kenney RPG Audio `handleCoins.ogg`. Rising steel figure (+6.8 semitones), same pack/room as `sting`. 44.1→48 kHz, hp60/lp15k, 5 ms tail fade. **stereo** Opus 96k |
| `sting.ogg` | wanted-level sting | Kenney `jingles_HIT03.ogg` | 44.1→48 kHz, 13.2 ms lead-in trimmed, natural −119 dBFS decay left intact. hp60/lp15k. **stereo** Opus 96k |

Positional sounds are mono on purpose: a `PannerNode` gains nothing from a stereo buffer and it
costs twice the decoded memory. Only the two UI sounds, which never reach a panner, stay stereo.

Every file above is derived from the upstream original, not from a previously shipped `.ogg`, so
nothing carries a second-generation encode. The upstream files can be re-fetched from the URLs in
the Sources table.

---

## Measured (shipped files)

`I` = ungated K-weighted integrated. `t50` = 50 ms K-weighted sliding-RMS peak. `TP` = true peak,
4x oversampled. `file pk` = peak sample in the decoded Opus, measured with `ffmpeg`. `dec pk` =
peak sample after `decodeAudioData` **in Chrome**, which is the number `GAIN` in `src/audio.js` is
tuned against. `max_vol` is `volumedetect`'s `max_volume`: **no file is `-inf`, i.e. nothing is
silent**, and every buffer decoded non-zero in the browser as well.

| File | Dur s | Ch | Rate | I | t50 | TP dB | file pk | dec pk | max_vol | tail / seam |
|---|---|---|---|---|---|---|---|---|---|---|
| `ambience.ogg` | 20.006 | 1 | 48000 | −26.58 | −22.74 | −12.10 | 0.2485 | 0.2501 | −12.1 | seam 0.03x |
| `cash.ogg` | 0.915 | 2 | 48000 | −24.95 | −14.02 | −8.21 | 0.3886 | 0.3891 | −8.2 | −73.7 dB |
| `door-close.ogg` | 0.539 | 1 | 48000 | −26.57 | −17.26 | −7.19 | 0.4369 | 0.4368 | −7.2 | −59.1 dB |
| `door-open.ogg` | 0.370 | 1 | 48000 | −25.37 | −17.22 | −4.63 | 0.5866 | 0.5836 | −4.6 | −60.5 dB |
| `engine-start.ogg` | 1.874 | 1 | 48000 | −17.99 | −12.04 | −3.82 | 0.6439 | 0.6439 | −3.8 | −75.1 dB |
| `engine.ogg` | 1.407 | 1 | 48000 | −18.31 | −15.75 | −5.35 | 0.5401 | 0.5410 | −5.4 | seam 0.40x |
| `glass-0.ogg` | 0.237 | 1 | 48000 | −24.48 | −17.91 | −7.42 | 0.4254 | 0.4276 | −7.4 | −124.7 dB |
| `glass-1.ogg` | 0.213 | 1 | 48000 | −23.55 | −17.46 | −5.82 | 0.5116 | 0.5106 | −5.8 | −101.5 dB |
| `glass-2.ogg` | 0.213 | 1 | 48000 | −23.30 | −17.19 | −6.29 | 0.4849 | 0.4832 | −6.3 | −105.1 dB |
| `hit-heavy-0.ogg` | 0.623 | 1 | 48000 | −22.32 | −11.81 | −1.12 | 0.8794 | 0.8801 | −1.1 | −67.4 dB |
| `hit-heavy-1.ogg` | 0.522 | 1 | 48000 | −21.86 | −11.98 | −1.48 | 0.8430 | 0.8363 | −1.5 | −79.3 dB |
| `hit-heavy-2.ogg` | 0.541 | 1 | 48000 | −22.45 | −12.58 | −1.19 | 0.8722 | 0.8583 | −1.2 | −66.0 dB |
| `hit-light-0.ogg` | 0.379 | 1 | 48000 | −21.89 | −13.53 | −5.39 | 0.5376 | 0.5412 | −5.4 | −110.4 dB |
| `hit-light-1.ogg` | 0.239 | 1 | 48000 | −21.25 | −14.68 | −5.08 | 0.5575 | 0.5534 | −5.1 | −99.2 dB |
| `hit-light-2.ogg` | 0.217 | 1 | 48000 | −21.02 | −14.85 | −4.90 | 0.5690 | 0.5738 | −4.9 | −100.9 dB |
| `horn.ogg` | 0.471 | 1 | 48000 | −21.91 | −15.11 | −6.19 | 0.4903 | 0.4904 | −6.2 | −84.1 dB |
| `punch-0.ogg` | 0.518 | 1 | 48000 | −21.28 | −13.87 | −4.29 | 0.6100 | 0.6102 | −4.3 | −92.8 dB |
| `punch-1.ogg` | 0.392 | 1 | 48000 | −17.70 | −12.35 | −2.62 | 0.7396 | 0.7385 | −2.6 | −75.2 dB |
| `punch-2.ogg` | 0.420 | 1 | 48000 | −18.54 | −13.22 | −4.16 | 0.6191 | 0.6143 | −4.2 | −80.7 dB |
| `scream.ogg` | 0.961 | 1 | 48000 | −20.04 | −15.12 | −9.96 | 0.3177 | 0.3139 | −10.0 | −95.2 dB |
| `siren.ogg` | 1.509 | 1 | 48000 | −17.54 | −16.60 | −9.03 | 0.3537 | 0.3528 | −9.0 | seam 0.03x |
| `skid.ogg` | 0.707 | 1 | 48000 | −18.36 | −17.41 | −7.54 | 0.4197 | 0.4204 | −7.5 | seam 0.19x |
| `step-0.ogg` | 0.075 | 1 | 48000 | −20.77 | −19.37 | −3.03 | 0.7059 | 0.7056 | −3.0 | −65.4 dB |
| `step-1.ogg` | 0.080 | 1 | 48000 | −22.63 | −20.95 | −2.84 | 0.7210 | 0.7224 | −2.8 | −67.4 dB |
| `step-2.ogg` | 0.079 | 1 | 48000 | −22.57 | −20.95 | −2.82 | 0.7229 | 0.7213 | −2.8 | −67.5 dB |
| `step-3.ogg` | 0.076 | 1 | 48000 | −21.57 | −20.15 | −2.47 | 0.7524 | 0.7529 | −2.5 | −66.2 dB |
| `step-4.ogg` | 0.081 | 1 | 48000 | −21.18 | −19.47 | −2.78 | 0.7260 | 0.7257 | −2.8 | −67.6 dB |
| `sting.ogg` | 0.739 | 2 | 48000 | −17.78 | −12.41 | −4.55 | 0.5922 | 0.5910 | −4.5 | −117.8 dB |

### Coherence, before and after

The number that matters is not raw spread — the intended mix hierarchy is 12 dB wide by design —
but **deviation from each file's class target**:

| | Before | After |
|---|---|---|
| Deviation from class target, all files | 17.56 LU | **2.54 LU** (−0.83 … +1.71) |
| Raw whole-set loudness spread (`I`) | 17.58 LU | 9.04 LU |
| `glass-*` internal spread | 5.70 LU | **0.72 LU** |
| `step-*` internal spread | 1.83 LU | **1.58 LU** |
| `punch-*` internal spread | 1.28 LU | **1.52 LU** |
| `hit-light-*` internal spread | 1.68 LU | **1.32 LU** |
| `hit-heavy-*` internal spread | 1.90 LU (whole-file) | **0.77 LU** |
| Files over 0 dBTP | 22 of 26 | **0 of 28** |
| Highest decoded peak | 2.764 (`horn`) | **0.880** (`hit-heavy-0`) |
| Largest DC offset | 0.00671 | **0.000037** |
| Files hard-stopping mid-ring | 12 | **0** |
| `step-*` spectral centroid spread | 2.87x | **1.18x** |
| `punch-*` spectral centroid spread | 2.99x | **1.56x** |

**Severity inversion fixed.** `hit-heavy` now averages −12.12 t50 against `hit-light`'s −14.35:
crossing the `sev 0.35` threshold into a heavier crash now makes it **2.2 dB louder**. It used to
make it 2.4–4.4 dB *quieter*, with the centroid collapsing by a factor of 4.3 at the same moment.

**"Horn never louder than a smash" holds.** `horn` was the loudest file in the set on every metric
(−6.95 LUFS, +8.90 dBTP, decoded peak 2.764). It now sits 3.0 LU under a heavy crash on the
transient, which is where the class table puts it, and it decodes to 0.490.

### Loop seams — verified, not asserted

Wrap-point sample step as a fraction of each file's own interior 99.9th-percentile sample delta,
measured on the **decoded Opus**. Under 0.5x is the bar. Each loop was additionally concatenated
to itself: in all four, the largest sample-to-sample step within ±5 ms of the join is *below* the
file's own interior p99.9, so there is no impulse there, and the 20 ms RMS either side of the join
steps by at most 2.1 dB.

| File | Wrap step | Ratio | Note |
|---|---|---|---|
| `ambience.ogg` | 0.00093 | **0.03x** | was 0.37x |
| `siren.ogg` | 0.00168 | **0.03x** | was 4.61x — a real −7.2 dBFS click every 1.5 s. Earlier revisions of this file claimed the seam was clean; it was not |
| `skid.ogg` | 0.01581 | **0.19x** | |
| `engine.ogg` | 0.01239 | **0.40x** | was 3.34x of the old file's interior *max*, plus a 4.39 dB level step |

---

## Two source replacements worth knowing about

**`skid.ogg` — the tyre squeal exists now.** Earlier revisions of this file recorded that no CC0
tyre-squeal recording could be found, and shipped a drag-racing burnout with a 1.6 kHz band-pass
in the mixer to fake tone out of broadband noise. BigSoundBank had simply not been checked. The
new file is a real outdoor 48 kHz / 24-bit recording of four tyres squealing and holds a stable
**1021–1043 Hz tone** at every point in the loop (autocorrelation 0.57–0.70); the old one had no
stable pitch at all. Both OpenGameArt squeals are CC-BY 3.0 and were rejected.

**`punch-*.ogg` — the punch has a slap now.** All ten Kenney `impactPunch` takes measure as
sub-bass booms: 2–6 kHz sits **24 to 47 dB** below their own broadband RMS and the 85% rolloff is
at 91–340 Hz, i.e. there is no knuckle in them, only body. The three shipped files come from
ljudbank's CC0 *37 hits/punches* and measure **−4.5 to −5.7 dB** in that band — about 35 dB more
slap — with a 1182–1844 Hz centroid instead of 208–623 Hz. They still carry body: the sub-250 Hz
band is 1.3–3.2 dB down, not scooped.

---

## Still not found

- **Nothing.** Both holes recorded in earlier revisions of this file are closed: `skid.ogg` is a
  real cornering squeal, and `scream.ogg` is a real CC0 human voice. `impact({kind:'scream'})` is
  no longer silent.
- The one remaining known compromise is variety, not licensing: there is **one** scream, so a
  crowded pile-up repeats it. `dedupe` in `src/audio.js` collapses same-clip repeats within 30 ms
  and 3 m, which covers the worst of it. If it grates, the same CC0 author's page and the CC0-only
  OGA collections *Death sounds* and *Female RPG Voice Starter Pack* have more takes; make
  `CLIPS.scream` an array and set-normalise the additions to t50 −15.1 with the chain above.
