0

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!

Tupi
  • 218
  • 5
  • 13

2 Answers2

1

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);
chrisguttandin
  • 7,025
  • 15
  • 21
  • Hey! Really thanks for your answer! It's exactly what I was looking for. I have a question, what does the `leftGain.gain.value = 0.5;` do? Again, thanks! – Tupi May 17 '21 at 14:56
  • I'm happy it helps. I added two `GainNodes`. One for each channel to level the signal for each channel independently. `0.5` is just an arbitrary number. – chrisguttandin May 17 '21 at 16:10
  • Alright, thanks! That's all what I need. ^^ – Tupi May 17 '21 at 16:19
0

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.

  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34669290) – Vallie Jul 13 '23 at 11:36