Skip to content

Writing

3 min read

Building an Interactive Circle of Fifths: Music Theory Meets Web Audio

I built an interactive Circle of Fifths that plays what it shows. Web Audio synthesis turns a centuries-old theory diagram into something you can hear.

The Circle of Fifths packs a surprising amount of music theory into a simple circular diagram, encoding the harmonic relationships between all twelve keys. I wanted a version you could actually hear, so I built an interactive one that plays audio when you click. That turns a centuries-old teaching tool into something you learn by ear as much as by eye.

The Circle of Fifths: Encoding Harmonic Space

For those unfamiliar with music theory, the Circle of Fifths arranges all twelve musical keys in a circular pattern where each adjacent key differs by a perfect fifth interval. Moving clockwise adds sharps; moving counter-clockwise adds flats. This arrangement reveals fundamental relationships that govern Western harmony.

The circle shows several things at once:

  • Key Signatures: The number of sharps or flats in each key
  • Relative Majors and Minors: Major and minor keys that share the same key signature
  • Chord Progressions: Common harmonic movements map to geometric patterns on the circle
  • Modulation Paths: Adjacent keys provide the smoothest key changes

Web Audio API: Bringing Theory to Life

The Web Audio API generates musical tones directly in the browser. Unlike pre-recorded samples, synthesized audio can respond dynamically to what the user does:

const audioContext = new AudioContext();

function playNote(frequency, duration = 0.5) {
  const oscillator = audioContext.createOscillator();
  const gainNode = audioContext.createGain();
  
  oscillator.connect(gainNode);
  gainNode.connect(audioContext.destination);
  
  oscillator.frequency.value = frequency;
  oscillator.type = 'sine';
  
  gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
  gainNode.gain.exponentialRampToValueAtTime(
    0.01, audioContext.currentTime + duration
  );
  
  oscillator.start(audioContext.currentTime);
  oscillator.stop(audioContext.currentTime + duration);
}

Now clicking a key gives immediate audio feedback, so you hear the tonic, dominant, and subdominant relationships that define tonal harmony.

A visualization of the audio signal path (Oscillator -> Gain -> Destination) discussed in the Web Audio API section.

Frequency Calculations and Equal Temperament

Converting musical notes to frequencies requires understanding equal temperament tuning, where each semitone represents a frequency ratio of the twelfth root of two:

const A4_FREQUENCY = 440; // Hz
const SEMITONE_RATIO = Math.pow(2, 1/12);

function noteToFrequency(note, octave) {
  const noteIndex = ['C', 'C#', 'D', 'D#', 'E', 'F', 
                     'F#', 'G', 'G#', 'A', 'A#', 'B'].indexOf(note);
  const semitonesFromA4 = (octave - 4) * 12 + (noteIndex - 9);
  return A4_FREQUENCY * Math.pow(SEMITONE_RATIO, semitonesFromA4);
}

That math keeps the pitches accurate across the whole circle, from C major through all twelve keys.

A diagram illustrating the geometric calculations required to position keys on the circle, bridging the math section and the design section.

Interactive Visualization Design

The circular layout requires careful geometric calculations to position elements correctly:

function getKeyPosition(index, radius) {
  const angle = (index * 30 - 90) * (Math.PI / 180);
  return {
    x: radius * Math.cos(angle),
    y: radius * Math.sin(angle)
  };
}

Each key occupies 30 degrees of the circle (360/12), with the -90 degree offset placing C major at the top. The inner ring displays relative minors, maintaining the same angular relationship while using a smaller radius.

Educational Features

The app also does some teaching:

  • Scale Display: Clicking a key shows all notes in that major or minor scale
  • Chord Highlighting: Visualize which chords naturally occur in each key
  • Progression Patterns: Highlight common chord progressions like I-IV-V-I
  • Audio Playback: Hear scales and chords to connect visual patterns with sound

Responsive Design Considerations

Musical apps have their own responsive-design problems. Touch targets have to work for both precise mouse clicks and finger taps, and the circular layout has to stay legible across screen sizes:

.circle-key {
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.circle-key:hover,
.circle-key:focus {
  transform: scale(1.1);
}

@media (max-width: 600px) {
  .circle-container {
    transform: scale(0.8);
    transform-origin: center top;
  }
}

Performance Optimization

Audio applications require careful performance management to prevent clicks and latency:

// Pre-warm the audio context on first user interaction
document.addEventListener('click', () => {
  if (audioContext.state === 'suspended') {
    audioContext.resume();
  }
}, { once: true });

Modern browsers suspend the audio context to block autoplay, so this pattern wakes it up on the first click and keeps audio responsive after that.

Extending the Foundation

The same patterns carry over to other music education tools:

  • Interval Training: Recognizing the sound of fifths, fourths, and other intervals
  • Chord Quality Recognition: Distinguishing major, minor, diminished, and augmented chords
  • Sight-Reading Assistance: Connecting key signatures to scale patterns

Seeing the theory and hearing it at the same time sticks better than either one on its own.


Try the interactive Circle of Fifths at cameronrye.github.io/circle-of-fifths or explore the source code on GitHub.

Subscribe

Was this helpful?

Discuss

Ask can help explain concepts, provide context, or point you to related content.