2011-08-27 35 views
0

从这个AS3代码中,我预计500行包含“2048”的跟踪输出。但是,我只能看到一些包含“2048”的行。剩下的迹线打印出一个“0”,表明extract()方法没有返回任何数据。使用Sound.extract在循环中分析声音文件的AS3

为什么会出现这种情况?我想用特定的步骤遍历声音文件以在相应的位置提取2048个字节的声音。一次抽取整个音效档将冻结秒的Adobe Flash,因此不能够被发现,只要步骤小于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); 
    } 
} 

我的想法,音效档的提取部分提取它(如在Actionscript 3 - Sound.extract method empties sound object data)后切出的音效档的休息,所以我尝试了另一个for循环:

for(var i=0; i<samplesInSound - steps * 2048; i += Math.floor(samplesInSound/steps) - 2048) 

但是这也没有奏效。

任何人都可以帮助我解决这个问题吗?

回答

1

我没有足够的声望来评论你的问题,所以我会用一个免责声明写下这个答案,让我知道它是否不能解决你的问题。

每次调用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(1,024,000)步骤并不比用sound.extract(byteArray,1024000)一次全部抓取它们更好。如果有的话,它会变慢。您需要给闪光时间以在呼叫声音之间'呼吸'。提取。

这里是一个可能的解决方案:

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. 
    } 
} 
+0

谢谢您的回答。不幸的是,我的计划是以比我在每个循环中提取的数据更大的步幅循环播放声音。例如: 'sound.extract(byteArray,2048,0)//将2048个采样前进到声音中 sound.extract(byteArray,2048,10000)//我们是10000个采样,抓住另一个2048 sound.extract(byteArray,2048,20000)//我们是20000个样本,再抓另一个2048等。' 我知道你提到的冻结问题。在最后的代码中,我将连接框架上的循环,或者像你的例子一样,连接一个定时器。 – user914964