javascripthtmlfrequencyaudiocontext

How to make a frequency sound stereo in JavaScript


I have some troubles while trying to reproduce different frequencies using two different audio channels (left and right) in JavaScript. I've been searching in StackOverflow and Internet for a while, but I didn't find anything that could help me, so I decided to ask here for help.

Let me explain first why I'm doing this. There's a lot of people in the world that have tinnitus (an "illness" where you hear a specific frequency in an ear or in both). Sometimes, people sat that tinnitus is not a big trouble. The website is gonna allow the users to know how a "tinnitus person" hear. For accomplishing that, the audio must be different in both ears, so I need to send different frequencies in two different channel audio.

This is the code I already have, it reproduces a specific frequency in mono (full app here: replit.com/Tupiet/hearing):

function letsStart() {
  try{
    window.AudioContext = window.AudioContext || window.webKitAudioContext;
    context = new AudioContext();
  }
  catch(e) {
    alert("API isn't working");
  }
}

function initFrequency() {
  let range = document.getElementById('range').value;
  osc = context.createOscillator();
  osc.frequency.value = range;
  osc.connect(context.destination);
  osc
  osc.start(0);

  document.querySelector(".show-frequency").innerHTML = range + "Hz";
}

The code above is playing a specific frequency in mono mode, but as I expected, I need to play it in a specific channel audio.

By the way, the only question I found that I thought it could help me was this one, but I think it's not what I'm searching since it doesn't work with frequencies.

How can I do it? I couldn't an explanation anywhere. Really really thanks!


Solution

  • You can achieve the desired result by using a ChannelMergerNode. It can be used to piece together a stereo signal.

    Here is an example with two independent oscillators.

    const audioContext = new AudioContext();
    
    const leftOscillator = audioContext.createOscillator();
    const leftGain = audioContext.createGain();
    const rightOscillator = audioContext.createOscillator();
    const rightGain = audioContext.createGain();
    const merger = audioContext.createChannelMerger(2);
    
    leftOscillator.connect(leftGain).connect(merger, 0, 0);
    rightOscillator.connect(rightGain).connect(merger, 0, 1);
    
    merger.connect(audioContext.destination);
    
    leftOscillator.frequency.value = 800;
    leftGain.gain.value = 0.5;
    leftOscillator.start(0);
    
    rightOscillator.frequency.value = 1400;
    rightGain.gain.value = 0.8;
    rightOscillator.start(0);