機能 #315
完了ノーツレーダー細分化 Phase 2: B分類(パターン認識)サブ軸の新規解析実装
説明
目的¶
#313 で確定した細分化データモデル設計(docs/notes-radar-subdivision-design.md)の Phase 2。NotesRadarCalculator.collectMetrics に per-lane 音符時系列・間隔ヒストグラムを導入し、横方向のパターン認識軸を新規解析で算出する。
親設計: #313。前提: Phase 1 (#314) の伝送・保持・集計縦串。
スコープ(B分類サブ軸)¶
-
PATTERN(新規親):
pattern_randa(乱打)/pattern_jack(縦連)/pattern_trill(トリル)/pattern_kaidan(階段) -
CHORD パターン:
chord_gachioshi(ガチ押し)/chord_denim(デニム)/chord_jika(軸) -
SCRATCH 細分:
scratch_single(単皿)/scratch_ren(連皿)/scratch_complex(皿複合) -
RHYTHM(新規親):
rhythm_24th/rhythm_henpyoshi(変拍子)/rhythm_irregular(不規則間隔) -
NOTES:
notes_density_peak_10s/notes_endgame(終盤)
新規パターン解析プリミティブ(設計 §5)¶
collectMetrics の既存1回走査に同居(追加走査なし、O(notes))。ChartMetrics に per-lane 状態を追加:
-
lastNoteTimeByLane[]/lastScratchTimeByLane[]/ 直近音符 lane 列(K=8 リング)/lastAnyNoteTime/ グローバル間隔ヒストグラム / パターンカウンタ / 10s ピーク Deque(既存 addPeakEvent と同型)。 - 音符ごと:
gap = time - lastNoteTimeByLane[lane]でジャック、直近2音符 lane で階段(単調±1)/トリル(A-B-A)、低同時押し×散らばりで乱打。 - 皿:
lastScratchTimeByLane間隔で連皿/単皿、皿 TL 前後窓の鍵盤で皿複合。 - リズム: 各 TL の BPM から拍長 → 4/8/12/16/24分グリッド命中・off-grid率・エントロピー。
暫定閾値(実データで再調整)¶
jack/trill ≤110ms, stair ≤130ms, 連皿境界180ms, 皿複合窓±250ms, デニム gap≤130ms, ガチ押し size≥4, off-grid 15%, 終盤末尾20%, 10s窓。
本体側の変更接点¶
Phase 1 と同じ縦串(feature/calculator/dto/handler/sqlite/ir)。差分は collectMetrics への per-lane 状態・ヒストグラム・パターンカウンタ追加と、各サブ軸 raw 算出。パターン軸を本体で 0–200 化する場合は anchor 定数を追加(数値は実データ後決め、暫定線形)。
plugin / server 側の責務¶
新 axis_key を EAV に追加保持・集計。新パターン軸の 0–200 anchor テーブルを実データ分布から確定。
テスト方針¶
NotesRadarCalculatorTest を手組み TimeLine で拡張: ジャック/トリル/階段/乱打/連皿/単皿/皿複合/リズム/終盤 の各パターンを既知譜面で計上・境界検証(閾値直上/直下の ON/OFF)、既存6軸値の不変(回帰)。
未解決(実データ後決め)¶
全パターン軸の 0–200 anchor、閾値を固定msかBPM相対か、乱打エントロピー閾値・窓K、皿複合窓と重み、デニム/ガチ押しsize閾値、リズムoff-grid許容、パターン軸rawを本体正規化かserver正規化かの責務分界。