No description
Find a file
2026-07-16 14:01:37 +09:00
.gitignore add notes.keras 2026-07-16 06:06:26 +09:00
generate_notes.py add notes.keras 2026-07-16 06:06:26 +09:00
generate_patterns.py LSTMで時系列に対応 2026-07-16 14:01:37 +09:00
README.md LSTMで時系列に対応 2026-07-16 14:01:37 +09:00
requirements.txt 最初のコミット 2026-07-15 22:23:10 +09:00
tjaf.py 最初のコミット 2026-07-15 22:23:10 +09:00

tjaf-generator

TJA譜面と対応する音声を教師データとして、譜面生成に使う2種類のTensorFlow/Kerasモデルを学習するツールです。

  • generate_patterns.py: 前後の時系列をLSTMで見て、各時刻にーツがあるかを判定する2値分類モデル
  • generate_notes.py: ノーツ位置の音声からノーツ種別(04)を分類するモデル

入力ディレクトリ以下の .tja を再帰的に検索し、音声から抽出したMFCC特徴量で学習します。学習結果は再利用できる .keras ファイルとして保存されます。

必要なもの

  • Python
  • TJA譜面
  • 各TJAの WAVE ヘッダーに対応する音声ファイル

依存パッケージは requirements.txt に固定されています。仮想環境でのインストールを推奨します。

python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

Windowsで仮想環境を有効化する場合は、次を実行してください。

.venv\Scripts\activate

入力データ

TJAと音声は、たとえば次のように配置します。

songs/
├── song-a/
│   ├── chart.tja
│   └── song.ogg
└── song-b/
    ├── chart.tja
    └── song.wav

TJAの WAVE には、そのTJAからの相対パスまたは絶対パスで音声を指定します。

TITLE:サンプル曲
BPM:120
WAVE:song.ogg
OFFSET:0

COURSE:Oni
LEVEL:5
#START
0010,
1010,
#END

WAVE で指定したファイルが見つからない場合は、TJAと同じディレクトリの main.<WAVEの拡張子> も検索します。TJAの文字コードと改行コードは、読み込み時にUTF-8/LFへ変換されます。

使い方

1. ノーツ位置モデルを生成する

音声の各時間枠を「ーツなし0」または「ーツあり1」に分類するモデルです。MFCCを曲ごとの時系列として固定長シーケンスに分割し、LSTMで前後の文脈を見ながら各フレームを判定します。

python generate_patterns.py ./songs

既定では patterns.keras に保存されます。保存先や学習条件も指定できます。

python generate_patterns.py ./songs \
  --output ./models/patterns.keras \
  --course 3 \
  --epochs 10 \
  --batch-size 64

TJAの空打ち 0 はノーツなし、それ以外の数字はすべてノーツありとして扱います。音声全体の時間枠を学習対象とし、アンダーサンプリングは行いません。クラス重みには、譜面ごとに求めたノーツあり率の全譜面における中央値を使用します。

patterns.keras(任意の時系列長, n-mfcc) の入力を受け取り、各時刻のーツ有無を時系列で出力します。推論時も単発フレームではなく、学習時と同じMFCC列を時系列のまま渡してください。末尾の不足フレームは学習時にパディングされ、損失計算からは除外されます。

2. ノーツ種別モデルを生成する

譜面上の各ーツ位置に対応する音声から、TJAのーツ種別 04 を分類するモデルです。

python generate_notes.py ./songs

既定では notes.keras に保存されます。オプションの指定方法は位置モデルと同じです。

python generate_notes.py ./songs \
  --output ./models/notes.keras \
  --course 3 \
  --epochs 10 \
  --batch-size 64

59 のノーツは学習対象外です。また、空打ち 0 は入力データに含まれますが、損失計算からは除外されます。

オプション

主なオプションは次の通りです。

オプション 既定値 内容
input_dir 必須 TJAを再帰検索する入力ディレクトリ
--output スクリプトごと モデルの保存先
--course 3 学習対象のコース番号
--epochs 4 学習エポック数
--batch-size 32 バッチサイズ
--scale-ms 10 MFCCの時間間隔ミリ秒
--n-mfcc 13 MFCCの次元数
--n-fft 1024 FFTの窓幅
--sequence-length 64 generate_patterns.py のLSTMへ渡す時系列フレーム数
--lstm-units 64 generate_patterns.py のLSTMユニット数

--output の既定値は、generate_patterns.pypatterns.kerasgenerate_notes.pynotes.keras です。

コース番号は次の通りです。

番号 コース
0 Easy
1 Normal
2 Hard
3 Oni
4 Edit / Ura
5 Tower
6 Dan

全引数は各スクリプトの --help でも確認できます。

python generate_patterns.py --help
python generate_notes.py --help

対応している譜面情報

ノーツ時刻の計算では、次の情報を反映します。

  • 共通ヘッダーの BPM(省略時は 120
  • 共通ヘッダーの OFFSET(省略時は 0
  • 譜面中の #BPMCHANGE
  • 譜面中の #MEASURE

上記以外の分岐、スクロール、停止などの命令は、学習時刻の計算には反映されません。

注意事項

  • 読み込めないTJAや音声は、理由を表示してスキップします。
  • 指定したコースが存在しない譜面もスキップします。
  • 同じモデルで推論するときは、学習時と同じ scale-msn-mfccn-fft を使ってMFCCを生成してください。
  • 譜面数や音声の長さに応じて、学習に必要なメモリと時間が増えます。まずは少数の曲と小さなエポック数で動作を確認してください。
  • このリポジトリは学習モデルの生成までを扱います。音声からTJAを出力する推論処理は含まれていません。