# 機能設計書 48-Gate

## 概要

本ドキュメントは、K-ShootMania のプレイ画面におけるGate（ゲート）エフェクト機能の設計を記述する。regawo.dllを使用し、4/8/12/16/24/32分音符単位のゲートエフェクトを楽曲にリアルタイムで適用する機能である。

### 本機能の処理概要

**業務上の目的・背景**：Gateは音楽の音量を周期的にON/OFFすることでリズミカルな刻み効果を生み出すエフェクトである。FXロングノートに割り当てられ、プレイヤーがFXボタンを押下している間にエフェクトが適用される。RetriggerがWaveformの一部を繰り返すのに対し、GateはWaveform全体の音量を周期的にカットする点が異なる。

**機能の利用シーン**：プレイ画面でFXロングノートにGateエフェクト（FX_GA4〜FX_GA32）が割り当てられている場合、ノート押下中にregawo.dllのVSTプラグインとしてゲートエフェクトが適用される。

**主要な処理内容**：
1. applyVSTEffects関数でfl_Gate=1の場合、regawo.dllをVSTプラグインとしてロード（BASS_VST_ChannelSetDSP）
2. 初期パラメータ設定: パラメータ1=0.0, 7=0.50（ゲートレシオ）, 8=0.90（ゲートスムース）, 10=500/22050（LPF周波数）, 11=20000/22050（HPF周波数）, 12=1.414/50（Q値）, 13=0.80（ゲートミックス）, 29=0.0（ByPassだが初期値は0で有効状態を示す）
3. FXエフェクト開始時: パラメータ6にBPMベースの周期値を設定し、gate_nowを更新
4. 周期計算: `60.0*4.0*1000.0/bpmfx/10.0/gate_now`
5. トリガー更新: 1小節間隔（c2bnow変化時）でパラメータ19にタイミング差分を設定
6. FXエフェクト終了時: パラメータ6を0にし、gate_now=0にリセット

**関連システム・外部連携**：regawo.dll（VSTプラグイン）、BASS Audio Library、bass_vst.dll

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | regawo.dllによる4/8/12/16/24/32分音符単位のゲートエフェクト適用 |

## 機能種別

リアルタイムオーディオエフェクト処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| fl_Gate | 整数 | Yes | Gateエフェクト使用フラグ | 0または1 |
| feffectnow | 整数配列 | Yes | L/R各レーザーの現在FXエフェクトID | FX_GA4〜FX_GA32の範囲 |
| feffectparam | 整数配列 | Yes | FXエフェクトのパラメータ（音符分割数） | 4,8,12,16,24,32 |
| bpmfx | 整数 | Yes | 現在のBPM*1000 | 正の整数 |
| gate_now | 整数 | No | 現在のGate音符分割数 | 0=無効 |

### 入力データソース

- 譜面ファイル（.ksh）のFXロングノート定義
- processAudioEffects関数でのFXエフェクト状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| hFX_Gate | 整数 | GateのVSTハンドル |
| gate_now | 整数 | 現在のGate分割数 |

### 出力先

- BASSオーディオエンジンのVSTエフェクトチェーン

## 処理フロー

### 処理シーケンス

```
1. VSTプラグインロード（applyVSTEffects）
   └─ hFX_Gate = BASS_VST_ChannelSetDSP(mid.0, regawo.dll, 0, 17)
   └─ パラメータ初期設定: 1=0.0, 7=0.50, 8=0.90, 10-13=フィルターパラメータ, 29=0.0
2. BPM変化時の周期更新
   └─ gate_now>0の場合: パラメータ6 = 60*4*1000/bpmfx/10/gate_now
3. トリガー更新（1小節間隔）
   └─ c2bnow変化時かつc2bnow_50ms変化時: パラメータ19にタイミング差分dstatを設定
4. FXエフェクト開始（FX_GA4〜FX_GA32）
   └─ パラメータ6 = BPMベース周期値, gate_now = feffectparam.cnt
5. FXエフェクト終了
   └─ パラメータ6 = 0, gate_now = 0
```

### フローチャート

```mermaid
flowchart TD
    A[applyVSTEffects: regawo.dllロード priority=17] --> B[初期パラメータ設定]
    B --> C[毎フレーム: processAudioEffects]
    C --> D{BPM変化?}
    D -->|Yes| E[パラメータ6周期更新]
    D -->|No| F{c2bnow変化?}
    E --> F
    F -->|Yes| G[パラメータ19にdstat設定]
    F -->|No| H{feffectnow変化?}
    G --> H
    H -->|開始| I[パラメータ6=周期, gate_now設定]
    H -->|終了| J[パラメータ6=0, gate_now=0]
    H -->|変化なし| K[次フレームへ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | 周期計算 | period = 60*4*1000/bpmfx/10/gate_now | gate_now > 0 |
| BR-48-02 | VSTプライオリティ | Gateのプライオリティは17 | applyVSTEffects |
| BR-48-03 | Wobbleと共用 | hFX_GateはWobbleエフェクト（パラメータ9）とも共用される | パラメータ6=Gate周期, パラメータ9=Wobble周期 |
| BR-48-04 | トリガー間隔 | 1小節間隔（c2bnow変化）でトリガー更新 | processAudioEffects |

### 計算ロジック

- Gate周期（パラメータ6）: `60.0 * 4.0 * 1000.0 / bpmfx / 10.0 / gate_now`
- トリガータイミング差分: `dstat = c2tf(拍頭カウント位置) - double(t + laserdelay0 + tfx_diff)`
- パラメータ19への設定: `maxf(minf(dstat / 10000.0, 1.0), 0.0)`

## データベース操作仕様

本機能ではデータベース操作は発生しない。

## エラー処理

### エラーケース一覧

BASS_VST_SetParam_Rはエラー時に最大5回リトライする。

### リトライ仕様

BASS_VST_SetParam_R内で最大5回リトライ。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- VSTプラグインのDSP処理が音切れを起こさないこと

## セキュリティ考慮事項

特になし。

## 備考

- GateとWobbleはregawo.dllの同一インスタンス（hFX_Gate）を共有する。Gateはパラメータ6で周期を制御し、Wobbleはパラメータ9で周期を制御する
- ByPass（パラメータ29）は初期値0.0だが、コメントに「GateとWobbleが切り替わるためByPassにすると上手くいかない」とある（260行目）
- FX_GA4=4分音符, FX_GA8=8分音符, FX_GA12=12分音符, FX_GA16=16分音符, FX_GA24=24分音符, FX_GA32=32分音符

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: VSTプラグインロードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | applyVSTEffects関数内のGate初期化（251-261行目） |

**主要処理フロー**:
- **252行目**: `hFX_Gate=BASS_VST_ChannelSetDSP(mid.0,dir_default+"\\lib\\regawo.dll",0,17)` でVSTロード
- **253-260行目**: 初期パラメータ設定（パラメータ1,7,8,10,11,12,13,29）

#### Step 2: BPM連動・トリガー更新を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | BPM変化時処理（408-413行目）とトリガー更新（448-450行目） |

**主要処理フロー**:
- **408-410行目**: BPM変化時にgate_now>0の場合、パラメータ6を再計算
- **448-450行目**: c2bnow_50ms変化時にパラメータ19にdstatを設定

#### Step 3: FXエフェクト切替を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | Gate ON/OFF処理（627-636行目, 719-723行目） |

**主要処理フロー**:
- **627-631行目**: Gate終了時: パラメータ6=0, gate_now=0
- **632-636行目**: 他のレーザーでGateが継続する場合: パラメータ6を他レーザーのパラメータで再設定
- **719-723行目**: Gate開始時: パラメータ6に周期値設定, gate_now設定

### プログラム呼び出し階層図

```
start_play
    +-- applyVSTEffects
    |       +-- BASS_VST_ChannelSetDSP(regawo.dll, priority=17) -> hFX_Gate
    |       +-- 初期パラメータ設定（1,7,8,10-13,29）
    |
    +-- on_update_play (毎フレーム)
            +-- processAudioEffects
                    +-- BPM変化: パラメータ6再計算
                    +-- c2bnow変化: パラメータ19更新
                    +-- feffectnow変化: Gate ON/OFF切替
```

### データフロー図

```
[入力]                      [処理]                           [出力]

譜面FXロングノート          feffectnow判定                   regawo.dll VSTパラメータ
  FX_GA4-FX_GA32 -------->  Gate ON/OFF

BPM値                       周期計算                         パラメータ6(周期)
  bpmfx ------------------>  60*4*1000/bpmfx/10/gate_now     パラメータ19(トリガー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | ソース | applyVSTEffects, processAudioEffects |
| bass_vst.as | `src/bass_vst.as` | ソース | BASS_VST_ChannelSetDSP, BASS_VST_SetParam_R APIバインディング |
| regawo.dll | `lib/regawo.dll` | DLL | Retrigger/Gate/Echo/Wobble VSTプラグイン |
