# 機能設計書 51-BitCrusher

## 概要

本ドキュメントは、K-ShootMania（KSM）のプレイ画面におけるBitCrusherオーディオエフェクトの設計を記述する。BitCrusherは、音声信号のビット深度を意図的に下げることでデジタルノイズ的なサウンドを生成するディストーション系エフェクトである。

### 本機能の処理概要

BitCrusherエフェクトは、FXノートのロング区間で発動し、bitc.dllを通じてオーディオストリームにリアルタイムでビットクラッシュ処理を適用する。

**業務上の目的・背景**：音楽ゲームにおいて楽曲演出の幅を広げるため、デジタルノイズ・ローファイ効果をリアルタイムに楽曲へ適用する必要がある。BitCrusherは譜面制作者が楽曲の特定区間にデジタルグリッチ的な音響効果を付与するために使用される。

**機能の利用シーン**：プレイ画面においてFXノートのロング区間でBitCrusherが指定されている場合、レーザー操作またはFXボタン押下に連動してエフェクトが適用される。また、レーザーフィルターとしても使用可能で、レーザー位置に応じてreduction値が変化する。

**主要な処理内容**：
1. 譜面読み込み時にBitCrusherエフェクトの使用フラグ（fl_BitC）を設定
2. VSTプラグインとしてbitc.dllをオーディオストリームにロード
3. FXノート区間に応じてreductionパラメータ（ビット深度削減量）を設定
4. エフェクトON/OFF時のByPass制御
5. レーザーフィルター使用時のreduction値のリアルタイム補間

**関連システム・外部連携**：BASS Audio Library（bass.dll）のVSTプラグインホスティング機能（bass_vst.dll）を通じてbitc.dllを制御する。

**権限による制御**：特になし。譜面データに基づいて自動的に適用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | bitc.dllによるビットクラッシャーエフェクト適用 |

## 機能種別

リアルタイム音声処理（VSTエフェクト適用）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| reduction | FXDEF_SAMPLE (float) | Yes | ビット深度削減量（0〜128） | 0.0〜128.0の範囲 |
| mix | FXDEF_RATE (float) | Yes | エフェクトのミックス率 | 0.0〜1.0の範囲 |
| feffectparam | int | Yes | FXノート区間のreduction値 | 譜面定義値 |

### 入力データソース

- KSH譜面ファイルのFXノート定義（fx-l=, fx-r=フィールド）
- ユーザー定義エフェクト（#define_fx / #define_filter）
- レーザーフィルター設定（filtertype=5でBitCrusher使用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 音声ストリーム | audio stream | BitCrusher処理が適用されたオーディオ出力 |
| hFX_BitC | int | メインストリーム用VSTエフェクトハンドル |
| hBitCFX | int | レーザーフィルター用VSTエフェクトハンドル |

### 出力先

オーディオ出力デバイス（BASS Audio Libraryのオーディオストリーム経由）

## 処理フロー

### 処理シーケンス

```
1. 譜面読み込みフェーズ（play_chart_load.hsp）
   └─ FXノート定義からFX_BITC（定数値14）を検出し fl_BitC=1 を設定
2. VSTエフェクト初期化フェーズ（applyVSTEffects）
   └─ fl_BitC=1の場合、BASS_VST_ChannelSetDSP でbitc.dllをロード
   └─ 初期reduction値を0に設定（BASS_VST_SetParam_R hFX_BitC,0,0）
3. リアルタイム処理フェーズ（processAudioEffects）
   └─ FXノート区間の切替時にreduction値を設定
   └─ エフェクトON: BASS_VST_SetParam_R hFX_BitC,0,feffectparam/128.0
   └─ エフェクトOFF: BASS_VST_SetParam_R hFX_BitC,0,0
4. レーザーフィルター処理（filtertype=5時）
   └─ レーザー位置（pdstat）に応じたreduction値の補間
   └─ pdstat*30.0/128.0 の計算式でVSTパラメータを設定
5. SwitchAudio対応
   └─ SwitchAudioストリームにもhBitCFX_swとして同一処理を適用
```

### フローチャート

```mermaid
flowchart TD
    A[譜面読み込み] --> B{FX_BITC定義あり?}
    B -->|Yes| C[fl_BitC=1を設定]
    B -->|No| D[BitCrusher未使用]
    C --> E[applyVSTEffects: bitc.dllロード]
    E --> F[processAudioEffects: 毎フレーム処理]
    F --> G{FXノート区間?}
    G -->|ON| H[reduction値設定]
    G -->|OFF| I[reduction=0]
    H --> J{レーザーフィルター?}
    J -->|Yes| K[pdstat基準で補間]
    J -->|No| L[feffectparam/128.0を設定]
    K --> F
    L --> F
    I --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-1 | エフェクト排他制御 | L/Rのレーザーそれぞれに独立してエフェクトを割り当て、両方がBitCrusherでない場合はOFF時にreduction=0にリセット | feffectp.cnt=FX_BITC かつ feffectnow.(1-cnt)!=FX_BITC |
| BR-51-2 | パラメータ範囲制限 | reduction値は0〜128の範囲、VSTパラメータは0.0〜1.0に正規化 | 常時 |
| BR-51-3 | レーザーフィルター連動 | filtertype=5の場合、レーザー位置に応じてreduction値が連続変化 | peffect=1 かつ filtertype=5 |
| BR-51-4 | ByPass制御 | ユーザー定義BitCrusherの場合、VSTパラメータ29（ByPass）で有効/無効を制御 | feffect=1時のユーザー定義FX |

### 計算ロジック

- **FXノートでの適用**: `BASS_VST_SetParam_R hFX_BitC, 0, double(feffectparam.cnt) / 128.0`
- **レーザーフィルターでの適用**: `BASS_VST_SetParam_R hBitCFX.cnt, 0, pdstat * 30.0 / 128.0`
- **ユーザー定義エフェクト**: `BASS_VST_SetParam_R hFX_User.cnt, 0, maxf(minf(value/128.0, 1.0), 0.0)`

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

### 操作別データベース影響一覧

本機能はデータベースを使用しない。すべてインメモリ処理である。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DLLロード失敗 | bitc.dllが存在しない場合 | BASS_VST_ChannelSetDSPが-1を返し、エフェクト未適用で続行 |
| - | パラメータ範囲外 | reduction値が不正な場合 | maxf/minfで0.0〜1.0にクランプ |

### リトライ仕様

リトライ処理は行わない。DLLロード失敗時はエフェクト未適用で続行する。

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

トランザクション管理は不要。リアルタイムオーディオ処理のためフレーム単位で処理される。

## パフォーマンス要件

- オーディオバッファ更新周期（updateperiod）内に処理を完了する必要がある
- VSTエフェクトの優先度: 19（他のエフェクトとの処理順序制御）
- レーザーフィルター使用時は `ts_bass > max(updateperiod/5, 1)` の条件でパラメータ更新

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

外部DLL（bitc.dll）を読み込むため、DLLの改竄に注意が必要。libディレクトリから相対パスで読み込む。

## 備考

- BitCrusherのVST DLL識別名: "bitc.dll"
- エフェクト定数値: FX_BITC = 14, FXDEF_FXTYPE_BITC = 4
- VSTパラメータ0がreduction、パラメータ1がmix
- レーザーフィルターとFXノートエフェクトの両方で使用可能

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

BitCrusherのエフェクト定義テーブルを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fxdef.hsp | `src/audio/fxdef.hsp` | BitCrusherの定数定義とパラメータテーブル |

**読解のコツ**: HSP（Hot Soup Processor）では配列の多次元アクセスに `.` を使用する。`fxdef_name.0.FXDEF_FXTYPE_BITC` は2次元配列の`[0][4]`要素にアクセスしている。

- **17行目**: `#define FX_BITC 14` - FXノート用のBitCrusherエフェクト定数
- **40行目**: `#define FXDEF_FXTYPE_BITC 4` - エフェクトタイプ定義
- **136-146行目**: BitCrusherのパラメータテーブル定義（prmnum=2, パラメータはreductionとmix）
- **144行目**: `fxdef_dllname.FXDEF_FXTYPE_BITC = "bitc.dll"` - 使用DLL名

#### Step 2: エントリーポイントを理解する

譜面読み込み時のBitCrusherフラグ設定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | 譜面解析時のBitCrusherフラグ設定 |

**主要処理フロー**:
1. **918行目**: `fl_BitC=0` - 初期化
2. **1153-1154行目**: FXノートのエフェクト定義がBitCrusherの場合 `fx.fxnum.2=FX_BITC` を設定し `fl_BitC=1`
3. **1064行目**: ユーザー定義エフェクトの場合 `userfx_params.cnt.0=FXDEF_FXTYPE_BITC` を判定

#### Step 3: VSTエフェクト初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | VSTプラグインのロードとパラメータ初期化 |

**主要処理フロー**:
- **241-243行目**: `applyVSTEffects`内で `fl_BitC=1` の場合 bitc.dll をロードし初期reduction=0に設定
- **208行目**: SwitchAudio用のBitCrusherハンドル `hBitCFX_sw` も同様に初期化

#### Step 4: リアルタイム処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | processAudioEffectsでの毎フレーム処理 |

**主要処理フロー**:
- **605-609行目**: FXノート区間終了時のBitCrusherリセット処理
- **705-706行目**: FXノート区間開始時のreduction値設定
- **983-996行目**: レーザーフィルター(filtertype=5)でのpdstat連動BitCrusher処理

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

```
play_init (play_init.hsp)
    |
    +-- loadKSHChartFile (play_chart_load.hsp)
    |       +-- fl_BitC=1 設定
    |       +-- FX_BITC エフェクト配列登録
    |
    +-- applyVSTEffects (play_audio_effects.hsp)
    |       +-- BASS_VST_ChannelSetDSP(bitc.dll) -> hFX_BitC
    |       +-- BASS_VST_SetParam_R(hFX_BitC, 0, 0)
    |
    +-- play_update -> processAudioEffects (play_audio_effects.hsp)
            +-- FXノートエフェクト切替
            |       +-- ON:  BASS_VST_SetParam_R(hFX_BitC, 0, param/128.0)
            |       +-- OFF: BASS_VST_SetParam_R(hFX_BitC, 0, 0)
            +-- レーザーフィルター処理
                    +-- BASS_VST_SetParam_R(hBitCFX, 0, pdstat*30/128)
```

### データフロー図

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

KSH譜面ファイル ---------> 譜面解析(fl_BitC設定) ---------> エフェクトフラグ
                              |
FXノート区間 ------------> processAudioEffects -----------> VSTパラメータ設定
  (feffectparam)              |                                |
                              v                                v
レーザー位置 ------------> pdstat計算 --------------------> bitc.dll
  (analogpos)                                                  |
                                                               v
音楽ストリーム ---------> BASS Audio Library --------------> スピーカー出力
  (mid.0)                   (bitc.dll適用済み)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fxdef.hsp | `src/audio/fxdef.hsp` | ソース | エフェクト定義テーブル（定数・パラメータ定義） |
| play_audio_effects.hsp | `src/scene/play/play_audio_effects.hsp` | ソース | VSTエフェクトの初期化・リアルタイム処理 |
| play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | ソース | 譜面読み込み時のエフェクトフラグ設定 |
| bitc.dll | `lib/bitc.dll` | 外部DLL | BitCrusher VSTプラグイン本体 |
| bass_vst.dll | - | 外部DLL | BASS VSTプラグインホスティング |
| bass.dll | - | 外部DLL | BASS Audio Libraryコア |
