Search code examples
frequencyweb-audio-apijavascript-oscillator

How does oscillator.detune() work in Web Audio API?


I have read that 1200 cents are in 1 octave.

So, I tried the following:

const audioContext = new AudioContext();

function Oscillator(frequency, detune) {
    this.oscillator = audioContext.createOscillator();
    this.oscillator.connect(audioContext.destination);

    this.oscillator.frequency.value = frequency;
    this.oscillator.detune.value = detune;

    this.oscillator.start(0);
    this.oscillator.stop(3);
    console.log('Playing new oscillator!');
}

Case 1:

const x = 200;
new Oscillator(x, 1200);
new Oscillator(2 * x, 0);

Both the oscillators individually produce the same sound for all values of x and it made sense to me because 1200 cents detune is one octave up (double of the frequency).

Case 2:

const x = 200;
new Oscillator(x, 600);
new Oscillator(x * 1.5, 0);

So, I expected that if I got halfway in terms of cents, then there should be a 50% hike in frequency. But, when I heard them individually, for many different values of x they all produced a different sound. It sounded like both sounds have the same frequency but different amplitude.

I am not able to understand why this is happening. Please help me out with this. I am quite new to physics behind sounds.


Solution

  • The formula to convert the value of the detune param into Hz is Math.pow(2, detune / 1200).

    https://webaudio.github.io/web-audio-api/#oscillatornode

    That means your second example should be either ...

    const x = 200;
    
    new Oscillator(x, 701.95);
    new Oscillator(x * 1.5, 0);
    

    ... or ...

    const x = 200;
    
    new Oscillator(x, 600);
    new Oscillator(x * 1.414, 0);