在播放整个声音时,很少有答案将两个音轨与sampleDataEvent侦听器混合在一起。有没有办法尽可能快地混合曲目? (轨道持续时间相同,采用ByteArray的形式)
在下面的帖子中
Programatically Mixdown of audio tracks (no playback)
作者建议使用Event.EnterFrame。但是,我对AS3的API并不熟悉。谁能提供一些示例代码?谢谢!
答案 0 :(得分:0)
如果您不需要以二进制格式输出混音,只需双击即可。
track1.play();
track2.play();
是的,当您的曲目在ByteArrays中时,首先制作两个Sound
对象,然后通过loadPCMDataFromByteArray()
从bytearrays中获取数据。
更新:由于您根本不想播放,混合两个曲目的最简单方法是从每个ByteArray中读取一个浮点数,然后将它们的平均值写入生成的ByteArray。如果您不希望在进行转换时让SWF停顿,那么使用ENTER_FRAME
听众是值得的。您已经说过您的阵列长度相等,如果是这样,以下代码片段应该执行您的"简单混合"那些wavs:
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
在侦听器调用和未改变位置之间可用,并且在循环中运行临时计数器,这将控制在此帧中的足够转换&#34;。像这样:
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值。