クラス BmsLoader
- Object
-
- BmsLoader
-
public final class BmsLoader extends Object
外部データからBMSコンテンツを生成するローダーです。BMSライブラリは、「外部データ」からBMSコンテンツを読み込む機能を提供します。ここで言う「外部データ」とは、 BMSで記述されたテキストデータのことを指します。外部データはファイル等の何らかの形式で記録されていることを 想定しており、Java言語の
InputStream
で読み取ることができるもの全てを指します。外部データの記述形式について
外部データは上述の通り、BMSで記述されたテキストデータです。一般的には「BMSファイル」のことを指します。 BMSライブラリで読み取り可能な記述形式は一般的なBMSの仕様を取り込んでいますが、一部独自の機能を盛り込んでいます。 詳細については以下を参照してください。BMS宣言
BMSの1行目において、";?bms "で始まるコメントを検出した場合、1行目をBMS宣言として解析しようとします。 BMS宣言の構文に誤りがある場合、BMS宣言は通常のコメントとして認識されるようになり、BMS宣言の無いBMSコンテンツとして 読み込まれます。BMS宣言の記述例は以下の通りです。;?bms encoding="UTF-8" rule="BM"
メタ情報
BMSの中で「ヘッダ」と呼ばれる宣言をメタ情報として解析します。メタ情報は"#"または"%"で始まる 行が該当します。ただし、BMS仕様で規定されていない名称のメタ情報はBMSコンテンツの情報としては読み込まれません。 それらの行は無視されるか、解析エラーとして報告されます。
メタ情報はBMSのどこで宣言されていても問題無く読み込むことができます(チャンネルを記述した後でもOK)。 ただし、一般的にはメタ情報を全て宣言した後でチャンネルを記述することがほとんどのようです。
メタ情報の記述例は以下の通りです。#GENRE J-POP #TITLE My Love Song #BPM 120 %URL http://www.lm-t.com/ %MYMETA 00AA00GG00ZZ
チャンネル
数字3文字+36進数2文字+":"で始まる行は「チャンネル」として解析します。最初の数字は小節番号、 続く36進数はチャンネル番号を表し、":"の後の記述は当該小節・チャンネルのデータを表します。 チャンネルデータの記述形式はBMS仕様によって定められているため、仕様に違反する記述をした場合、当該チャンネルは 解析エラーとして報告されます。
一般的にチャンネルは小節番号の若い順で記述されますが、小節番号は前後しても構いません。ただし、BMSの可読性が 著しく低下するので小節番号順に記述することが推奨されます。
チャンネルの記述例は以下の通りです。01002:1.5 0880A:00AB00CD00EF00GH 123ZZ:String data channel
エラーハンドリングについて
通常、BMSの読み込みにおいてエラー行を検出した場合はその行を無視し、読み込みを続行することがほとんどです。 アプリケーションによっては、特定のエラーを検出した場合例外的に読み込みを中止し、読み込みエラーとして扱いたい ケースがあります。そのような場合はsetHandler(BmsLoadHandler)
でハンドラを登録し、発生したエラーに応じて 読み込みの続行・中止を選択することが できます。発生したエラーを蓄積し、エラーをユーザーに報告するようなケースも エラーハンドリングを行うことで解決できます。詳細はBmsLoadHandler
を参照してください。拡張したBMSコンテンツオブジェクトを読み込みたい場合
アプリケーションによっては拡張したBMSコンテンツオブジェクト(BmsContent
)を読み込みたいケースが存在します。BmsLoader
では読み込み時に、生成するBMSコンテンツオブジェクトを決定することができるようになっています。setHandler(BmsLoadHandler)
で設定したハンドラのBmsLoadHandler.createContent(BmsSpec)
を オーバーライドすることによりアプリケーションで独自拡張したBMSコンテンツオブジェクトを返すことができます。BOM付きUTF-8で記録されたBMSの読み込みについて
外部データにBOM(Byte Order Mark)が付与された場合でも正常に読み込むことはできますが、現バージョンのBMSライブラリで 読み込めるのはリトルエンディアンの場合のみです。ビッグエンディアンで記録された外部データはサポートしていません。- 関連項目:
BmsLoadHandler
,BmsScriptError
-
-
フィールドの概要
フィールド 修飾子とタイプ フィールド 説明 static BmsLoadHandler
DEFAULT_HANDLER
BMSローダのデフォルトハンドラです。
-
コンストラクタの概要
コンストラクタ コンストラクタ 説明 BmsLoader()
BmsLoaderオブジェクトを構築します。
-
メソッドの概要
すべてのメソッド インスタンス・メソッド concreteメソッド 修飾子とタイプ メソッド 説明 BmsContent
load(byte[] bms)
BMSコンテンツを読み込みます。BmsContent
load(File bms)
BMSコンテンツを読み込みます。BmsContent
load(InputStream bms)
BMSコンテンツを読み込みます。BmsContent
load(Reader bms)
BMSコンテンツを読み込みます。BmsContent
load(String bms)
BMSコンテンツを読み込みます。BmsContent
load(Path bms)
BMSコンテンツを読み込みます。BmsLoader
setAllowRedefine(boolean isAllow)
メタ情報・重複不可チャンネルの再定義を検出した場合のデータ上書きを許可するかどうかを設定します。BmsLoader
setFixSpecViolation(boolean isFix)
BMSライブラリの定める仕様に違反した値を自動的に仕様範囲内に丸め込むかどうかを設定します。BmsLoader
setHandler(BmsLoadHandler handler)
BMS読み込みハンドラを設定します。BmsLoader
setIgnoreUnknownChannel(boolean isIgnore)
不明なチャンネルを無視するかどうかを設定します。BmsLoader
setIgnoreUnknownMeta(boolean isIgnore)
不明なメタ情報を無視するかどうかを設定します。BmsLoader
setIgnoreWrongData(boolean isIgnore)
不正なデータを無視するかどうかを設定します。BmsLoader
setSkipReadTimeline(boolean isSkip)
タイムラインの読み込みをスキップするかどうかを設定します。BmsLoader
setSpec(BmsSpec spec)
読み込み対象BMSのBMS仕様を設定します。BmsLoader
setSyntaxErrorEnable(boolean isEnable)
構文エラーの有効状態を設定します。
-
-
-
フィールドの詳細
-
DEFAULT_HANDLER
public static final BmsLoadHandler DEFAULT_HANDLER
BMSローダのデフォルトハンドラです。具体的な振る舞いはBmsLoadHandler
を参照してください。
-
-
メソッドの詳細
-
setSpec
public final BmsLoader setSpec(BmsSpec spec)
読み込み対象BMSのBMS仕様を設定します。ローダーは設定されたBMS仕様に従ってBMSの構文を解析します。
- パラメータ:
spec
- BMS仕様- 戻り値:
- このオブジェクトのインスタンス
-
setHandler
public final BmsLoader setHandler(BmsLoadHandler handler)
BMS読み込みハンドラを設定します。デフォルトでは
DEFAULT_HANDLER
が設定されています。BMS読み込み時の振る舞いを変えたい場合は 実装をカスタマイズしたBmsLoadHandler
オブジェクトを設定してください。nullを設定することは出来ません。nullにした状態で
load(java.io.File)
メソッドを呼び出すと例外がスローされます。- パラメータ:
handler
- BMS読み込みハンドラ- 戻り値:
- このオブジェクトのインスタンス
-
setSyntaxErrorEnable
public final BmsLoader setSyntaxErrorEnable(boolean isEnable)
構文エラーの有効状態を設定します。BMSでは、メタ情報・チャンネル定義以外の記述は全て無視される仕様になっています。BMS内での不要・不正な記述を 防ぐために、メタ情報・チャンネル定義と認識されない全ての記述を構文エラーとしたい場合に当メソッドを使用します。
構文エラーを有効にした状態でメタ情報・チャンネル定義以外の記述を検出すると、BMS読み込みハンドラにて解析エラーを 通知するようになります。通知メソッドから解析中止が返されるとBMS解析はエラーとなります。
この設定は、複数行コメントが終了しない状態でBMSの読み込みが終了した場合(
BmsErrorType.COMMENT_NOT_CLOSED
)、 およびsetHandler(BmsLoadHandler)
で設定したハンドラのBmsLoadHandler.testContent(BmsContent)
が検査失敗を返した場合(BmsErrorType.TEST_CONTENT
)にも適用されます。デフォルトでは構文エラーは「無効」になっています。
- パラメータ:
isEnable
- 構文エラーの有効状態- 戻り値:
- このオブジェクトのインスタンス
-
setFixSpecViolation
public final BmsLoader setFixSpecViolation(boolean isFix)
BMSライブラリの定める仕様に違反した値を自動的に仕様範囲内に丸め込むかどうかを設定します。この設定を有効にすることで訂正される値とは、「初期BPM」「小節長」「BPM変更用のBPM」「譜面停止時間」を指します。 それぞれの値の許容範囲は
BmsSpec
を参照してください。この設定のデフォルト値は false です。BMSライブラリ仕様の違反を検出するとローダーに設定された
BmsLoadHandler
に対してエラー通知を行います。その際のエラー種別はBmsErrorType.SPEC_VIOLATION
となります。通常、BMSライブラリの仕様違反となる値は非常に極端な値となっており、値を訂正したとしても当該楽曲の再生には 大きな影響がない場合がほとんどですが、値の使い方次第では楽曲の構成を大きく崩してしまう可能性があります。そのような ケースが許容されない場合には仕様違反の訂正は行わず、当該楽曲の読み込みはエラーとして扱うべきです。
この設定を有効にして読み込まれたBMSは定義上とは異なるデータとして読み込まれますので、
BmsContent.generateHash()
が生成する値にも影響を及ぼします。デフォルトではこの設定は「有効」になっています。
- パラメータ:
isFix
- 仕様違反訂正の有効状態- 戻り値:
- このオブジェクトのインスタンス
-
setAllowRedefine
public final BmsLoader setAllowRedefine(boolean isAllow)
メタ情報・重複不可チャンネルの再定義を検出した場合のデータ上書きを許可するかどうかを設定します。データ上書きを許可すると、先に定義されたメタ情報、または同じ小節の重複不可チャンネルデータを上書きするようになります。 メタ情報は単体メタ情報(
BmsUnit.SINGLE
)と定義済みの索引付きメタ情報(BmsUnit.INDEXED
)が対象です。 重複不可チャンネルでは、例えば以下のような定義を行った場合に上の行の定義は完全に上書きされ、 存在しなかったものとして処理されます。#003XY:11001100 ;上書きされ、無かったことになる #003XY:22002222 ;上書きされ、無かったことになる #003XY:00330033 ;この行のみが有効になる
この設定は値型・配列型チャンネルの両方に適用されます。
再定義が不許可の状態でメタ情報・重複不可チャンネルの再定義が検出された場合、再定義された行はエラーとして処理され、 BMSコンテンツ読み込みハンドラの
BmsLoadHandler.parseError(BmsScriptError)
が呼び出されます。 エラーはBmsErrorType.REDEFINE
として通知されます。- パラメータ:
isAllow
- 再定義の許可有無- 戻り値:
- このオブジェクトのインスタンス
-
setIgnoreUnknownMeta
public final BmsLoader setIgnoreUnknownMeta(boolean isIgnore)
不明なメタ情報を無視するかどうかを設定します。無視すると、BMS解析はエラーにならず不明メタ情報を読み飛ばして解析を続行するようになります。
具体的には、
setHandler(BmsLoadHandler)
で設定したハンドラのBmsLoadHandler.parseError(BmsScriptError)
にBmsErrorType.UNKNOWN_META
のエラーが一切通知されなくなります。デフォルトではこの設定は「有効」になっています。
- パラメータ:
isIgnore
- 不明メタ情報を無視するかどうか- 戻り値:
- このオブジェクトのインスタンス
-
setIgnoreUnknownChannel
public final BmsLoader setIgnoreUnknownChannel(boolean isIgnore)
不明なチャンネルを無視するかどうかを設定します。無視すると、BMS解析はエラーにならず不明チャンネルを読み飛ばして解析を続行するようになります。
具体的には、
setHandler(BmsLoadHandler)
で設定したハンドラのBmsLoadHandler.parseError(BmsScriptError)
にBmsErrorType.UNKNOWN_CHANNEL
のエラーが一切通知されなくなります。デフォルトではこの設定は「有効」になっています。
- パラメータ:
isIgnore
- 不明チャンネルを無視するかどうか- 戻り値:
- このオブジェクトのインスタンス
-
setIgnoreWrongData
public final BmsLoader setIgnoreWrongData(boolean isIgnore)
不正なデータを無視するかどうかを設定します。無視すると、BMS解析はエラーにならず不正データ定義のあったメタ情報・チャンネルを読み飛ばして解析を 続行するようになります。
具体的には、
setHandler(BmsLoadHandler)
で設定したハンドラのBmsLoadHandler.parseError(BmsScriptError)
にBmsErrorType.WRONG_DATA
のエラーが一切通知されなくなります。デフォルトではこの設定は「有効」になっています。
- パラメータ:
isIgnore
- 不正データを無視するかどうか- 戻り値:
- このオブジェクトのインスタンス
-
setSkipReadTimeline
public final BmsLoader setSkipReadTimeline(boolean isSkip)
タイムラインの読み込みをスキップするかどうかを設定します。この設定を有効にするとタイムラインの定義を読み飛ばすようになり、BMSコンテンツに小節データとノートが 含まれなくなります。つまり、BMSコンテンツに取り込まれるのはBMS宣言とメタ情報のみなることを意味します。
読み込み対象のBMSに含まれるメタ情報のみを参照したい場合は、この設定を有効にすることで 読み込み処理のパフォーマンス向上が期待できます。
タイムラインの読み込みをスキップする場合、タイムライン(チャンネル定義)の行の小節番号とチャンネル番号定義の 書式が正しければ、誤った値(
BmsErrorType.WRONG_DATA
になる状態)を定義していたとしてもスキップされます。 ただし、小節番号、チャンネル番号のいずれかが誤った書式で定義されていた場合、その行はスキップされず 構文エラー(BmsErrorType.SYNTAX
)として扱われます。デフォルトではこの設定は「無効」になっています。
- パラメータ:
isSkip
- タイムラインの読み込みをスキップするかどうか- 戻り値:
- このオブジェクトのインスタンス
-
load
public final BmsContent load(File bms) throws BmsException
BMSコンテンツを読み込みます。BMSコンテンツは指定されたファイルから読み込みます。
読み込み処理の詳細は
load(String)
を参照してください。- パラメータ:
bms
- BMSファイル- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
-load(String)
を参照
-
load
public final BmsContent load(Path bms) throws BmsException
BMSコンテンツを読み込みます。BMSコンテンツは指定されたパスが示すファイルから読み込みます。
読み込み処理の詳細は
load(String)
を参照してください。- パラメータ:
bms
- BMSファイルのパス- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
-load(String)
を参照
-
load
public final BmsContent load(InputStream bms) throws BmsException
BMSコンテンツを読み込みます。BMSコンテンツは指定された入力ストリームから読み込みます。
読み込み処理の詳細は
load(String)
を参照してください。- パラメータ:
bms
- BMSの入力ストリーム- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
-load(String)
を参照
-
load
public final BmsContent load(byte[] bms) throws BmsException
BMSコンテンツを読み込みます。BMSコンテンツは指定されたバイト配列から読み込みます。
読み込み処理の詳細は
load(String)
を参照してください。- パラメータ:
bms
- BMSのバイト配列- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
-load(String)
を参照
-
load
public final BmsContent load(Reader bms) throws BmsException
BMSコンテンツを読み込みます。File
/Path
/InputStream
/ byte[]が入力となる場合、BmsLoader
では最初に先頭行のBMS宣言を解析します。BMS宣言が存在し、encoding要素が存在する場合はその設定値から 使用する文字セットを解決します。以後の読み込みは当該文字セットを用いて文字列をデコードし、BMS解析を行います。 ただし、入力にBOM(Byte Order Mark)が付いている場合はUTF-8で入力をデコードし、encoding要素は "UTF-8" に設定・上書きします。上記の条件に該当しない場合は全て
BmsSpec.getStandardCharset()
で取得できる文字セットを用いて BMSをデコードし、解析を行います。BMS宣言は左から順に解析し、その順番でBMSコンテンツにセットされます。また、BMS解析の動作仕様は概ね以下の通りです。
- 行頭の半角スペースおよびタブは無視されます。
- 半角スペースおよびタブのみの行は空行として読み飛ばします。
- 改行コードは<CR>, <LF>, <CR><LF>を自動認識します。
- 先頭行において、";bms? "で始まる場合はBMS宣言として認識されます。
- ";"、"*"、または"//"で始まる行はコメント行として認識されます。(単一行コメント)
- "/*"で始まる行は複数行コメントの開始行として認識されます。以降、行末に"* /"が出現するまでの 行は全てコメントとして認識されます。
- 複数行コメントが閉じられずにBMS解析が終了した場合、エラーハンドラにて
BmsErrorType.COMMENT_NOT_CLOSED
が通知されます。 - "#"または"%"で始まり、1文字目がアルファベットで始まる行をメタ情報の定義と見なします。
- "#"に続き3文字の半角数字で始まり、次に2文字の半角英数字、更にその次が":"で始まる行をチャンネルデータの定義と見なします。
- 以上のパターンに該当しない行は構文エラーとし、エラーハンドラにて
BmsErrorType.SYNTAX
が通知されます。
メタ情報解析について
- メタ情報の値は、文字列の右側の半角空白文字は消去されます。
- 索引付きメタ情報は、名称の末端文字2文字を36進数値と見なしてその値をインデックス値とし、残りの文字を名称として扱います。
- 索引付きメタ情報のインデックス値が36進数値でない場合、エラーハンドラにて
BmsErrorType.UNKNOWN_META
が通知されます。 - BMS仕様に規定されていない名称を検出した場合、エラーハンドラにて
BmsErrorType.UNKNOWN_META
が通知されます。 - メタ情報の値がBMS仕様に規定されたデータ型の記述書式に適合しない場合、エラーハンドラにて
BmsErrorType.WRONG_DATA
が通知されます。
チャンネル解析について
- チャンネル番号がBMS仕様に未定義の場合、エラーハンドラにて
BmsErrorType.UNKNOWN_CHANNEL
が通知されます。 - 以下のケースを検出した場合、エラーハンドラにて
BmsErrorType.WRONG_DATA
が通知されます。- チャンネルに定義されたデータの記述書式がBMS仕様に違反している場合。
- データ重複許可チャンネルの同小節番号内にて
BmsSpec.CHINDEX_MAX
+1個を超えるデータ定義を検出した場合。 - 配列型チャンネルデータの配列要素数が当該小節の刻み総数より多い場合。
- 配列型チャンネルデータの配列要素数が0。
- パラメータ:
bms
- BMSのReader- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
- BMS仕様が設定されていない: Cause IllegalStateExceptionBmsException
- ハンドラが設定されていない: Cause IllegalStateExceptionBmsLoadException
- ハンドラ(BmsLoadHandler.parseError(com.lmt.lib.bms.BmsScriptError)
)がfalseを返した
-
load
public final BmsContent load(String bms) throws BmsException
BMSコンテンツを読み込みます。BmsLoaderでは、最初に先頭行のBMS宣言を解析します。BMS宣言が存在し、encoding要素が存在する場合はその設定値から 使用する文字セットを解決します。
- パラメータ:
bms
- BMSの文字列- 戻り値:
- BMSコンテンツ
- 例外:
BmsException
- bmsがnull: Cause NullPointerExceptionBmsException
- BMS仕様が設定されていない: Cause IllegalStateExceptionBmsException
- BMS読み込みハンドラが設定されていない: Cause IllegalStateExceptionBmsException
- ハンドラが設定されていない: Cause IllegalStateExceptionBmsException
- BMS宣言にてencoding指定時、指定の文字セットが未知: Cause ExceptionBmsLoadException
- ハンドラ(BmsLoadHandler.parseError(com.lmt.lib.bms.BmsScriptError)
)がfalseを返した
-
-