2011-08-01 12 views
2

フラッシュcs3でメトロノームを作成しようとしています。これは、タイマーを使用することでそれほど一貫性がありません。フラッシュのタイミングを改善する(actionscript 3)

誰かが、より良いタイミング能力のために書いたかもしれないクラスを知っていたのだろうか、それともFlash Player 10で利用可能な新しいダイナミックサウンドジェネレーションでも方法がありますか?

答えて

0

良い質問です。私はいつもフラッシュの正確なタイミングを達成できないということは、VMの松葉杖であり、それを受け入れたと仮定してきました。しかし、私はグーグルで、Adobe Developer Connection CookBooksで次のレシピを見つけました。記録された結果の比較から判断すると、ユーザはうまく動作しているようですコメント:

Adobe Developer Connection CookBooks: Accurate Timer

テストそれをしては、あなたの結果を投稿し、私はそれらを読んで興味があると思います。

0

イベントが発生したときに実行されるコード(ENTER_FRAMEまたはTimerEventのいずれか)に制限されているため、現在のFlash Playerでは完全なタイミングを取得できません。

これまでの回答からもわかるように、これらのイベントが発生したとき(新しいDateインスタンスを作成するか、getTimer()を呼び出して)、フレーム間の時間デルタを計算すると、アプリケーションレコードを記録できます。これらのデルタを使用すると、アプリケーションが正確な時刻情報を持っているかのようにアプリケーションを動作させることができますが、イベントがその精度で起動しないため、50ミリ秒ごとに完全にコードを実行する方法はありません。

サウンド生成の可能性を使用する限り:Soundクラスには、ENTER_FRAMEまたはTimerEventの代わりに使用できるEvent.SAMPLE_DATAイベントがありますが、すぐには反応しません。バッファーに十分なデータを渡さないと、イベントは停止します。そして、バッファを満たすデータの量は、ENTER_FRAMEまたはTimerEventの精度よりも大きくなります。サポートするコード:

public class Tester extends Sprite 
{ 
    private const MAXIMUM_LOG_LINES:uint = 30; 

    private var _timer:Timer; 
    private var _sound:Sound; 

    private var _textField:TextField; 

    public function Tester() 
    { 
     stage.scaleMode = StageScaleMode.NO_SCALE; 
     stage.align = StageAlign.TOP_LEFT; 

     _textField = new TextField(); 
     _textField.defaultTextFormat = new TextFormat(null, 12); 
     _textField.multiline = true; 
     _textField.wordWrap = true; 
     _textField.width = stage.stageWidth; 
     _textField.height = stage.stageHeight; 
     addChild(_textField); 

     _timer = new Timer(1, 0); 
     _timer.addEventListener(TimerEvent.TIMER, onTimerTick, false, 0, true); 
     _timer.start(); 

     _sound = new Sound(); 
     _sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSoundSampleData, false, 0, true); 
     _sound.play(); 

     addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true); 
    } 

    private function onTimerTick(event:TimerEvent):void 
    { 
     log("onTimerTick(event) @"+getTimer()); 
    } 

    private function onEnterFrame(event:Event):void 
    { 
     log("onEnterFrame(event) @"+getTimer()); 
    } 

    private function onSoundSampleData(event:SampleDataEvent):void 
    { 
     log("onSoundSampleData(event) @"+getTimer()); 
     for (var c:int=0; c<2048; c++) 
     { 
      event.data.writeFloat(0); 
      event.data.writeFloat(0); 
     } 
    } 

    private function log(message:String):void 
    { 
     trace(message); 
     _textField.appendText(message+"\n"); 

     if (_textField.numLines > MAXIMUM_LOG_LINES) 
     { 
      var indexOfFirstLine:int = _textField.text.indexOf("\r"); 
      while(indexOfFirstLine >= 0 && _textField.numLines > MAXIMUM_LOG_LINES) 
      { 
       indexOfFirstLine++; 
       _textField.text = _textField.text.substring(indexOfFirstLine, _textField.text.length); 
       indexOfFirstLine = _textField.text.indexOf("\r"); 
      } 
     } 
    } 
} 

`

+0

SampleDataEventのアプローチは、実際にはかなり高精度で10ms以上の精度を生み出しています。 – Djip

0

私はこの問題を解決メトロノームと呼ばれるlibaryをリリースしました。これは私自身の問題に取り組む前に私の最初の検索が私を連れて来たからです。

http://cote.cc/projects/metronomeからダウンロードできます(GitHubリポジトリへのリンクもあります)。

希望すると便利です。

P.S.私はまた、図書館がどのようになったのかを詳述するブログ記事を書いた。 http://cote.cc/blog/accurate-timing-in-actionscript