Web Audio API,获取两个数组中左/右声道的 getByteTimeDomainData。

问题描述 投票:0回答:2

我目前正在尝试使用网络音频 API 创建音频可视化,即我正在尝试从给定的音频源生成利萨茹图形。

我看到了这篇post,但我缺少一些先决条件。如何获取左/右通道的时域数据?目前看来我只获取合并的数据。

任何帮助或提示将不胜感激。

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

});
javascript audio web-audio-api
2个回答
1
投票

观察正确,波形为下混频结果。从当前规格(我的重点):

将当前下混合时域(波形)数据复制到 传递无符号字节数组。 [...]

为了解决这个问题,您可以使用通道分配器 (

createChannelSplitter()
) 并将每个通道分配给两个单独的分析器节点。

有关

createChannelSplitter()
的更多详细信息,请参阅此链接


0
投票

我们可以通过使用

StereoPannerNode
pan
选项来实现这一点:

[-1,1]范围内的浮点数,表示 输出图像中的 AudioNode。值 -1 代表完全左移, 1代表全权。默认值为 0。

立体声VU表

在下面的演示中,BBC 世界广播电台被分成左右两个频道。然后,这些通道被路由到它们自己的分析器中,分析器为进度条提供值。循环是使用动画帧和计时器完成的。

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 = Object. values(frequencyDataL).reduce((a,b) => a + b, 0)*-0.05
   let vR = Object. values(frequencyDataR).reduce((a,b) => a + b, 0)*-0.05
   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

© www.soinside.com 2019 - 2024. All rights reserved.