# LFO implementation

Built from the supplied `06-envelope` HTML, CSS and JavaScript source. Read only its source files, without attempts, notes, slides or other experiments. The student request is preserved in `prompt.txt`.

The page keeps the existing noise colours, filter choices, original/filtered comparison, attack, release and stop. It adds a native Web Audio sine OscillatorNode, initially set to 0.1 Hz, with volume as its destination and 55% depth. The oscillator and audio context are created only by the Start action. No sound starts from editing a control.

Volume modulation adds a bipolar offset to the manual base gain. At 100% depth it ranges from silence to twice the base gain. The existing conservative source gain and compressor remain in place. Displayed volume may exceed 100% because it reports a multiple of the manual source scale, rather than clipping the upper half of the wave.

Frequency modulation uses the selected filter's detune input, with a sine sweep in octaves around the manual frequency. Full depth allows up to three octaves each way. The range contracts near the endpoints to remain within 20 Hz and 16 kHz, or the audio context's lower Nyquist allowance. Choosing frequency from bypass selects low-pass and filtered listening so the movement is audible. The user can still choose bypass or original afterward; an on-page hint then explains why no filter movement is heard.

Each filter has a separate LFO depth gain. Only the chosen filter receives a nonzero modulation depth, and volume depth is zero for the frequency destination. Turning LFO off sets every depth to zero, which restores the manual base settings. Attack and release act on a separate gain after the modulation. The LFO oscillator continues silently between swells after the first Start.

The rate slider covers 0.05–20 Hz on a logarithmic scale. The 0.1 Hz and 6 Hz buttons set those exact frequencies. At 0.1 Hz, one cycle is ten seconds. Changing rate preserves phase. The moving dot and value readouts use audio-context time; the filter graph follows the moving frequency. This is a control display, not a sampled waveform or output loudness meter. The envelope has its own existing display.

Checks completed:

- `node --check app.js` passed.
- All 44 literal JavaScript ID references exist in the HTML.
- No external library, font, network request or service is required.
- The first complete source copy is in `attempts/001/`.

Browser interaction, sound output and listening checks are left to the parent task, as requested. I have not claimed audible loudness matching, hardware-independent levels or browser-tested behaviour. The inherited generated noise loops repeat after six seconds. The LFO runs independently and can take longer than the loop to complete a cycle.
