# Filter app implementation

Date: 2026-10-29

Implemented from `prompt.txt`. The only prior app source read was `../04-noise/index.html`, `style.css`, and `app.js`. Its noise synthesis, colour calibration, loop crossfade, and general visual style are retained here. No other app, slide, history, attempt, or implementation note was consulted.

## Choices

- Standalone HTML, CSS, and JavaScript. Native Web Audio only. No assets, libraries, requests, or external services.
- Sound starts through the explicit on button. Defaults are white noise, 20% level, bypass, frequency about 1 kHz, and Q 0.71.
- Bypass, high-pass, low-pass, and band-pass are radio choices. Frequency is a logarithmic 20 Hz to 16 kHz control. Its label changes to Cutoff frequency for high/low-pass and Centre frequency for band-pass. Bypass disables frequency and Q.
- Original and Filtered compare the same running noise source. Three fixed filter branches remain fed by that source; the listening controls crossfade their output gains. Selecting a filter, moving a parameter, or comparing does not recreate or restart the source. Changing the noise colour deliberately replaces the source after a fade.
- Q ranges from 0.5 to 8. Low/high-pass Q is translated to the native Web Audio dB parameter with `20 * log10(Q)`. Band-pass uses native linear Q. The bandwidth explanation changes for band-pass.
- The low/high-pass input is attenuated by the maximum biquad response when resonance rises. Attenuation is applied before raising Q; level returns more slowly after Q falls. A compressor and the retained conservative master gain provide further control.
- The response graph is a calculated transfer response, including the displayed level trim. It is available while sound is off. The dashed original line is 0 dB, and the orange curve is the selected filter. It does not claim to measure the room, headphones, or noise spectrum.
- Native radios and range controls support keyboard operation. Labels, value text, canvas descriptions, and a status announcement are included. Layout changes to stacked controls on narrow screens.

## First complete implementation

`attempts/001/` preserves the first complete `index.html`, `style.css`, and `app.js` before checks. These files have not been edited after capture. The current implementation differs only in one JavaScript comment, which now says the rounded logarithmic frequency starts near 1 kHz.

Snapshot SHA-256 values:

```text
c42e8f31105859429a9618b60ed5e8aeef02db5d8a5bcacb52486e7f0b9669cd  index.html
ced33cc2153eedfdf4cfaa3f556ad3b1baacc35e153d63072c2a4b1a5ed8daa8  style.css
7c37c838ddc3c30943f7d096dd2222e8685a5080f281b2ca772bcdd71f604dc6  app.js
```

## Checks completed here

- `node --check app.js` passed.
- HTML parsing found 19 unique IDs. All 19 JavaScript ID selectors and all explicit label targets exist. Both linked dependencies are local files. No network calls or external assets were found.
- A numerical sweep sampled the response 540,270 times across all three filter types, Q 0.5 to 8, cutoffs 20 Hz to 16 kHz, and sample rates 44.1, 48, and 96 kHz. Values were finite; maximum compensated gain was 1.00000000.
- The initial rounded logarithmic position corresponds to 998.48 Hz.

## Limits and remaining checks

- No browser, server, playback, screenshot, or listening test was run in this subtask. The coordinating agent handles those checks at `http://127.0.0.1:4191/apps/05-filters/`.
- Comfortable acoustic volume still depends on the device and its output volume. The response curve describes the filter and its trim, before the compressor.
- As in the previous noise app, pink noise uses an approximation designed around 44.1 kHz, and colour loudness matching is approximate. Each colour loops a six-second generated buffer.
- No Git, commit, push, or shared-file changes were made.
