# Noise listening app — implementation notes

The app follows the student prompt in `prompt.txt`. It is plain HTML, CSS and JavaScript, uses native Web Audio, and makes no network requests for audio or libraries.

## Behaviour

- Three native radio controls choose white, pink or brown noise; each includes one short listening cue.
- Sound starts only from the on/off button. Initial level is 20%; the level slider spans 0–100% with a conservative internal maximum gain of 0.42.
- White noise uses uniform random samples. Pink noise uses Paul Kellet's recursive approximation. Brown noise uses a leaky integrator with a 20 Hz turnover, so it remains bounded and does not accumulate DC.
- Six-second mono buffers are generated at the device's sample rate. A 250 ms crossfade makes the loop boundary continuous. Each buffer has its DC offset removed.
- Four FFT windows estimate A-weighted RMS. The three buffers are approximately matched using that estimate, then all receive the same peak-safety scaling. This is approximate perceived-level matching, not an SPL measurement or a guarantee of equal subjective loudness.
- A single buffer source connects through gain and an analyser to the output. Colour changes fade down, stop and disconnect the previous source, then start the new source with a short fade up. Sources do not overlap or accumulate. Fast changes cancel the pending switch.
- The log-frequency spectrum averages power per frequency bin within narrow display bands, showing the signal after the level control. The vertical scale is dBFS. Off state shows an empty grid rather than fabricated audio data.
- No user effects, downloads, sound files, recording, microphone input or external services.

## Snapshot

`attempts/001/` contains the first complete implementation, copied before checks or revisions. It is retained unchanged.

## Checks and limitations

- Browser and listening checks are reserved for the root agent; I did not listen to the result or use browser tools.
- `node --check app.js` passed. A Node-only DSP check generated all three colours at 44.1 and 48 kHz: all samples were finite, peak amplitudes remained at or below 0.85, DC means were near zero, and the A-weighted RMS estimates matched across colours to better than 0.1%. This checks calculations, not audible quality. Root will verify actual browser behaviour.
- After the immutable first snapshot, an initialization promise was added to handle repeated clicks during the first synthesis, and slider changes now preserve an in-progress colour fade.
- A-weighting is a rough comparison aid. Speaker response, headphones, hearing and noise colour can affect subjective loudness; the user can adjust level.
- Pink-noise coefficients are the common 44.1 kHz approximation; the curve is approximate at other device rates.
- Mono playback and repeated six-second random buffers keep processing light; long focused listening may reveal repetition.
- The app requires a modern Web Audio browser with `cancelAndHoldAtTime`, `ResizeObserver`, and CSS `:has` support.
