3

I'm currently trying to create an audio visualisation using an web audio api, namely I'm attempting to produce lissajou figures from a given audio source.

I came across this post, but I'm missing some preconditions. How can I get the time domain data for the left / right channels? Currently it seems I'm only getting the merged data.

Any help or hint would be much appreciated.

$(document).ready(function () {

  var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  var audioElement = document.getElementById('audioElement');
  var audioSrc = audioCtx.createMediaElementSource(audioElement);
  var analyser = audioCtx.createAnalyser();

  // Bind analyser to media element source.
  audioSrc.connect(analyser);
  audioSrc.connect(audioCtx.destination);

  //var timeDomainData = new Uint8Array(analyser.frequencyBinCount);
  var timeDomainData = new Uint8Array(200);

  // loop and update time domain data array.
  function renderChart() {
     requestAnimationFrame(renderChart);

     // Copy frequency data to timeDomainData array.
     analyser.getByteTimeDomainData(timeDomainData);

     // debugging: print to console
     console.log(timeDomainData);

  }

  // Run the loop
  renderChart();

});

2 Answers 2

1

The observation is correct, the waveform is the down-mixed result. From the current spec (my emphasis):

Copies the current down-mixed time-domain (waveform) data into the passed unsigned byte array. [...]

To get around this you could use a channel splitter (createChannelSplitter()) and assign each channel to two separate analyzer nodes.

For more details on createChannelSplitter() see this link.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply, the provided links and the hint to a solution, those answers my question indeed.
0

We can achieve that by using the StereoPannerNode pan option:

A floating point number in the range [-1,1] indicating the position of an AudioNode in an output image. The value -1 represents full left and 1 represents full right. The default value is 0.


Web-radio with 2 channels stereo VU Meters

On the following demo, the BBC world radio get split into two left and right channels. Those channels are then routed into their own analyzers, who feeds the value for the progress bars. The looping is done using animation frames and timers.

const ctx = new AudioContext();
const audioSrc = ctx.createMediaElementSource(player);
const analyserL = ctx.createAnalyser();
const analyserR = ctx.createAnalyser();
let job, origin = new Date().getTime();
const L = new StereoPannerNode(ctx, {pan: -1});
const R = new StereoPannerNode(ctx, {pan: 1});

audioSrc.connect(analyserL);
audioSrc.connect(analyserR);
audioSrc.connect(ctx.destination);

analyserL.fftSize = 32;
const bufferLengthL = analyserL.frequencyBinCount;
const frequencyDataL = new Float32Array(bufferLengthL);

analyserR.fftSize = 32;
const bufferLengthR = analyserR.frequencyBinCount;
const frequencyDataR = new Float32Array(bufferLengthR);

let i = 0;
const timer = () => {
  if (new Date().getTime() - i > origin){
   analyserL.getFloatFrequencyData(frequencyDataL);
   analyserR.getFloatFrequencyData(frequencyDataR);
   let vL = 100 - (Object. values(frequencyDataL).reduce((a,b) => a + b, 0) * -0.03)
   let vR = 100 - (Object. values(frequencyDataR).reduce((a,b) => a + b, 0) * -0.03)
   VUL.value = ~~vL
   VUR.value = ~~vR
   i = i + 41 // 24 FPS
   job = requestAnimationFrame(timer)
  } else if (job !== null){
      requestAnimationFrame(timer)
  }
}

/* Start looping ------------------------*/
requestAnimationFrame(timer)
<audio id="player" controls crossorigin="anonymous" autoplay src="https://stream.live.vc.bbcmedia.co.uk/bbc_world_service"></audio>
<br>
L <progress id="VUL" max="100" value="0"></progress>
<br>
R <progress id="VUR" max="100" value="0"></progress>

https://developer.mozilla.org/en-US/docs/Web/API/StereoPannerNode/StereoPannerNode

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.