2009-05-30 9 views
0

Appel channel.position sur un événement ENTER_FRAME, je remarque que ce n'est pas mis à jour toutes les images, mais il ressemble plus à chaque image et demi.Cadres pour Audio Synchronisation et channel.position Précision

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)); 
}); 

se traduira par quelque chose le long des lignes de (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 
    ... 

Quelqu'un at-il remarqué ce comportement avant? Existe-t-il des techniques pour déterminer quel «cadre» de l'audio est joué, sachant cette inexactitude?

Répondre

0

Oui, ce comportement est normal car les événements sont threadés et appellent donc leurs délégués chaque fois que leur thread est prioritaire. L'impression sur la console est également effectuée de manière à ne pas toujours imprimer des messages au bon moment. En fait, le problème que vous voyez est probablement juste un problème d'impression. Essayez de stimuler votre framerate, voir ce qui se passe.

Cependant, pour être plus précis, vous pouvez essayer d'utiliser la classe de minuterie. Généralement, vous pouvez faire en sorte que les coches se produisent beaucoup plus rapidement que vos images, ce qui signifie que la marge d'erreur sera plus faible. Pourtant, vous utilisez l'événement, donc il peut y avoir une certaine dérive.

Pour compenser cela, vous pouvez vérifier l'heure par rapport aux trames pour déterminer le décalage. Cela vous permet de corriger toute dérive.

EDIT: Cet exemple a été tiré directement à partir this page dans la documentation ActionScript 3, notez les positionTimer qu'ils utilisent:

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(); 
     } 
    } 
} 
+0

Jacking le taux de trame jusqu'à 60 prend en charge les images manquantes, mais ne augmenter la granularité des demandes channel.position. Il en résulte que la trame 55 est signalée 3, ou 4 fois 56 signalées 3 ou 4 fois, et ainsi de suite. – Robert

+0

C'est étrange parce que les événements ENTER_FRAME ne devraient se déclencher qu'une fois par image. – Soviut

+0

À droite, et ce n'est pas qu'il déclenche plus d'une fois une image, sa position de canal est mise à jour à une vitesse plus lente que la fréquence d'images. – Robert