【问题标题】:Overlay two audio buffers into one buffer source将两个音频缓冲区叠加到一个缓冲区源中
【发布时间】:2014-04-03 19:26:33
【问题描述】:

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

  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);  
}

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

解释和/或 sn-ps 会很棒。

【问题讨论】:

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


    【解决方案1】:

    @Padenot 是对的,但他的代码中有一些错字,所以如果你复制/粘贴它,它就无法工作。您可以在下面找到带有更正的相同代码,以便您使用它。感谢您的帮助@Padenot ;)

    function mix(buffers) {
    
        var nbBuffer = buffers.length;// Get the number of buffer contained in the array buffers
        var maxChannels = 0;// Get the maximum number of channels accros all buffers
        var maxDuration = 0;// Get the maximum length
    
        for (var i = 0; i < nbBuffer; i++) {
            if (buffers[i].numberOfChannels > maxChannels) {
                maxChannels = buffers[i].numberOfChannels;
            }
            if (buffers[i].duration > maxDuration) {
                maxDuration = buffers[i].duration;
            }
        }
    
        // Get the output buffer (which is an array of datas) with the right number of channels and size/duration
        var mixed = context.createBuffer(maxChannels, context.sampleRate * maxDuration, context.sampleRate);        
    
        for (var j=0; j<nbBuffer; j++){
    
            // For each channel contained in a buffer...
            for (var srcChannel = 0; srcChannel < buffers[j].numberOfChannels; srcChannel++) {
    
                var _out = mixed.getChannelData(srcChannel);// Get the channel we will mix into
                var _in = buffers[j].getChannelData(srcChannel);// Get the channel we want to mix in
    
                for (var i = 0; i < _in.length; i++) {
                    _out[i] += _in[i];// Calculate the new value for each index of the buffer array
                }
            }
        }
    
        return mixed;
    }
    

    【讨论】:

      【解决方案2】:

      在音频中,要将两个音频流(这里是缓冲区)混合合为一个,您可以简单地将每个样本值添加在一起。实际上,我们可以在您的 sn-p 基础上做到这一点:

      /* `buffers` is a javascript array containing all the buffers you want
       * to mix. */
      function mix(buffers) {
        /* 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 (var 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 out = mixed.getChanneData(srcChannel);
            /* Get the channel we want to mix in */
            var in = buffers[i].getChanneData(srcChannel);
            for (var i = 0; i < in.length; i++) {
              out[i] += in[i];
            }
          }
        }
        return out;
      }
      

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

      几点说明:为简单起见,我的 sn-p 假设:

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

      再一次,Web Audio API 为您完成了所有这些,所以我想知道为什么您需要自己做,但至少现在您知道如何做 :-)。

      【讨论】:

      • 如何将 2 个 mediaStream 混合在一起?
      • 已解决问题,对此感到抱歉。
      • @padenot 什么都没有修复。还有像mixedcontext 这样的未定义变量。另一个错误是循环变量i 在其上下文之外使用。下面还有另一个循环使用它自己的i 计数器,我对发生的事情一无所知。如果您提到启用此功能的方法,“Web Audio API 会为您完成所有这些”,这对我们也是有益的。
      猜你喜欢
      • 2014-11-14
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多