AS3中准确的BPM事件监听器

时间:2009-12-07 08:41:33

标签: actionscript-3 flash audio flex

我正在尝试将动画同步到特定BPM的音乐。我尝试过使用Timer但是在处理小间隔时(毫秒)不准确。我做了一些阅读,发现了一种使用小型静音音频文件和SOUND_COMPLETE事件作为Timer的替代方法。

我用这段代码使用了167ms长的声音文件。

package
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;

    public class BetterTimer extends EventDispatcher
    {
        private var silentSound:Sound;

        public function BetterTimer(silentSoundUrl:String):void {
            super();
            silentSound = new Sound( new URLRequest(silentSoundUrl) );
            silentSound.addEventListener(Event.COMPLETE, start);
        }
        public function start():void {
            this.timerFired( new Event("start") );
        }
        private function timerFired(e:Event):void {
            dispatchEvent( new Event("fire") );
            var channel:SoundChannel = silentSound.play();
            channel.addEventListener(Event.SOUND_COMPLETE, timerFired, false, 0, true);
        }
    }
}

这仍然没有留下来。 Flash Player是否具有声音准确性?

5 个答案:

答案 0 :(得分:5)

您还可以将新的Sound API与SampleDataEvent一起使用,并基本上使用Sound.extract()手动播放MP3。在这种情况下,您可以预先知道延迟,甚至可以在您的(延迟)事件发生时计算样本。

这就是我们在AudioTool中所做的,而且效果非常好。

答案 1 :(得分:2)

这是非常棘手的正确!有一个名为BeatTimer的小型lib试图这样做。我自己没有尝试过这个代码,但如果它符合它的要求它应该正是你所需要的。

答案 2 :(得分:1)

设置帧速率以使事件间隔为帧速率的倍数可能会有所帮助(例如,167ms等于6 fps; 12,18,24等也可以。)

如果我理解正确,更好的解决方案是使用enterframe事件。不是通过计算事件来确定动画的位置,而是使用经过的时间(getTimer或声音位置)计算它。这也可以使动画在滞后的较慢的计算机上工作。

答案 3 :(得分:1)

我通过推出自己的节拍器课程回答了类似的问题。请在此处查看:Better timing in Flash (actionscript 3)

答案 4 :(得分:0)

我正在浏览popforge库的AudioBuffer并尝试使用其中一种方法。这就是创造同步声音。以下是我的所作所为。

var syncSamples:ByteArray = new ByteArray(); 
syncSamples.length = (2646000 / _bpm) << 1; /*44100*60=2646000*/
SoundFactory.fromByteArray(syncSamples, Audio.MONO, Audio.BIT16, Audio.RATE44100, soundInit);

ms延迟非常接近,例如:在120 BPM时,它在509 - 512ms之间。问题是,我正朝着正确的方向前进吗?