DEV Community

wimdenherder
wimdenherder

Posted on

Creating Freddie Mercury's voice with javascript

PS: Listen to the result here: https://freddievoicejavascript.web.app/

I've always been fascinated with Freddie Mercury's voice (leadsinger of Queen). Especially, there is a moment in 'Who wants to live forever' on the high B note, where his voice has a golden glitter over it.

If you click here, it starts at the high B note!

Queen - Who Wants To Live Forever (Official Video) - YouTube

Taken from A Kind Of Magic, 1986.Click here to buy the DVD with this video at the Official Queen Store:http://www.queenonlinestore.comThe official 'Who Wants...

favicon youtube.com

Analysing this note with spectrogram reveals that it's due to the overtones why this particular note has such a heavenly sound. Where you associate heaven with up in the skies, you hear the high overtones as heavenly sounds.

Image description

Analysing this musical note through the lens of a spectrogram unveils a fascinating insight: the sublime, ethereal quality of this note stems from its overtones. The association of heaven with celestial heights echoes in the auditory experience of the high overtones, translating into what can be described as aural divinity.

Image description

I analysed the frequencies and came to this array of [frequency, volume]

let freddie = [[500,1],[1000, 40], [1500, 5], [2000, 10],[2500,10],[3000,15],[3500,10],[4000,5]]
Enter fullscreen mode Exit fullscreen mode

Pay attention to the ratio's here.

First we have 500 Herz, this has a very weak volume of 1%. Let me explain this rare oddity. Freddie's voice actually makes the ventricular folds vibrate along with the vocal folds one octave lower (!!). The ventricular folds This is a technique only known in throat singing, but really a rarity for pop/rock singers.

What they discovered was that he likely employed subharmonics, a singing style where the ventricular folds vibrate along with the vocal folds. Most humans never speak or sing with their ventricular folds unless they’re Tuvan throat singers, so the fact that this popular rock vocalist was probably dealing with subharmonics is pretty incredible.

Then we have 1000 Herz. This is the high B note, that you actually hear, the real note. The rest are overtones that give rise to the sound pallet, that golden shine over his voice.

What is remarkable is that the 3000 Herz is a very strong overtone. This is the ratio 3:2 to the octave 2000 herz. In music harmony it's called the fifth. This is what gives the voice the golden glitter! And it's 37,5% (15/40) of the original volume of the basic tone, and that property of Freddie's voice is really special. It makes his voice the unique voice in the world. Especially considering that it's also in the high range.

Then I added another typical feature of Freddie's voice. His pretty fast vibrato at 7 Herz. I added also some random aberrations to the vibrato to make it sound more human.
Here is the script that you can just run in your browser (for example in the javascript console):

// this imitates the spectrogram of freddie mercury's voice in who wants to live forever

async function playFrequencies(baseFrequency, duration, frequencyVolumeArray, vibratoDepthPercent = 2, vibratoSpeed = 7, maxRandomness = 0.2) {
  // Create AudioContext
  let audioCtx = new (window.AudioContext || window.webkitAudioContext)();

  let pitchRatio = baseFrequency / frequencyVolumeArray[0][0];
  console.log('pitchRatio', pitchRatio)

  // Create a list of promises
  let promises = frequencyVolumeArray.map((freqVol) => {
      // Extract the frequency and volume
      let frequency = freqVol[0];
      let volume = freqVol[1] / 100; // Convert percentage to decimal

      // Create oscillator for the frequency
      let oscillator = audioCtx.createOscillator();
      oscillator.frequency.value = pitchRatio * frequency; // Set base frequency

      // Create a GainNode to control the volume
      let gainNode = audioCtx.createGain();
      gainNode.gain.value = volume;

      // Create vibrato oscillator and gain
      let vibrato = audioCtx.createOscillator();
      let vGain = audioCtx.createGain();

      // Connect the vibrato to the main oscillator frequency
      vibrato.connect(vGain);
      vGain.connect(oscillator.frequency);

      // Connect the oscillator to the gain node
      oscillator.connect(gainNode);

      // Connect the gain node to the output destination
      gainNode.connect(audioCtx.destination);

      // Function to update vibrato parameters
      const updateVibrato = () => {
          let randomDepthVariation = (Math.random() * 2 - 1) * maxRandomness; // -5% to +5%
          let randomSpeedVariation = (Math.random() * 2 - 1) * maxRandomness; // -5% to +5%
          let adjustedVibratoDepth = vibratoDepthPercent * (1 + randomDepthVariation);
          let adjustedVibratoSpeed = vibratoSpeed * (1 + randomSpeedVariation);
          vibrato.frequency.value = adjustedVibratoSpeed; // Vibrato frequency
          vGain.gain.value = frequency * (adjustedVibratoDepth / 100); // Vibrato depth
      };

      // Start the oscillator and vibrato
      oscillator.start();
      vibrato.start();

      // Update vibrato parameters every 0.5 seconds
      let vibratoInterval = setInterval(updateVibrato, 500);

      // Return a promise that resolves after the sound finishes
      return new Promise((resolve) => {
          setTimeout(function() {
              clearInterval(vibratoInterval);
              resolve();
          }, duration * 1000);
      });
  });

  // Wait for all sounds to finish
  await Promise.all(promises);

  // Close the AudioContext
  audioCtx.close();
}

let freddie = [[500,1],[1000, 40], [1500, 5], [2000, 10],[2500,10],[3000,15],[3500,10],[4000,5]]

// Play frequencies with their respective volumes, with vibrato depth of 2% and speed of 7 Hz
await playFrequencies(500, 1, freddie, 2, 7, 0.2);
Enter fullscreen mode Exit fullscreen mode

You can just copy this javascript in the browser (javascript console) or run it in the tag on a page. You&#39;ll hear the heavenly sounds :-D</p>

Top comments (0)