在播放整个声音时,很少有将两个音轨与sampleDataEvent侦听器混合的答案。有什么办法可以尽快混合曲目? (磁迹的持续时间相同,并且为ByteArray的形式)
在下面的帖子中
Programatically Mixdown of audio tracks (no playback)
作者建议使用Event.EnterFrame。但是,我不太熟悉AS3的API。谁能提供示例代码?谢谢!

最佳答案

如果您不需要以二进制格式输出混音,只需进行两次播放即可。

track1.play();
track2.play();

是的,因为您的磁道位于ByteArrays中,所以首先创建两个Sound对象,然后通过loadPCMDataFromByteArray()从bytearray中获取数据。

更新:由于您根本不希望播放,因此混合两条音轨的最简单方法是从每个ByteArray中读取一个浮点数,然后将其平均值写入结果ByteArray中。如果不想在转换时让SWF停顿,那么使用ENTER_FRAME侦听器是值得的。您已经说过数组的长度相等,如果是这样,则下面的代码片段应该对这些波形进行“简单混合”:
var f1:Number;
var f2:Number;
b1.position=0;
b2.position=0;
var result:ByteArray=new ByteArray();
var l:int=b1.length; // cache property
var i:int=0;
while (i<l) {
    i=i+4; // size of float
    f1=b1.readFloat();
    f2=b2.readFloat();
    result.writeFloat(0.5*f1+0.5*f2);
}

执行Enterframe方法要求您的result在侦听器调用之间可用,并且位置保持不变,并在循环中运行一个临时计数器,该计数器将控制“在此帧中进行足够的转换”。像这样:
var result:ByteArray;
var tracks:Vector.<ByteArray>=[];
var mixFinished:Function; // a callback
function startMixing():void {
    // just make it start mixing
    for (var i:int=tracks.length;i>=0;i--) tracks[i].position=0;
    addEventListener(Event.ENTER_FRAME,doMixing);
    result=new ByteArray();
}
function doMixing(e:Event):void {
    if (tracks.length==0) {
        removeEventListener(Event.ENTER_FRAME,doMixing);
        return;
    } // sanity check
    var mixrate:Number=1.0/tracks.length;
    for (var i:int=0;i<2048;i++) { // adjust number accordingly
        var tm:int=0; // how many tracks mixed
        var f:int=0;
        for (var j:int=tracks.length-1;j>=0;j--) {
            if (tracks[j].position<tracks[j].length) {
                // this track isn't finished
                tm++;
                f+=tracks[j].readFloat();
            }
        }
        if (tm==0) { // all tracks reached end, stop mixing
            removeEventListener(Event.ENTER_FRAME,doMixing);
            if (mixFinished!=null) mixFinished(); // do a callback
            return;
        }
        result.writeFloat(f*mixrate);
    }
}

这样,您可以填充tracks,设置mixFinished并调用startMixing,然后等待直到mixFinished被调用为止,此时您的声音应该正确混合。如果您觉得混合过程应该更快,请适当增加代码中的2048值。

10-06 14:19
查看更多