javascript - 将两个音频缓冲区叠加到一个缓冲区源中

标签 javascript html audio html5-audio web-audio-api

试图将两个缓冲区合并为一个; 我已经能够从音频文件创建两个缓冲区并加载和播放它们。现在我需要将两个缓冲区合并为一个缓冲区。它们如何合并?

  context = new webkitAudioContext();
  bufferLoader = new BufferLoader(
    context,
    [
      'audio1.mp3',
      'audio2.mp3',
    ],
    finishedLoading
    );

  bufferLoader.load();

function finishedLoading(bufferList) {
  // Create the two buffer sources and play them both together.
  var source1 = context.createBufferSource();
  var source2 = context.createBufferSource();
  source1.buffer = bufferList[0];
  source2.buffer = bufferList[1];

  source1.connect(context.destination);
  source2.connect(context.destination);
  source1.start(0);
  source2.start(0);  
}

现在这些源分别加载,同时播放;但是如何将这两个源合并为一个缓冲区源呢?我不想附加它们,我想叠加/合并它们。

解释和/或片段会很棒。

最佳答案

在音频中,要两个音频流(此处为缓冲区)合二为一,您只需将每个样本值相加即可。实际上,我们可以根据您的代码段执行此操作:

/* `buffers` is a javascript array containing all the buffers you want
 * to mix.
 * `context` is an AudioContext or OfflineAudioContext */
function mix(buffers, context) {
  /* Get the maximum length and maximum number of channels accros all buffers, so we can
   * allocate an AudioBuffer of the right size. */
  var maxChannels = 0;
  var maxDuration = 0;
  for (let i = 0; i < buffers.length; i++) {
    if (buffers[i].numberOfChannels > maxChannels) {
      maxChannels = buffers[i].numberOfChannels;
    }
    if (buffers[i].duration > maxDuration) {
      maxDuration = buffers[i].duration;
    }
  }
  var out = context.createBuffer(
    maxChannels,
    context.sampleRate * maxDuration,
    context.sampleRate
  );

  for (var j = 0; j < buffers.length; j++) {
    for (
      var srcChannel = 0;
      srcChannel < buffers[j].numberOfChannels;
      srcChannel++
    ) {
      /* get the channel we will mix into */
      var output = out.getChanneData(srcChannel);
      /* Get the channel we want to mix in */
      var input = buffers[j].getChanneData(srcChannel);
      for (let i = 0; i < input.length; i++) {
        output[i] += input[i];
      }
    }
  }
  return out;
}

然后,简单地影响从这个函数返回到一个新的AudioBufferSourceNode.buffer,然后像往常一样播放它。

一些注意事项:为简单起见,我的代码片段假定:

  • 如果您有一个单声道缓冲器和一个立体声缓冲器,您将只能在混合缓冲器的左声道中听到单声道缓冲器。如果你想把它复制到左边和右边,你必须做的是称为up-mixing;
  • 如果您希望一个缓冲区比另一个缓冲区更安静或更响亮(例如,如果您移动调音台上的音量推子),只需将 toMix[i] 值乘以一个小于以下的数字即可1.0 使其更安静,大于 1.0 使其更响亮。

话又说回来,Web Audio API 为您做了所有这些,所以我想知道为什么您需要自己做,但至少现在您知道怎么做了:-)。

关于javascript - 将两个音频缓冲区叠加到一个缓冲区源中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22135056/

相关文章:

javascript - 根据它的值更改选定的单选按钮背景

php - 删除php中嵌套的html标签

python - 音频组的成员无法访问/dev/dsp 来播放声音

Android AudioManager getParameters 和 setParameters 函数

javascript - 获取多边形中每个点的纬度和经度 - Google Maps API v3

javascript - Ajax 循环调用

html - 文本不会留在 DIV 内

java - FreeTTS,Java,Linux: “LINE UNAVAILABLE: Format is …”的解决方法

javascript - 使用 React hooks 获取数据清理异步回调

javascript - 如何在asp.net中每3秒拉伸(stretch)和更改背景图像