Bach Raised to Twelve
Overview
The Sounds element generates buttons that play musical notes at specified frequencies using the Web Audio API. It’s useful for demonstrating concepts in acoustics, music theory, or physics of sound.
Implementation Details
Audio Generation
The element uses the Web Audio API to synthesize tones programmatically:
- Creates an oscillator with sine wave type
- Applies gain node for volume control
- Implements ADSR envelope (attack, decay, sustain, release)
// Example element config: array of [label, frequency] pairs
::: js Sounds
["C", 261.63], ["F", 348.84], ["G", 392.44], ["C", 523.25]
sounds1
autoPlay, noControls, h=fit
:::
Envelope Shaping
The sound uses a volume envelope to prevent clicks:
- Attack: 0.25s ramp from 0 to max volume (0.25)
- Sustain: 0.5s at max volume
- Release: 0.25s ramp back to 0
This creates a natural-sounding tone that fades in and out smoothly.
UI Design
Each button displays a musical note icon (SVG) alongside the note label. Buttons use flexbox wrapping to arrange themselves automatically based on container width, making the element responsive to different screen sizes.
The buttons use themed colors that adapt to light/dark modes, with hover effects for interactive feedback.
Technical Considerations
The element creates a new AudioContext for each button press rather than maintaining a persistent context. This simplifies resource management but means the element doesn’t support polyphonic playback (multiple simultaneous notes).
The oscillator is automatically cleaned up after the release phase completes, preventing memory leaks from abandoned audio nodes. The timing is calculated to ensure the oscillator stops exactly when the envelope reaches zero.