パッケージ com.lmt.lib.bms.bemusic

クラス BeMusicSequencer


  • public abstract class BeMusicSequencer
    extends Object
    BMS譜面の楽曲位置情報に含まれる時間情報に従って譜面の再生動作を行うシーケンサです。

    シーケンサは時間経過を監視し、然るべき時間に到達すると再生動作を行うべき楽曲位置情報の通知を順次行います。 シーケンサを利用することでアプリケーションはBMS譜面の処理タイミングの考慮から解放され、 再生動作のロジック実装に集中することができるようになります。

    Be-Musicサブセットが提供するシーケンサでは、一般的な音楽プレーヤーのような再生・停止・一時停止・再開機能に加え、 再生位置の設定・取得にも対応しているので、あらゆる種類のアプリケーションに応用することが可能です。 アプリケーションはシーケンサが提供する各種イベント通知を必要な分だけ実装することで、 目的とする機能を少ないコーディング量で実現できます。イベント通知の詳細は「on」で始まるメソッドを参照してください。

    状態遷移

    シーケンサは一般の音楽プレーヤーと似た状態を持ち、以下の図のような遷移を行います。

                                                       +-----------+
              +------------------stop------------------| COMPLETED |
              |                                        +-----------+
              |                                              1
              |                      +-------complete--------+
              v                      |
           +------+             +---------+              +---------+
     (*)-->| IDLE |----play---->| PLAYING |----pause---->| PAUSING |
           +------+             +---------+              +---------+
             1  1                  |   1                    |   |
             |  +-------stop-------+   +-------resume-------+   |
             |                                                  |
             +-----------------------stop-----------------------+

    再生制御と状態

    各再生制御機能は前述の状態により使用可否が異なります。どの状態の時にどの再生制御が有効かは以下の表を参照してください。 「n/a」と記載されている箇所は、その機能はその状態の時には使用できず、実行しても何も行われないことを示します。

     
    Func/StatusIDLEPLAYINGPAUSINGCOMPLETED
    playOKn/an/an/a
    stopn/aOKOKOK
    pausen/aOKn/an/a
    resumen/an/aOKn/a
    setPositionOKOKOKn/a

    イベント通知について

    当クラスではシーケンサの各種動作状況を検知するためのイベントが用意されています。 「on」で始まる名前のメソッドがイベント通知が行われるメソッドです。これらのメソッドは必ず loop(boolean), update() を呼び出したスレッドから呼び出されることに留意してください。

    • フィールドの概要

      フィールド 
      修飾子とタイプ フィールド 説明
      static int QUEUE_SIZE
      再生制御要求キューのサイズ
      static double SLEEP_TIME_DEFAULT
      当クラスが提唱するループ待機時間の規定値(秒)
      static double SLEEP_TIME_MAX
      ループ待機時間の最大値(秒)
    • コンストラクタの概要

      コンストラクタ 
      修飾子 コンストラクタ 説明
      protected BeMusicSequencer​(BeMusicChart chart)
      新しいシーケンサオブジェクトを構築します。
      protected BeMusicSequencer​(BeMusicChart chart, double duration)
      新しいシーケンサオブジェクトを構築します。
    • メソッドの概要

      すべてのメソッド staticメソッド インスタンス・メソッド concreteメソッド 
      修飾子とタイプ メソッド 説明
      BeMusicChart getChart()
      このシーケンサが再生対象としているBMS譜面を取得します。
      double getDuration()
      このシーケンサの再生時間(秒)を取得します。
      double getPosition()
      現在の再生位置(秒)を取得します。
      boolean isCompleted()
      シーケンサの状態が「再生完了」かどうかを取得します。
      boolean isPausing()
      シーケンサの状態が「一時停止中」かどうかを取得します。
      boolean isPlaying()
      シーケンサの状態が「再生中」かどうかを取得します。
      boolean isStopped()
      シーケンサの状態が「初期状態」かどうかを取得します。
      void loop​(boolean exitWhenComplete)
      シーケンサの「時間経過処理」をループします。
      protected void onComplete()
      BMS譜面の再生が完了(再生によって再生位置が再生時間に到達)した時に呼び出されます。
      protected void onFinishLoop​(Throwable uncaught)
      ループ処理による時間経過処理が終了した時に呼び出されます。
      protected double onGetSleepTime()
      ループ処理による待機の直前で待機時間を決定する時に呼び出されます。
      protected void onPause()
      BMS譜面の再生が一時停止された時に呼び出されます。
      protected void onPlay()
      BMS譜面の再生が開始された時に呼び出されます。
      protected void onPoint​(BeMusicPoint p)
      再生位置が楽曲位置情報の時間に到達した時に呼び出されます。
      protected void onResume()
      BMS譜面の再生が再開された時に呼び出されます。
      protected void onSeek​(double oldPosition)
      再生位置が変更された時に呼び出されます。
      protected void onStartLoop()
      ループ処理による時間経過処理が開始された時に呼び出されます。
      protected void onStop()
      BMS譜面の再生が停止された時に呼び出されます。
      protected void onUpdate()
      時間経過処理が1回実行される度に1回呼び出されます。
      void pause()
      BMS譜面の再生を一時停止します。
      void play()
      BMS譜面の再生を開始します。
      static void play​(BeMusicChart chart, double duration, double sleepTime, Consumer<BeMusicPoint> processor)
      指定したBMS譜面を再生します。
      static void play​(BeMusicChart chart, Consumer<BeMusicPoint> processor)
      指定したBMS譜面を再生します。
      void resume()
      BMS譜面の再生を再開します。
      void setPosition​(double newPosition)
      現在の再生位置を指定した位置に設定します。
      void stop()
      BMS譜面の再生を停止します。
      void update()
      シーケンサの「時間経過処理」を1回実行します。
    • フィールドの詳細

      • SLEEP_TIME_DEFAULT

        public static final double SLEEP_TIME_DEFAULT
        当クラスが提唱するループ待機時間の規定値(秒)
        関連項目:
        定数フィールド値
      • SLEEP_TIME_MAX

        public static final double SLEEP_TIME_MAX
        ループ待機時間の最大値(秒)
        関連項目:
        定数フィールド値
      • QUEUE_SIZE

        public static final int QUEUE_SIZE
        再生制御要求キューのサイズ
        関連項目:
        定数フィールド値
    • コンストラクタの詳細

      • BeMusicSequencer

        protected BeMusicSequencer​(BeMusicChart chart,
                                   double duration)
        新しいシーケンサオブジェクトを構築します。

        シーケンサは再生対象のBMS譜面と再生時間が必須入力情報となります。 アプリケーションでシーケンサを実装する際はオブジェクト構築時にこれらを指定できるように設計してください。

        パラメータ:
        chart - 再生対象のBMS譜面
        duration - 再生時間
        例外:
        NullPointerException - chartがnull
        IllegalArgumentException - durationがマイナス値
    • メソッドの詳細

      • getChart

        public BeMusicChart getChart()
        このシーケンサが再生対象としているBMS譜面を取得します。
        戻り値:
        再生対象のBMS譜面
      • getDuration

        public double getDuration()
        このシーケンサの再生時間(秒)を取得します。
        戻り値:
        再生時間(秒)
      • getPosition

        public double getPosition()
        現在の再生位置(秒)を取得します。

        再生位置はループ処理または更新処理によって時間経過処理を行うことで更新されます。 時間経過処理を行わない場合、常に同じ値を返すことに注意してください。

        戻り値:
        現在の再生位置(秒)
      • setPosition

        public void setPosition​(double newPosition)
        現在の再生位置を指定した位置に設定します。

        当メソッドを呼び出すと再生位置を指定した位置に更新する要求が再生制御要求キューに投入されます。 要求が処理されるのはループ処理または更新処理によって時間経過処理が行われる時です。 要求が受理されると現在の再生位置を更新し、onSeek(double) が呼び出されます。

        再生位置の設定を再生が完了している状態で実行しても再生位置は更新されません。 例外はスローされないので再生位置を更新可能な状態かどうかは isCompleted() で調べてください。

        パラメータ:
        newPosition - 新しい再生位置(秒)
        例外:
        IllegalArgumentException - newPositionがマイナス値または再生時間超過
        IllegalStateException - 再生制御要求キューに空きがなく要求が受理できなかった
      • isPlaying

        public boolean isPlaying()
        シーケンサの状態が「再生中」かどうかを取得します。
        戻り値:
        シーケンサの状態が「再生中」であればtrue
      • isPausing

        public boolean isPausing()
        シーケンサの状態が「一時停止中」かどうかを取得します。
        戻り値:
        シーケンサの状態が「一時停止中」であればtrue
      • isStopped

        public boolean isStopped()
        シーケンサの状態が「初期状態」かどうかを取得します。
        戻り値:
        シーケンサの状態が「初期状態」であればtrue
      • isCompleted

        public boolean isCompleted()
        シーケンサの状態が「再生完了」かどうかを取得します。
        戻り値:
        シーケンサの状態が「再生完了」であればtrue
      • loop

        public void loop​(boolean exitWhenComplete)
        シーケンサの「時間経過処理」をループします。

        当メソッドは、呼び出し元スレッドによってシーケンサの時間経過処理をループします。 実際にループが開始される前に onStartLoop() が呼び出され、その後再生が終了するまで時間経過処理が繰り返されます。 このループ処理は呼び出し元スレッドが割り込まれるか、exitWhenCompleteがtrueの場合はシーケンサの状態が「再生終了」 になるまで繰り返されます。

        時間経過処理が1回処理される度にループの待機処理が入り、CPU負荷の軽減措置が行われます。 待機時間は毎回 onGetSleepTime() が返す値によって決定されます。詳細はイベントの説明を参照してください。 待機時間が長くなると、その分次の時間経過処理で一度に処理される楽曲位置情報の量が多くなります。 サウンドの再生を伴うシーケンサの場合、それにより正確なサウンドの再生タイミングが確保できなくなりますので、 待機時間を長くしすぎないように設計してください。

        ループ処理が終了すると onFinishLoop(Throwable) が呼び出され、当メソッドから制御が戻ります。 ループ処理中に例外がスローされるとループ処理から抜け、その例外が前述のイベントで通知されます。 通知された例外はイベント処理終了後に呼び出し元へスローされます。

        当メソッドと update() は相互排他の関係にあり、どちらかが実行されている間はもう片方を実行できません。 また、複数スレッドによる当メソッドの多重実行もできません。

        パラメータ:
        exitWhenComplete - シーケンサの状態が「再生終了」になった時ループ処理を終了するかどうか
        例外:
        IllegalStateException - 別スレッドがループ処理を実行中
        IllegalStateException - update() を実行中
        関連項目:
        update()
      • update

        public void update()
        シーケンサの「時間経過処理」を1回実行します。

        シーケンサの状態が再生中の時に当メソッドを呼び出すと、前回の時間経過処理からの時間分だけ時間経過を行います。 その時間経過で通過した楽曲位置が onPoint(BeMusicPoint) イベントに通知され、その後 onUpdate() イベントが呼び出されます。

        当メソッドによる時間経過処理では待機処理は実行されません。よって onGetSleepTime() も呼び出されません。

        当メソッドはアプリケーションの他の箇所で実装されたループ処理・待機処理の中に、 シーケンサの処理を組み込みたい場合に役立ちます。ただし、シーケンサがサウンドの再生を行うケースでは、 当メソッドの呼び出し間隔が空きすぎないように注意してください。 間隔が空きすぎると正確なサウンドの再生タイミングが確保できなくなります。

        当メソッドと loop(boolean) は相互排他の関係にあり、どちらかが実行されている間はもう片方を実行できません。 また、複数スレッドによる当メソッドの多重実行もできません。

        例外:
        IllegalStateException - 別スレッドが時間経過処理を実行中
        IllegalStateException - loop(boolean) を実行中
      • play

        public void play()
        BMS譜面の再生を開始します。

        当メソッドを呼び出すと再生要求が再生制御要求キューに投入されます。 要求が処理されるのはループ処理または更新処理によって時間経過処理が行われる時です。 要求が受理されると現在の再生位置から時間経過のカウントを開始し、onPlay() が呼び出されます。

        当メソッドが作用するのはシーケンサの状態が「初期状態」の時のみです。それ以外の状態では何も行われません。 例外はスローされないので再生可能な状態かどうかは isStopped() で調べてください。

        例外:
        IllegalStateException - 再生制御要求キューに空きがなく要求が受理できなかった
      • stop

        public void stop()
        BMS譜面の再生を停止します。

        当メソッドを呼び出すと停止要求が再生制御要求キューに投入されます。 要求が処理されるのはループ処理または更新処理によって時間経過処理が行われる時です。 要求が受理されると再生位置が0にリセットされ、onStop() が呼び出されます。

        既に停止されている状態で当メソッドを呼び出しても何も行われません。 例外はスローされないので停止可能な状態かどうかは isStopped() で調べてください。

        例外:
        IllegalStateException - 再生制御要求キューに空きがなく要求が受理できなかった
      • pause

        public void pause()
        BMS譜面の再生を一時停止します。

        当メソッドを呼び出すと一時停止要求が再生制御要求キューに投入されます。 要求が処理されるのはループ処理または更新処理によって時間経過処理が行われる時です。 要求が受理されると時間経過処理による再生位置のカウントが停止され、onPause() が呼び出されます。

        当メソッドが作用するのはシーケンサの状態が「再生中」の時のみです。それ以外の状態では何も行われません。 例外はスローされないので一時停止可能な状態かどうかは isPlaying() で調べてください。

        例外:
        IllegalStateException - 再生制御要求キューに空きがなく要求が受理できなかった
      • resume

        public void resume()
        BMS譜面の再生を再開します。

        当メソッドを呼び出すと再開要求が再生制御要求キューに投入されます。 要求が処理されるのはループ処理または更新処理によって時間経過処理が行われる時です。 要求が受理されると時間経過処理による再生位置のカウントが再開され、onResume() が呼び出されます。

        当メソッドが作用するのはシーケンサの状態が「一時停止中」の時のみです。それ以外の状態では何も行われません。 例外はスローされないので再開可能な状態かどうかは isPausing() で調べてください。

        例外:
        IllegalStateException - 再生制御要求キューに空きがなく要求が受理できなかった
      • play

        public static void play​(BeMusicChart chart,
                                Consumer<BeMusicPoint> processor)
        指定したBMS譜面を再生します。

        当メソッドは再生位置に到達した楽曲位置情報の処理のみを行う簡易シーケンサによってBMS譜面を再生します。 再生時間は指定したBMS譜面の BeMusicChart.getPlayTime()、ループ処理の待機時間は SLEEP_TIME_DEFAULT を使用し、楽曲位置情報は関数processorに通知します。 指定したBMS譜面を時間まで再生後、当メソッドが終了します。

        パラメータ:
        chart - 再生対象のBMS譜面
        processor - 再生位置に到達した楽曲位置情報を処理する関数
        例外:
        NullPointerException - chartがnull
        NullPointerException - processorがnull
      • play

        public static void play​(BeMusicChart chart,
                                double duration,
                                double sleepTime,
                                Consumer<BeMusicPoint> processor)
        指定したBMS譜面を再生します。

        当メソッドは再生位置に到達した楽曲位置情報の処理のみを行う簡易シーケンサによってBMS譜面を再生します。 再生時間、ループ処理の待機時間は指定された値を使用し、楽曲位置情報は関数processorに通知します。 指定したBMS譜面を時間まで再生後、当メソッドが終了します。

        パラメータ:
        chart - 再生対象のBMS譜面
        duration - 再生時間
        sleepTime - ループ処理の待機時間
        processor - 再生位置に到達した楽曲位置情報を処理する関数
        例外:
        NullPointerException - chartがnull
        IllegalArgumentException - durationがマイナス値
        IllegalArgumentException - sleepTimeがSLEEP_TIME_MAX超過
        NullPointerException - processorがnull
      • onStartLoop

        protected void onStartLoop()
        ループ処理による時間経過処理が開始された時に呼び出されます。

        当イベントは loop(boolean) によるループ処理が開始された直後に呼び出されます。 実際の時間経過処理は当イベントの処理終了後に開始されます。アプリケーションは必要に応じて、 自身が実装するシーケンサの初期化処理を当イベントに記述することができます。

        当イベントで実行時例外がスローされると時間経過処理は一度も実行されることなく onFinishLoop(Throwable) が呼び出され、その後ループ処理が終了し呼び出し元へ例外がスローされます。

      • onFinishLoop

        protected void onFinishLoop​(Throwable uncaught)
        ループ処理による時間経過処理が終了した時に呼び出されます。

        当イベントは loop(boolean) によるループ処理が終了した直後に呼び出されます。 ループ処理の終了契機についてはloop(boolean) のドキュメントを参照してください。

        当イベントでは、シーケンサの処理終了時にアプリケーション独自のメモリ解放などの終了処理を記述できます。 また、ループ処理中に未キャッチの例外がスローされたかどうかをイベントの引数で検知することができます。

        パラメータ:
        uncaught - ループ処理中にスローされた未キャッチの例外、またはnull
      • onPlay

        protected void onPlay()
        BMS譜面の再生が開始された時に呼び出されます。

        当イベントは play() による再生要求が処理された直後に呼び出されます。 当イベントが呼び出されるのは、停止していたBMS譜面が再生され始めることを意味します。 また、その時の再生位置は必ずしもBMS譜面の先頭(0)であるとは限りません。 アプリケーションは再生開始時に必要な処理を当イベント内で記述してください。

      • onStop

        protected void onStop()
        BMS譜面の再生が停止された時に呼び出されます。

        当イベントは stop() による停止要求が処理された直後に呼び出されます。 BMS譜面の再生位置は常に先頭(0)にリセットされますので、再生位置を任意の場所に設定したい場合は別途 setPosition(double) を呼び出して明示的に再生位置を更新してください。

      • onPause

        protected void onPause()
        BMS譜面の再生が一時停止された時に呼び出されます。

        当イベントは pause() による一時停止要求が処理された直後に呼び出されます。 BMS譜面の再生位置は、再生が再開されるか明示的に再生位置を更新するまで変化しません。

        シーケンサが一時停止・再開をサポートし、且つサウンドの再生を伴う場合、 アプリケーションは現在のサウンドを全て停止し、次に再生が再開されるまでその状態を保持することが求められます。

      • onResume

        protected void onResume()
        BMS譜面の再生が再開された時に呼び出されます。

        当イベントは resume() による再開要求が処理された直後に呼び出されます。 BMS譜面の再生位置のカウントが再開され、時間経過に伴い再生位置が変化するようになります。

        シーケンサが一時停止・再開をサポートし、且つサウンドの再生を伴う場合、 アプリケーションは現在の再生位置からのサウンド再生を再開することが求められます。

      • onComplete

        protected void onComplete()
        BMS譜面の再生が完了(再生によって再生位置が再生時間に到達)した時に呼び出されます。

        当イベントが呼ばれる時、再生位置(getPosition())は再生時間(getDuration())と同じになります。 また、isCompleted() はtrueを返します。この状態になると再生・一時停止・再開は全て受け付けなくなり、 停止のみが有効な操作となります。

        当イベントは onPoint(BeMusicPoint), onUpdate() よりも後で呼び出されます。

      • onUpdate

        protected void onUpdate()
        時間経過処理が1回実行される度に1回呼び出されます。

        当イベントは update() では呼び出し毎に1回、loop(boolean) ではループ毎に1回呼ばれます。 1回の時間経過処理で処理する楽曲位置情報が存在するかどうかに限らず、必ず呼び出されます。 当イベントの目的は、楽曲位置情報の有無に限らず何らかの定期的な処理が必要な時にその処理を行うことにあります。 例えば、譜面の描画処理などは楽曲位置情報の到達有無に限らず一定周期で行わなければならないため、 そのような処理を行う契機として当イベントを活用することを想定しています。

        当イベントから再生位置を取得すると、時間経過処理後の再生位置が返ります。 アプリケーションはその再生位置を基準としてBMS譜面から各種情報を抽出し、希望する処理を実装できます。

        当イベントは最も頻繁に呼び出されるイベントです。イベント内で記述する処理はできるだけ負荷を軽く、 使用メモリ容量を小さく抑えるべきです。当イベントの負荷が高すぎると後続の時間経過処理に遅れが生じ、 再生動作の品質が低下する可能性が発生してしまいます。

      • onPoint

        protected void onPoint​(BeMusicPoint p)
        再生位置が楽曲位置情報の時間に到達した時に呼び出されます。

        イベントの入力引数には再生位置に到達した楽曲位置情報が格納されています。当イベントで行う主な処理は、 例えばBGMの再生、BGAの表示、テキストの表示など、再生位置に応じたプレゼンテーションが挙げられます。 これらのように処理タイミングに忠実に従う必要のある処理は当イベントで行うことが推奨されます。

        このイベントは onUpdate() よりも先に呼び出されます。 前述の通り、当イベントで推奨される処理にはサウンド再生に関連するものがあり、 少しでも早く処理を完了させることが求められるためです。

        当イベント呼び出しの時間的な精度は onGetSleepTime() が返す待機時間の長さに大きく依存します。 アプリケーションごとに必要な精度は待機時間の長さで調整してください。(ループ処理で時間経過処理を行う場合)

        パラメータ:
        p - 再生位置に到達した楽曲位置情報
        関連項目:
        BeMusicPoint.getTime()
      • onSeek

        protected void onSeek​(double oldPosition)
        再生位置が変更された時に呼び出されます。

        当イベントが呼び出された時に getPosition() を呼び出すと、変更後の再生位置が返ります。 変更前の再生位置を参照したい場合は入力引数の再生位置を参照してください。

        パラメータ:
        oldPosition - 変更前の再生位置(秒)
      • onGetSleepTime

        protected double onGetSleepTime()
        ループ処理による待機の直前で待機時間を決定する時に呼び出されます。

        当イベントは待機毎に呼び出されます。これはシーケンサの状態により待機時間を調整する場合などに対応するためです。 そのような必要がなければ常に同じ値を返すように実装してください。デフォルトでは固定で SLEEP_TIME_DEFAULT を返すように実装されています。

        返す待機時間は SLEEP_TIME_MAX を超えないようにしてください。超えた値を返すと例外がスローされます。 また、0以下の値を返すと待機処理自体を行わず、ループ処理が最高速度で動作するようになります。 再生の精度は最大化されますが、CPU負荷は非常に高くなりますので注意してください。

        戻り値:
        待機時間(秒)