JSFiddle - React, Tailwind, and code Playground

Babel + JSX

let audioCtx = new AudioContext();

class HarmonicSynth {

  /**
   * Given an array of overtone amplitudes, construct an additive
   * synth for that overtone structure
   */
  constructor(partialAmplitudes) {
    this.partials = partialAmplitudes
      .map(() => audioCtx.createOscillator());
    this.partialGains = partialAmplitudes
      .map(() => audioCtx.createGain());
    this.masterGain = audioCtx.createGain();
    
    partialAmplitudes.forEach((amp, index) => {
      this.partialGains[index].gain.value = amp;
      this.partials[index].connect(this.partialGains[index]);
      this.partialGains[index].connect(this.masterGain);
    });
    this.masterGain.gain.value = 0.3;

  }
  
  connect(dest) {
    this.masterGain.connect(dest);
  }
  
  disconnect() {
    this.masterGain.disconnect();
  }
  
  start(time = 0) {
    this.partials.forEach(o => o.start(time));
  }
  
  stop(time = 0) {
    this.partials.forEach(o => o.stop(time));
  }
  
  setFrequencyAtTime(frequency, time) {
    this.partials.forEach((o, index) => {
      o.frequency.setValueAtTime(frequency * (index + 1), time);
    });
  }
  
  exponentialRampToFrequencyAtTime(frequency, time) {
    this.partials.forEach((o, index) => {
      o.frequency.exponentialRampToValueAtTime(frequency * (index + 1), time);
    });
  }
}

 
const G4 = 440 * Math.pow(2, -2/12);
const A4 = 440;
const F4 = 440 * Math.pow(2, -4/12);
const F3 = 440 * Math.pow(2, -16/12);
const C4 = 440 * Math.pow(2, -9/12);

let synth = new HarmonicSynth([1, 0.1, 0.2, 0.5]);

let t = audioCtx.currentTime;
synth.setFrequencyAtTime(G4, t);
synth.setFrequencyAtTime(G4, t + 0.95);
synth.exponentialRampToFrequencyAtTime(A4, t + 1);
synth.setFrequencyAtTime(A4, t + 1.95);
synth.exponentialRampToFrequencyAtTime(F4, t + 2);
synth.setFrequencyAtTime(F4, t + 2.95);
synth.exponentialRampToFrequencyAtTime(F3, t + 3);
synth.setFrequencyAtTime(F3, t + 3.95);
synth.exponentialRampToFrequencyAtTime(C4, t +...