我已经在网络应用中为动态声音创建了标准播放器,如下所示:
var _dynamicAudio:Vector.<Number> = new Vector.<Number>();
var _sampleIndex:uint = 0;
// ..Code to generate '_dynamicAudio' samples omitted
var _sound:Sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleDataEvent);
_sound.play();
function onSampleDataEvent(event:SampleDataEvent):void {
var samplesRead:int = 0;
while (samplesRead <= 8192 && _sampleIndex < _dynamicAudio.length) {
var sample:Number = _dynamicAudio[_sampleIndex];
event.data.writeFloat(sample);
event.data.writeFloat(sample);
_sampleIndex++;
_samplesRead++;
}
}
然而,在较慢的计算机上(或者如果我通过打开其他应用程序来强调我自己),音频偶尔会“乱码”。听起来它在最近的一个样本块上被卡住了。当发生这种情况时,我注意到event.position
跳过8192的某个倍数,这似乎也暗示onSampleDataEvent
没有被调用几个连续的样本块。如果这是真的,那么这个问题似乎是不可避免的。我想知道的是,如果有任何方法可以在它发生之前检测到它,我可以暂停音频代替可怕的噪音吗?谢谢!
答案 0 :(得分:0)
可能是while()循环很重,并且你并不总是有内存/ CPU能力来处理它。所以它会冻结并为你提供你所描述的效果。
有可能将循环分解为更小的循环,从而平衡CPU负载。同时处理足够远的事件以无缝播放音频。
以下代码未经过测试,只是分解循环的示例:
var _dynamicAudio:Vector.<Number> = new Vector.<Number>();
var _sampleIndex:uint = 0;
// ..Code to generate '_dynamicAudio' samples omitted
var _sound:Sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleDataEvent);
_sound.play();
function onSampleDataEvent(event:SampleDataEvent):void {
var samplesRead:int = 0;
writeSamples(0, event);
}
function writeSamples(counter:int, eventReference:SampleDataEvent):void
{
var startTime:int = getTimer();
while (samplesRead <= (8192 - counter) && _sampleIndex < _dynamicAudio.length)
{
// check if the processing takes too long
if (getTimer() - startTime > 5)
{
writeSamples(counter, eventReference);
break;
}
counter++;
var sample:Number = _dynamicAudio[_sampleIndex];
event.data.writeFloat(sample);
event.data.writeFloat(sample);
_sampleIndex++;
_samplesRead++;
}
}
预览代码的主要思想是:
1)检查while循环是否执行时间过长。在我的例子中,5ms是限制 2)如果执行太长则断开循环并从停止的位置再次开始循环。
如果整个过程花费的时间少于限制,那么循环将一次完成。
您可能希望重构代码,因为它未经过优化,并且会产生大量垃圾而不是重用对象。