如何将声音效果附加到AudioBuffer

时间:2017-10-12 15:49:47

标签: javascript audio html5-audio web-audio

我正在尝试将以下声音效果添加到某些音频文件中,然后获取其音频缓冲区并转换为.mp3格式

  • 淡出第一首曲目
  • 淡入以下曲目
    • 背景音轨(并通过为其提供小增益节点使其成为背景)
    • 另一首将成为两个合并曲目的声音的曲目
  • 淡出前一个并再次淡入第一首曲目

我观察到AudioParam类返回的效果以及来自GainNode接口的效果都附加到上下文的目标而不是缓冲区本身。是否有一种技术可以将AudioParam实例值(或增益属性)支持到缓冲区,因此当我将它们合并到一个终极缓冲区时,它们仍然可以保留这些效果?或者这些效果只对目标有意义(意味着我必须在sourceNode上connect)并通过OfflineContexts / startRendering输出它们?我之前尝试过这种方法,并且在我的最后一个线程上被告知我只需要一个BaseAudioContext而且它不必是一个OfflineContext。我认为对各种文件有各种影响,我需要几个上下文,因此我陷入各种AudioParams和GainNodes的困境,但通过调用start直接隐式调用它们会无意中失去它们的效力。

以下代码段演示了我所指的效果,而完整代码可在https://jsfiddle.net/ka830Lqq/3/找到

var beginNodeGain = overallContext.createGain(); // Create a gain node


        beginNodeGain.gain.setValueAtTime(1.0, buffer.duration - 3); // make the volume high 3 secs before the end

        beginNodeGain.gain.exponentialRampToValueAtTime(0.01, buffer.duration); // reduce the volume to the minimum for the duration of expRampTime - setValTime i.e 3

        // connect the AudioBufferSourceNode to the gainNode and the gainNode to the destination
        begin.connect(beginNodeGain); 

因此,另一个片段

function handleBg (bgBuff) {

            var bgContext = new OfflineAudioContext(bgBuff.numberOfChannels, finalBuff[0].length, bgBuff.sampleRate), // using a new context here so we can utilize its individual gains

            bgAudBuff = bgContext.createBuffer(bgBuff.numberOfChannels, finalBuff[0].length, bgBuff.sampleRate),

            bgGainNode = bgContext.createGain(),

            smoothTrans =  new Float32Array(3);


            smoothTrans[0] = overallContext.currentTime; // should be 0, to usher it in but is actually between 5 and 6

            smoothTrans[1] = 1.0;

            smoothTrans[2] = 0.4; // make it flow in the background

            bgGainNode.gain.setValueAtTime(0, 0); //currentTime here is 6.something-something

            bgGainNode.gain.setValueCurveAtTime(smoothTrans, 0, finalBuff.pop().duration); // start at `param 2` and last for `param 3` seconds. bgBuff.duration



            for (var channel = 0; channel < bgBuff.numberOfChannels; channel++) {

                 for (var j = 0; j < finalBuff[0].length; j++) {

                    var data = bgBuff.getChannelData(channel),

                    loopBuff = bgAudBuff.getChannelData(channel),

                    oldBuff = data[j] != void(0) ? data[j] : data[j - data.length];

                    loopBuff[j] = oldBuff;
                }
            }

            // instead of piping them to the output speakers, merge them

            mixArr.push(bgAudBuff);

            gottenBgBuff.then(handleBody());
        } 

0 个答案:

没有答案