# 機能設計書: AudioContext（Web Audio APIコンテキスト管理）

## 1. 機能概要

### 1.1 機能の目的
AudioContextは、Web Audio APIのAudioContextをグローバルに管理し、three.jsのオーディオシステム全体で一貫したオーディオコンテキストを提供するためのユーティリティモジュールである。シングルトンパターンを採用し、複数のオーディオコンポーネント間でAudioContextを共有する。

### 1.2 主な機能
- AudioContextのシングルトン取得
- ブラウザ互換性対応（webkit prefix対応）
- グローバルなAudioContext管理

### 1.3 関連する画面/コンポーネント
- Audio（オーディオソース）
- PositionalAudio（3D空間オーディオ）
- AudioListener（オーディオリスナー）
- AudioAnalyser（オーディオ解析）

## 2. 機能仕様

### 2.1 データ構造

```javascript
// モジュールレベル変数
let _context;  // AudioContextのシングルトンインスタンス

// エクスポート関数
function AudioContext() {
    // AudioContextの取得または作成
}
```

### 2.2 プロパティ詳細

| プロパティ名 | 型 | 説明 | スコープ |
|-------------|-----|------|---------|
| _context | AudioContext | キャッシュされたAudioContextインスタンス | モジュールプライベート |

### 2.3 メソッド詳細

#### 2.3.1 AudioContext()
```javascript
function AudioContext(): AudioContext
```
**戻り値:** Web Audio APIのAudioContextインスタンス

**処理内容:**
1. `_context`がundefinedの場合、新しいAudioContextを作成
2. ブラウザ互換性のため、`window.AudioContext`または`window.webkitAudioContext`を使用
3. `_context`に格納してキャッシュ
4. `_context`を返却

### 2.4 ビジネスルール
- AudioContextはアプリケーション全体で1つのみ存在する（シングルトン）
- 初回呼び出し時にのみインスタンスを作成
- ブラウザのAudioContext自動再生ポリシーに従う必要がある

### 2.5 状態遷移
AudioContextの状態はWeb Audio API仕様に従う：
- `suspended`: 初期状態（自動再生ポリシーによる）
- `running`: アクティブな状態
- `closed`: 終了状態

```
[suspended] ---(ユーザーインタラクション)---> [running]
[running] ---(close())---> [closed]
```

## 3. 入出力設計

### 3.1 入力データ
| データ項目 | 型 | 必須 | 説明 |
|-----------|-----|------|------|
| なし | - | - | パラメータなし |

### 3.2 出力データ
| データ項目 | 型 | 説明 |
|-----------|-----|------|
| context | AudioContext | Web Audio APIのAudioContextインスタンス |

## 4. 処理フロー

### 4.1 AudioContext取得フロー
```
[AudioContext()呼び出し]
        |
        v
[_context が undefined?]
        |
    Yes |           No
        v            |
[AudioContext作成]   |
        |            |
        v            |
[_context に格納]    |
        |            |
        v            v
[_context を返却]<---'
```

### 4.2 シーケンス図
```
Component       AudioContext.js      window
    |                  |                |
    |--AudioContext()-->               |
    |                  |                |
    |        [_context undefined?]      |
    |                  |                |
    |                  |--new AudioContext()
    |                  |<-instance------|
    |                  |                |
    |<-AudioContext----|                |
    |                  |                |
    |--AudioContext()-->               |
    |        [_context exists]          |
    |<-cached instance-|                |
```

## 5. エラーハンドリング

### 5.1 エラー条件
| エラー条件 | エラー種別 | 対処方法 |
|-----------|-----------|---------|
| AudioContext未サポート | TypeError | フォールバック処理または警告表示 |
| AudioContext制限超過 | NotAllowedError | 既存のAudioContextを再利用 |
| 自動再生ポリシー違反 | NotAllowedError | ユーザーインタラクション後にresume() |

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

### 6.1 推奨読解順序
1. **AudioContext.js** - ユーティリティ関数を理解
2. **AudioListener.js** - AudioContextの使用方法を確認
3. **Audio.js** - オーディオ再生での活用を理解

### 6.2 重要な処理の詳細

#### AudioContext関数（1-11行目）
```javascript
let _context;

function AudioContext() {
    if ( _context === undefined ) {
        _context = new ( window.AudioContext || window.webkitAudioContext )();
    }
    return _context;
}
```
**1行目**: モジュールスコープの変数宣言（シングルトン用）
**4行目**: キャッシュ済みかどうかの判定
**5行目**: ブラウザ互換性を考慮したAudioContext生成
**7行目**: キャッシュしたインスタンスを返却

### 6.3 プログラム呼び出し階層図
```
AudioContext.js
└── AudioContext()
    ├── 初回: new (window.AudioContext || window.webkitAudioContext)()
    └── 2回目以降: キャッシュから返却

呼び出し元:
├── AudioListener.js
│   └── constructor() → AudioContext()
├── Audio.js
│   └── context プロパティ
└── AudioAnalyser.js
    └── audio.context 経由
```

### 6.4 データフロー図
```
[AudioContext.js]
       |
       | _context (シングルトン)
       v
[AudioListener]
       |
       | this.context
       v
[Audio] -------> [AudioAnalyser]
       |              |
       | getOutput()  | analyser
       v              v
[GainNode] ----> [AnalyserNode]
```

### 6.5 関連ファイル一覧
| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| src/audio/AudioContext.js | メイン | AudioContextユーティリティ |
| src/audio/AudioListener.js | 関連 | AudioContextの主要消費者 |
| src/audio/Audio.js | 関連 | オーディオ再生でcontext使用 |
| src/audio/PositionalAudio.js | 関連 | 3D空間オーディオでcontext使用 |
| src/audio/AudioAnalyser.js | 関連 | 周波数解析でcontext使用 |

## 7. 使用例

### 7.1 基本的な使用例
```javascript
import { AudioContext } from 'three';

// AudioContextの取得（初回は作成）
const context = AudioContext();

// 同じインスタンスが返される
const context2 = AudioContext();
console.log(context === context2);  // true
```

### 7.2 AudioListenerでの使用
```javascript
// AudioListenerを通じて間接的にAudioContextを使用
const listener = new THREE.AudioListener();
camera.add(listener);

// listener.contextはAudioContext()で取得したインスタンス
console.log(listener.context.state);  // 'suspended' or 'running'
```

### 7.3 自動再生ポリシー対応
```javascript
const listener = new THREE.AudioListener();
const audio = new THREE.Audio(listener);

// ユーザーインタラクション時にresumeを呼び出す
document.addEventListener('click', () => {
    if (listener.context.state === 'suspended') {
        listener.context.resume();
    }
});
```

## 8. 備考

### 8.1 ブラウザ互換性
- 古いSafari（iOS含む）では`webkitAudioContext`が必要
- 現在のモダンブラウザではすべて`AudioContext`をサポート

### 8.2 自動再生ポリシー
- Chrome 66+、Safari 11+では自動再生が制限される
- ユーザーインタラクション（クリック、タッチ等）後にresume()が必要
- バックグラウンドタブではAudioContextがsuspendされる場合がある

### 8.3 メモリ管理
- AudioContextは明示的にclose()しない限りメモリを保持
- 多くのブラウザでは同時に作成できるAudioContextの数に制限がある
- シングルトンパターンにより、この問題を回避

### 8.4 パフォーマンス考慮事項
- AudioContextの作成は比較的高コストな操作
- シングルトンパターンにより、作成コストを初回のみに限定
- 複数のオーディオソースが1つのAudioContextを共有可能
