Tupi
Tupi

Reputation: 258

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!

Upvotes: 1

Views: 579

Answers (2)

user22205632
user22205632

Reputation: 1

The answer by chrisguttandin does not fully work. The problem is that if you only allowed one side to oscillate, you still hear it in both speakers. The process does not give a true stereo affect.

Upvotes: 0

chrisguttandin
chrisguttandin

Reputation: 9076

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);

Upvotes: 2

Related Questions