# 機能設計書 112-再生・プレビュー

## 概要

本ドキュメントは、K-Shoot MANIA譜面エディタにおける再生・プレビュー機能の設計を記述する。譜面の再生/停止、同期スクロール、半速再生、TICK音、直角音、FXエフェクト、LASERエフェクト、ループ再生の各制御機能を提供する。

### 本機能の処理概要

譜面エディタ上で制作中の譜面をリアルタイムに音声付きで再生し、ノートのタイミングやエフェクトの確認を行う機能群である。

**業務上の目的・背景**：譜面制作者が制作中の譜面の音楽との同期状態やノート配置の妥当性を確認する必要がある。エディタ内で直接再生することで、ゲーム本体を起動せずに素早くフィードバックを得られるようにする。

**機能の利用シーン**：譜面制作中に再生メニューまたはSpaceキーで譜面を再生し、ノートタイミングの確認、エフェクト適用の確認、選択範囲のループ再生による反復確認などに利用される。

**主要な処理内容**：
1. 再生/停止(CMD_PLAY_PLAY): BASS AudioLibraryで楽曲を再生し、BPMに同期してカーソルを移動
2. 同期スクロール(CMD_PLAY_SYNCHRO): 再生中に画面が自動スクロール
3. TICK音(CMD_PLAY_TICK): ノート位置でtick.wav/tick2.wavを再生
4. 直角音(CMD_PLAY_CHOKKAKU): 直角レーザー位置で効果音を再生
5. FXエフェクト(CMD_PLAY_FX): FXノート区間でオーディオエフェクトをプレビュー
6. LASERエフェクト(CMD_PLAY_LASER): レーザー位置でフィルターエフェクトをプレビュー
7. 半速再生(CMD_PLAY_BPMHALF): BPMを半分にして再生
8. ループ再生(CMD_PLAY_LOOPPLAYBACK): 選択範囲を繰り返し再生
9. 音量制御(CMD_PLAY_VOL_100/75/50/25/0): 再生音量の5段階制御

**関連システム・外部連携**：BASS Audio Library(bass.dll)を使用してオーディオストリーム再生・エフェクト適用を行う。VSTエフェクトDLL群によるFXエフェクト処理も含む。

**権限による制御**：権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 譜面エディタ | 主画面 | 再生メニューからの各再生制御操作 |

## 機能種別

メディア再生制御 / オーディオ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmd | int | Yes | 再生コマンドID | CMD_PLAY_PLAY/STOP/SYNCHRO/TICK/FX/LASER/CHOKKAKU/LOOPPLAYBACK/BPMHALF/VOL_* |
| cnowf | int | No | 現在のカーソル位置(内部カウント値) | 再生開始位置として使用 |
| cnowflen | int | No | 選択範囲の長さ | ループ再生の範囲として使用 |

### 入力データソース

- メニュー操作(再生メニュー)
- キーボードショートカット(Spaceキー等)
- 楽曲音声ファイル(OGG/MP3/WAV)
- TICK音ファイル(tick.wav, tick2.wav)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| playingsample | int | 再生中フラグ(0: 停止、1: 再生中) |
| synchro | int | 同期スクロール有効フラグ |
| assisttick | int | TICK音有効フラグ |
| enablean | int | 直角音有効フラグ |
| preview_fx | int | FXエフェクトプレビュー有効フラグ |
| preview_laser | int | LASERエフェクトプレビュー有効フラグ |
| loopplayback | int | ループ再生有効フラグ |
| _bpmhalf | int | 半速再生フラグ |
| vol | int | 再生音量(0/25/50/75/100) |

### 出力先

- BASS AudioLibrary(音声出力)
- エディタ画面(カーソル位置のリアルタイム更新)
- メニューのチェック状態

## 処理フロー

### 処理シーケンス

```
1. ユーザーがSpace/メニューで再生を開始
   └─ CMD_PLAY_PLAYコマンド発行 → gosub *playing
2. 楽曲ファイルをBASS_StreamCreateFileでオープン
   └─ Switch Audio対応の場合は複数ストリームを準備
3. 再生ループ開始
   └─ BASS_ChannelPlayで楽曲再生を開始
4. フレームごとに現在位置を計算
   └─ BPM・拍子変化に対応したタイミング計算
5. TICK音・直角音・エフェクトを現在位置に応じて適用
   └─ assisttick/enablean/preview_fx/preview_laserフラグで制御
6. synchro=1の場合は画面を自動スクロール
   └─ posnow変数を更新して描画更新
7. ループ再生の場合は終端で先頭に戻る
   └─ loopplayback=1かつ選択範囲ありの場合
8. 停止条件で再生終了
   └─ pendfl=1、楽曲終了、Escキー等
```

### フローチャート

```mermaid
flowchart TD
    A[Spaceキー/メニュー] --> B[gosub *playing]
    B --> C[楽曲ファイルオープン]
    C --> D[BASS_ChannelPlay開始]
    D --> E{再生ループ}
    E --> F[現在位置計算]
    F --> G{TICK音有効?}
    G -->|Yes| H[tick.wav再生]
    G -->|No| I{同期スクロール?}
    H --> I
    I -->|Yes| J[画面スクロール更新]
    I -->|No| K{停止条件?}
    J --> K
    K -->|No| L{ループ再生かつ終端?}
    L -->|Yes| M[先頭に戻る]
    L -->|No| E
    M --> E
    K -->|Yes| N[BASS_StreamFree]
    N --> O[再生終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-112-01 | 再生開始位置 | カーソル位置(cnowf)から再生を開始する | CMD_PLAY_PLAY実行時 |
| BR-112-02 | 半速再生 | bpmhalf=1の場合、BPMを半分にして再生する | CMD_PLAY_BPMHALF有効時 |
| BR-112-03 | ループ再生 | 選択範囲がある場合、その範囲を繰り返し再生する | loopplayback=1かつ選択範囲あり |
| BR-112-04 | エフェクト遅延補正 | FXエフェクト適用時はバッファサイズ分先行して再生開始する | feffect=1の場合 |
| BR-112-05 | 音量制御 | 5段階(0/25/50/75/100%)で音量を制御する | CMD_PLAY_VOL_*実行時 |
| BR-112-06 | 設定永続化 | assisttick/loopplayback設定はconfig.iniに保存される | エディタ終了時 |

### 計算ロジック

- 再生位置からカウント値への変換: `cnow += int(double(t-tt)*bpm/625/beat/1000*2)` (15861行目)
- TICK音再生条件: 現在時刻がノート位置の前後500ms以内 (15981行目)

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

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

データベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル不在 | 楽曲ファイルが存在しない場合 | 音声なしで再生を継続(mplayfl=0) |

### リトライ仕様

リトライ処理はない。

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

トランザクション管理はない。

## パフォーマンス要件

- 再生ループはawait 1(約1ms)間隔で動作する
- 同期スクロール時は描画更新が毎フレーム行われるため、描画品質に影響する場合がある

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

セキュリティに関する考慮事項はない。

## 備考

- 再生中はUI操作が制限され、pendfl変数により一部コマンドがキューイングされる
- config.iniに保存される設定: editor_assisttick, editor_loopplayback
- BASS AudioLibraryのバッファ長制御により、エフェクト適用時のレイテンシが考慮されている

---

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

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

### 推奨読解順序

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

再生制御に関わるフラグ変数とオーディオハンドル変数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshooteditor.hsp | `kshooteditor.hsp` | **497行目**: `playingsample=0` - 再生中フラグ初期化 |
| 1-2 | kshooteditor.hsp | `kshooteditor.hsp` | **502-508行目**: assisttick/preview_fx/preview_laser/loopplayback初期値 |
| 1-3 | kshooteditor.hsp | `kshooteditor.hsp` | **507行目**: `_bpmhalf=0` - 半速再生フラグ初期化 |
| 1-4 | kshooteditor.hsp | `kshooteditor.hsp` | **131-144行目**: CMD_PLAY_*のenum定義 |

**読解のコツ**: HSPではグローバル変数で状態管理を行う。playingsample/pendfl/mflが再生状態の中核をなす。

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

再生コマンドの発行から*playingサブルーチンの呼び出しまでの流れを追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshooteditor.hsp | `kshooteditor.hsp` | **775-791行目**: メニュー項目追加(addmenu) |
| 2-2 | kshooteditor.hsp | `kshooteditor.hsp` | **8345行目**: `CMD_PLAY_PLAY → gosub *playing` |
| 2-3 | kshooteditor.hsp | `kshooteditor.hsp` | **8347-8398行目**: 各再生オプションのトグル処理 |

**主要処理フロー**:
1. **8345行目**: CMD_PLAY_PLAYでgosub *playingを呼び出し
2. **8347-8354行目**: CMD_PLAY_SYNCHROでsynchro変数をトグル
3. **8355-8367行目**: CMD_PLAY_TICKでassisttickをトグルしツールバーアイコン更新
4. **8368-8383行目**: CMD_PLAY_FX/LASERでpreview_fx/preview_laserをトグル
5. **8392-8398行目**: CMD_PLAY_LOOPPLAYBACKでloopplaybackをトグル
6. **8435-8437行目**: CMD_PLAY_BPMHALFで_bpmhalfをトグル
7. **8400-8434行目**: CMD_PLAY_VOL_*でvol変数を設定(100/75/50/25/0)

#### Step 3: 再生ループ処理を理解する

*playingサブルーチンの内部処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kshooteditor.hsp | `kshooteditor.hsp` | **15437行目**: `bpmhalf=_bpmhalf|ctrl_key` - 半速フラグ設定 |
| 3-2 | kshooteditor.hsp | `kshooteditor.hsp` | **15475行目**: BASS_StreamCreateFileで楽曲読み込み |
| 3-3 | kshooteditor.hsp | `kshooteditor.hsp` | **15742行目**: ループ再生用の外側ループ開始 |
| 3-4 | kshooteditor.hsp | `kshooteditor.hsp` | **15837行目**: 再生メインループ開始 |
| 3-5 | kshooteditor.hsp | `kshooteditor.hsp` | **15902-15927行目**: 楽曲再生開始とポジション設定 |
| 3-6 | kshooteditor.hsp | `kshooteditor.hsp` | **15940行目**: ループ再生終了判定 |
| 3-7 | kshooteditor.hsp | `kshooteditor.hsp` | **15978-15999行目**: TICK音再生処理 |

**主要処理フロー**:
- **15840行目**: `t=(d3timer()-ot)/(1+bpmhalf)` - 現在時刻の計算
- **15861行目**: `cnow+=int(double(t-tt)*bpm/625/beat/1000*2)` - タイミングからカウント値へ変換
- **15914行目**: `BASS_ChannelPlay(mid)` - 楽曲再生開始
- **15941-15944行目**: 同期スクロール処理

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

```
*OnCommand (2191行目)
    |
    +-- CMD_PLAY_PLAY (8345行目)
    |       +-- gosub *playing
    |           +-- BASS_StreamCreateFile (楽曲読み込み)
    |           +-- BASS_ChannelPlay (再生開始)
    |           +-- 再生ループ
    |               +-- BASS_ChannelGetPosition_ms (再生位置取得)
    |               +-- TICK音再生 (BASS_SampleGetChannel/BASS_ChannelPlay)
    |               +-- 画面スクロール更新 (synchro=1時)
    |               +-- エフェクト適用 (FX/LASER)
    |           +-- BASS_StreamFree (解放)
    |
    +-- CMD_PLAY_SYNCHRO (8347行目) → synchroトグル
    +-- CMD_PLAY_TICK (8355行目) → assisttickトグル
    +-- CMD_PLAY_FX (8368行目) → preview_fxトグル
    +-- CMD_PLAY_LASER (8376行目) → preview_laserトグル
    +-- CMD_PLAY_CHOKKAKU (8384行目) → enableanトグル
    +-- CMD_PLAY_LOOPPLAYBACK (8392行目) → loopplaybackトグル
    +-- CMD_PLAY_BPMHALF (8435行目) → _bpmhalfトグル
    +-- CMD_PLAY_VOL_* (8400-8434行目) → vol設定
    +-- CMD_PLAY_SAMPLE (8438行目) → プレビュー再生
```

### データフロー図

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

楽曲ファイル --------+
tick.wav/tick2.wav --+--> *playing再生ループ -----------> BASS AudioLib → スピーカー
カーソル位置 --------+    +-- BPM同期計算                 画面スクロール更新
再生設定フラグ ------+    +-- TICK音/直角音判定           メニューチェック状態
                          +-- エフェクト適用
                          +-- ループ判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshooteditor.hsp | `kshooteditor.hsp` | ソース | エディタ本体。再生制御コマンド・再生ループ処理を含む |
| tick.wav | `tick.wav` | リソース | BTノート位置で再生されるTICK音 |
| tick2.wav | `tick2.wav` | リソース | FXノート位置で再生されるTICK音 |
| src/bass.as | `src/bass.as` | ソース | BASS AudioLibraryのHSPバインディング |
| src/bass_fx.as | `src/bass_fx.as` | ソース | BASS FX拡張のHSPバインディング |
| src/bass_vst.as | `src/bass_vst.as` | ソース | BASS VSTプラグインのHSPバインディング |
