Tips・その他 


$mplayer.play()のバグの原因となるコード

$mplayerオブジェクトは、MediaPlayerクラスです。
MediaPlayerクラスのソースは、「Kernel\Util\MediaPlayer.tonyu」です。
この「MediaPlayer.tonyu」にバグの原因となるコードがあります。

MediaPlayer.tonyuのplayメソッド定義部分
function play( s,ar,v) {
  if ( s) {
    if (s is BGM) stop();
    if (!v || (v>=0 && v<=128)) {
      s.play(ar,v);
    } else {
      s.play(ar,128);
    }
  }/* else {
    (new BGM()).play();
  }*/
}

3行目のstop();が、バグの原因となっています。
サウンドオブジェクト(「$se_bgm01」など)がMidiの場合、
Midiを停止してから、再生しているように見えます。

しかし、このplay()やstop()は、実際にはsigファイルを書き込んでいるだけです(play()はMidiの再生時のみ)
sigファイルの内容は、1行目にP,R,S,Xのどれか1つが書かれます。
意味は、P:再生(繰り返しなし)、R:再生(繰り返しあり)、S:停止、X:Tonyuの終了です。
1行目がP,Rの場合、2行目にはMidiファイルのパスが書き込まれます。

sigファイルをMusicPlayerが読み込んで、MusicPlayerはそれぞれの動作をします。

上のコードでは、Midiの再生をするのに2回も書き込み処理を行ってしまいます。
つまり、無駄な書き込みをしているということです。

どのようなバグがおこるか

再生命令を出してもMidiが再生されないことがあります。
例えば、BGMが切り替わる時に、次に再生するBGMが再生されず、BGMが停止した状態になることがあります。

Tonyuからはsigファイルを書き込み、MusicPlayerからはsigファイルを読み込むので、
書き込みと読み込みのタイミングが重なると、再生・停止が行われない可能性があります。

Ymplayer.tonyuと修正版MediaPlayer.tonyuでは、上の3行目のコードを省いているため、
バグが起こりにくくなります。
しかし、もしかするとYmeplayerクラスや修正版MediaPlayer.tonyuを使ってもバグが起こるかもしれません。
TonyuとMusicPlayerが、1つのファイルを読み書きする以上、同時アクセスが発生するので、
このバグを完全に消すことはできません。

バグの原因となるプログラムを作らない

このバグが起きる原因は、stop()のすぐ後にplay()を呼び出していることです。
プロジェクト上でこれと同じことをしている場合は、バグが起きやすいです。
BGMの切替をする場合は、なるべくこのようにしない方がいいです。

戻る