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.

Technologies used

JavaScript