【问题标题】:web audio analyze entire buffer网络音频分析整个缓冲区
【发布时间】:2017-10-07 15:38:28
【问题描述】:

我的应用程序中有预先录制的音频文件的音频缓冲区。 我正在尝试获取整个音轨的频域数据,这是我尝试过的:

getAudioDataFromBuffer: function(buf){
    var src = g.audioContext.createBufferSource();
    src.buffer = buf;
    var anal = src.context.createAnalyser();
    src.connect(anal);
    var dataArray = new Uint8Array(buf.length);
    anal.fftSize = 2048;
    anal.getByteFrequencyData(dataArray);
    return dataArray;
},

但这只会给我一个充满零的数组。

我需要这个来比较两个音轨,一个是预先录制的,另一个是在应用程序中录制的。我想我可以测量它们的频域之间的相关性。

【问题讨论】:

  • 请注意:不要缩短“分析”:D
  • 如何从通道数据中获取频域数据?我尝试直接测量通道数据之间的相关性,但我不喜欢结果。 @凯多
  • 我觉得很有趣....

标签: javascript signal-processing web-audio-api


【解决方案1】:

看到this answerthis discussion,我找到了解决方案。

基本上你需要使用 OfflineAudioContext。这里的代码从已经加载的音频缓冲区开始:

var offline = new OfflineAudioContext(2, buffer.length ,44100);
var bufferSource = offline.createBufferSource();
bufferSource.buffer = buffer;

var analyser = offline.createAnalyser();
var scp = offline.createScriptProcessor(256, 0, 1);

bufferSource.connect(analyser);
scp.connect(offline.destination); // this is necessary for the script processor to start

var freqData = new Uint8Array(analyser.frequencyBinCount);
scp.onaudioprocess = function(){
  analyser.getByteFrequencyData(freqData);
  console.log(freqData);
};

bufferSource.start(0);
offline.oncomplete = function(e){
  console.log('analysed');
};
offline.startRendering();

【讨论】:

【解决方案2】:

这是一个使用最新版本 Web Audio API 的工作示例:

注意:您需要以 audioBuffer 开头。您可以使用新的 File System Access API 获得一个:

const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const arrayBuffer = await file.arrayBuffer();
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);

获得audioBuffer 后,您可以使用offlineAudioContext 访问其内容:

const offlineAudioContext = new OfflineAudioContext(
    audioBuffer.numberOfChannels,
    audioBuffer.length,
    audioBuffer.sampleRate
  );
    
const bufferSourceNode = offlineAudioContext.createBufferSource();

bufferSourceNode.start(0);

offlineAudioContext
  .startRendering()
  .then(renderedBuffer => {

    const data = renderedBuffer.getChannelData(0);

    for (let i = 0, length = data.length; i < length; i += 1) {

      // careful here, as you can hang the browser by logging this data
      // because 1 second of audio contains 22k ~ 96k samples!
      if (!(i % 1000) && i < 250000) console.log(data[i]);
    }
  }

【讨论】:

    【解决方案3】:

    我认为你需要更多类似的东西

    AudioBuffer.getChannelData()

    返回一个 Float32Array,其中包含与通道关联的 PCM 数据,由通道参数定义(0 表示第一个通道)。

    查阅 Mozilla 或 W3C 文档。

    干杯

    基连

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      • 2014-04-28
      • 2022-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多