2009-12-07 2 views
2

Я пытаюсь синхронизировать анимацию с музыкой при определенном BPM. Я пробовал использовать таймер, но он неточен при работе с небольшими интервалами в миллисекундах. Я сделал некоторое чтение и нашел альтернативный метод, в котором используется небольшой тихий аудиофайл и событие SOUND_COMPLETE в качестве таймера.Точный прослушиватель событий BPM в AS3

Я использовал звуковой файл длиной 167мс с этим кодом.

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 способным к точности со звуком?

ответ

2

Это очень сложно сделать правильно! Есть небольшая библиотека под названием BeatTimer, которая пытается это сделать. Я сам не пробовал этот код, но если он делает то, что он утверждает, он должен быть именно тем, что вам нужно.

+0

Я только что дал этому BeatTimer попробовать. Это было написано, чтобы нанести удар по четверти ударам при определенном BPM. Я тестировал его с восьмым и шестнадцатым, и он остается точным в течение моей 2-минутной петли. Я также хотел бы попробовать решение Joa, но для моих целей этот BeatTimer работает хорошо. Благодарю. – knuckfubuck

1

Установка частоты кадров, так что интервал событий может быть кратным частоте кадров, может помочь (например, 167 мс равно 6 кадров в секунду, 12, 18, 24 и т.д.).

Если я правильно понял, лучшим решением было бы использовать событие enterframe. Вместо определения положения анимации путем подсчета событий вычислите его с использованием прошедшего времени (getTimer или положение звука). Это также заставило бы анимацию работать на более медленных компьютерах с задержкой.

5

Вы также можете использовать новый Sound API с SampleDataEvent и в основном воспроизводить MP3 вручную, используя Sound.extract(). В этом случае вы знаете латентность спереди и можете даже подсчитать до образца, когда произойдет ваше (замедленное) событие.

Это то, что мы делаем в AudioTool, и оно работает очень хорошо.

0

Я искал AudioBuffer библиотеки Popforge и попытался использовать один из подходов. Это создает синхронизирующий звук. Следующее - это то, что я сделал.

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 - 512 мс. Вопрос в том, иду я в правильном направлении?

Смежные вопросы