Синхронизация кадров с аудио и каналом. Точность позиционирования - PullRequest
0 голосов
/ 30 мая 2009

Вызывая channel.position для события ENTER_FRAME, я замечаю, что оно не обновляется каждый кадр, но выглядит больше как каждые полтора кадра.

var sound:Sound = new Sound(new URLRequest('music.mp3')); 
var channel:SoundChannel = sound.play(); // assume the sound is completely,
                                         // totally, 100% loaded

addEventListener(Event.ENTER_FRAME, function(e:Event):void{
   trace(  "Position : " + channel.position 
         + " - Frame : " + int(channel.position / 30));
});

приведет к чему-то вроде (30 FPS)

   ...
   Position : 1439.6371882086166 - Frame : 47
   // 48 is missing
** Position : 1486.077097505669 -  Frame : 49
** Position : 1486.077097505669 -  Frame : 49
   Position : 1532.517006802721 -  Frame : 51
   Position : 1578.9569160997733 - Frame : 52
   // 53 is missing
** Position : 1625.3968253968253 - Frame : 54
** Position : 1625.3968253968253 - Frame : 54
   Position : 1671.8367346938776 - Frame : 55
   // 56 is missing
   Position : 1718.2766439909296 - Frame : 57
   ...

Кто-нибудь замечал такое поведение раньше? Существуют ли какие-либо методы для определения того, какой «кадр» звука воспроизводится, зная эту неточность?

1 Ответ

0 голосов
/ 31 мая 2009

Да, это нормальное поведение, потому что события являются многопоточными и поэтому будут вызывать их делегаты всякий раз, когда их поток имеет приоритет. Печать на консоль также является многопоточной, поэтому она не всегда может печатать сообщения в нужное время. Infact, проблема, которую вы видите, вероятно, просто проблема печати. Попробуйте увеличить частоту кадров, посмотрите, что получится.

Тем не менее, чтобы быть более точным, вы можете попробовать использовать класс таймера. Как правило, вы можете заставить тики происходить намного быстрее, чем ваши кадры, что означает, что поле для ошибки будет ниже. Тем не менее, вы используете событие, поэтому возможны некоторые отклонения.

Чтобы компенсировать это, вы можете сравнить время с кадрами, чтобы определить смещение. Это позволит вам исправить любой дрейф.

РЕДАКТИРОВАТЬ: этот пример был взят прямо из этой страницы в документации ActionScript 3, обратите внимание на positionTimer, который они используют:

package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;
    import flash.utils.Timer;

    public class SoundChannelExample extends Sprite {
        private var url:String = "MySound.mp3";
        private var soundFactory:Sound;
        private var channel:SoundChannel;
        private var positionTimer:Timer;

        public function SoundChannelExample() {
            var request:URLRequest = new URLRequest(url);
            soundFactory = new Sound();
            soundFactory.addEventListener(Event.COMPLETE, completeHandler);
            soundFactory.addEventListener(Event.ID3, id3Handler);
            soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            soundFactory.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            soundFactory.load(request);

            channel = soundFactory.play();
            channel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);

            positionTimer = new Timer(50);
            positionTimer.addEventListener(TimerEvent.TIMER, positionTimerHandler);
            positionTimer.start();
        }


        private function positionTimerHandler(event:TimerEvent):void {
            trace("positionTimerHandler: " + channel.position.toFixed(2));
        }

        private function completeHandler(event:Event):void {
            trace("completeHandler: " + event);
        }

        private function id3Handler(event:Event):void {
            trace("id3Handler: " + event);
        }

        private function ioErrorHandler(event:Event):void {
            trace("ioErrorHandler: " + event);
            positionTimer.stop();       
        }

        private function progressHandler(event:ProgressEvent):void {
            trace("progressHandler: " + event);
        }

        private function soundCompleteHandler(event:Event):void {
            trace("soundCompleteHandler: " + event);
            positionTimer.stop();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...