动态生成的音频Garbling

时间:2014-01-14 20:23:09

标签: actionscript-3 flash media-player

我已经在网络应用中为动态声音创建了标准播放器,如下所示:

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没有被调用几个连续的样本块。如果这是真的,那么这个问题似乎是不可避免的。我想知道的是,如果有任何方法可以在它发生之前检测到它,我可以暂停音频代替可怕的噪音吗?谢谢!

1 个答案:

答案 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)如果执行太长则断开循环并从停止的位置再次开始循环。

如果整个过程花费的时间少于限制,那么循环将一次完成。

您可能希望重构代码,因为它未经过优化,并且会产生大量垃圾而不是重用对象。