Flash AS3在循环中使用Sound.extract分析声音文件

Flash AS3在循环中使用Sound.extract分析声音文件,flash,actionscript-3,audio,bytearray,extract,Flash,Actionscript 3,Audio,Bytearray,Extract,从这个AS3代码中,我期望500行跟踪输出包含“2048”。但我得到的只是一些包含“2048”的行。其余的跟踪打印一个“0”,显示extract()方法没有返回任何数据 为什么会这样?我想用特定的步骤遍历声音文件,以在相应位置提取2048字节的声音。一次提取整个声音文件会使flashplayer冻结几秒钟,因此对我来说不是一个好的解决方案 只要长步长小于samplesInSound/2048,就可以发现这种行为。与2048行相比,越接近该值,打印的“0”行就越多 var sound:Sound

从这个AS3代码中,我期望500行跟踪输出包含“2048”。但我得到的只是一些包含“2048”的行。其余的跟踪打印一个“0”,显示extract()方法没有返回任何数据

为什么会这样?我想用特定的步骤遍历声音文件,以在相应位置提取2048字节的声音。一次提取整个声音文件会使flashplayer冻结几秒钟,因此对我来说不是一个好的解决方案

只要长步长小于samplesInSound/2048,就可以发现这种行为。与2048行相比,越接近该值,打印的“0”行就越多

var sound:Sound = new Sound();
sound.load(new URLRequest("soundfile.mp3"));
sound.addEventListener(Event.COMPLETE, soundLoaded);

function soundLoaded(e:Event){
    var samplesInSound:Number = sound.length*44.1;
    var steps:int = 500;
    var byteArray:ByteArray = new ByteArray();
    for(var i=0; i<samplesInSound; i += Math.floor(samplesInSound/steps)){
        var extracted = sound.extract(byteArray, 2048, i);
        trace(i + ": " + extracted);
    }
}
var声音:声音=新声音();
load(新的URL请求(“soundfile.mp3”);
sound.addEventListener(事件完成,声音加载);
功能已加载(e:事件){
var samplesInSound:Number=sound.length*44.1;
var步数:int=500;
var byteArray:byteArray=new byteArray();

对于(var i=0;i我没有足够的声誉来评论你的问题,因此我将在回答时附上免责声明,如果它不能解决你的问题,请告诉我

每次调用sound.extract都将从上一次调用sound.extract的地方提取,因此您不必每次都使用startPosition参数。这就是为什么您会得到奇怪的结果,对sound.extract的调用已经在声音中进行了:

sound.extract(byteArray, 2048) // advances 2048 samples into the sound
sound.extract(byteArray, 2048) // we are 2048 samples in, grab another 2048
sound.extract(byteArray, 2048) // we are 4096 samples in, grab another 2048, etc.
更重要的是,目前的使用方式实际上并不能阻止Flash播放器在长时间的声音中冻结,因为无论如何,你都是在一个循环中完成的。在一个循环中抓取500*2048(1024000)个步骤并不比用声音一次抓取它们要好。摘录(byteArray,1024000)。如果有的话,它会慢一些。在调用sound.extract的过程中,你需要给闪光时间来“呼吸”

下面是一个可能的解决方案:

class SoundLoader
{
    public var sound:Sound;
    public var byteArray:ByteArray;
    public var samplesInSound:int;

    public function SoundLoader(sound:Sound)
    {
        this.sound = sound;
        samplesInSound = sound.length * 44.1;
        byteArray = new ByteArray();
    }

    // Returns "true" if the sound has finished extracting.
    public function extract(samplesToExtract:int):Boolean
    {
        var extracted:int = sound.extract(byteArray, samplesToExtract);

        return extracted < samplesToExtract;
    }
}

function soundLoaded(e:Event)
{
    soundLoader = new SoundLoader(sound);

    // 2048 is very low, you'll need to experiment with how much you can load at once without Flash hiccupping.

    if (soundLoader.extract(2048))
    {
        // A very short sound! soundLoader.byteArray contains the extracted sound, ready to use.
    }
    else
    {
        // add a timer that calls soundLoader.extract(2048) again.
        // keep repeating the timer until soundLoader.extract returns 'true' - then you can use soundLoader.byteArray.
        // the timer allows Flash to do other things inbetween, which avoids it freezing up.
    }
}
类声音加载器
{
公共声音:声音;
公共变量byteArray:byteArray;
公共var-samplesInSound:int;
公共功能SoundLoader(声音:声音)
{
这个声音=声音;
samplesInSound=sound.length*44.1;
byteArray=新的byteArray();
}
//如果声音已完成提取,则返回“true”。
公共函数提取(samplesToExtract:int):布尔值
{
提取的var:int=sound.extract(byteArray,samplesToExtract);
返回提取的
谢谢你的回答。不幸的是,我的计划是以比我在每个循环中提取的数据更大的步长循环声音。例如,我想要实现的是:
sound.extract(byteArray,2048,0)//将2048个样本推进声音。extract(byteArray,2048,10000)//我们有10000个样本,再抓取一个2048声音。提取(byteArray,2048,20000)//我们有20000个样本,再抓取一个2048,等等。
我知道你提到的冻结问题。在最后的代码中,我将在帧上或在你的示例中,在计时器上连接循环。
class SoundLoader
{
    public var sound:Sound;
    public var byteArray:ByteArray;
    public var samplesInSound:int;

    public function SoundLoader(sound:Sound)
    {
        this.sound = sound;
        samplesInSound = sound.length * 44.1;
        byteArray = new ByteArray();
    }

    // Returns "true" if the sound has finished extracting.
    public function extract(samplesToExtract:int):Boolean
    {
        var extracted:int = sound.extract(byteArray, samplesToExtract);

        return extracted < samplesToExtract;
    }
}

function soundLoaded(e:Event)
{
    soundLoader = new SoundLoader(sound);

    // 2048 is very low, you'll need to experiment with how much you can load at once without Flash hiccupping.

    if (soundLoader.extract(2048))
    {
        // A very short sound! soundLoader.byteArray contains the extracted sound, ready to use.
    }
    else
    {
        // add a timer that calls soundLoader.extract(2048) again.
        // keep repeating the timer until soundLoader.extract returns 'true' - then you can use soundLoader.byteArray.
        // the timer allows Flash to do other things inbetween, which avoids it freezing up.
    }
}