音声とイベントの同期

 KAG での音声とイベントの同期といえば、

@playse storage=se.wav
@resetwait
@hoge
@wait mode=until time=10000
@hogehoge
@wait mode=until time=15000
@hogehogehoge

などとやるのが定番です。

 しかし、これだと音声の再生がもたついたりした場合に、段々、音声とイベントがずれてしまう可能性があります。そこで、もっと精度の高い同期はできないでしょうか。

 というわけで、早速、作ってみました。

; first.ks -----------------------------------------------------------------
@loadplugin module=wuvorbis.dll

@iscript

//--------------------------------------------------------------------------
// 同期プラグイン
//--------------------------------------------------------------------------
class SynchroPlugin extends KAGPlugin
{
    var buf;
    var time;
    var moving = false;

    //----------------------------------------------------------------------

    // コンストラクタ
    function SynchroPlugin(window)
    {
        super.KAGPlugin(); // 親クラスのコンストラクタを呼ぶ
        this.window = window; // ウィンドウへの参照
    }

    //----------------------------------------------------------------------

    // デストラクタ
    function finalize()
    {
        finish(); // 終了
        super.finalize(...); // 親クラスのデストラクタを呼ぶ
    }

    //----------------------------------------------------------------------

    // 同期の開始
    function startSynchro(buf = 0, time = 0)
    {
        finish(); // 終了

        this.buf = buf;
        this.time = time;

        System.addContinuousHandler(continuousHandler);
        moving = true;
    }

    //----------------------------------------------------------------------

    // タイマーの周期が来た
    function continuousHandler()
    {
        if(kag.se[buf].position >= time)
            finish();
    }

    //----------------------------------------------------------------------

    /// 終了
    function finish()
    {
        if(moving)
        {
            window.trigger('synchro');
            System.removeContinuousHandler(continuousHandler);
            moving = false;
            buf = void;
            time = void;
        }
    }

    //----------------------------------------------------------------------

    function onRestore(f, clear, elm)
    {
        finish(); // 終了
    }

    //----------------------------------------------------------------------

}
//--------------------------------------------------------------------------

kag.addPlugin(global.synchro_object = new SynchroPlugin(kag));
    // プラグインオブジェクトを作成し、登録する

@endscript
; マクロ登録
@macro name=waitse
@eval exp="synchro_object.startSynchro(+mp.buf, +mp.time)"
@waittrig * name="synchro" onskip="synchro_object.finish()"
@endmacro

@playse storage=test.ogg
曲が始まりました。[r]
@waitse buf=0 time=12000
12秒たちました。[r]
@waitse buf=0 time=15000
15秒たちました。[r]
;---------------------------------------------------------------------------