WebAudioAPI ディレイ/エコーの制作

今までの学習のまとめです。

ローカルの音声ファイルをMediaElementで読み込み、AudioBufferでFXを付与して出力しています。

ディレイは原音とエフェクト音を分けて出力(センド・エフェクト)できるようにしています。

>エフェクト音は通常のaudioContext.createDelay()に対してディレイタイムにLFOを掛け、HPFを通したものを出力しています。
これは音程に揺らぎを与え、低域の飽和を抑える役目をしています。

MEMO 追加予定
テープの劣化 = ディストーション
走行時のノイズ = ヒスノイズ
走行速度の揺れ = ディレイタイムにLFO
ハイダンプ/ローダンプ







```html
<!DOCTYPE html>
<html lang="jp">

<head>
	<meta charset="UTF-8">
</head>

<body>
	<input id="Afile" type="file">
	<audio id="Aplayer"></audio>
	<input type="checkbox" id="play_pause">PLAY/PAUSE
	<input type="checkbox" id="loop">LOOP
	<br>
	<input type="range" id="volume" value="1" min="0" max="1" step="0.05">GAIN
	<input type="range" id="pitchAdj" value="1.00" min="0.7" max="1.16" step="0.01">PITCH
	<br>
	<input type="range" id="inputVolume" value="0.95" min="0" max="0.95" step="0.05">InputVolume
	<input type="range" id="repeatRate" value="0" min="0" max="1" step="0.05">RepeatRate
	<input type="range" id="intensity" value="0" min="0" max="1" step="0.05">Intensity
	<input type="range" id="echoVolume" value="0" min="0" max="1.3" step="0.05">EchoVolume
	<script>
```

```javascript
		window.onload = () => {
			//ファイルの読み込み
			var Actx = new(window.AudioContext || window.webkitAudioContext)();
			var gain = Actx.createGain();
			var source = Actx.createMediaElementSource(Aplayer);
			Afile.onchange = function() {
				Aplayer.src = URL.createObjectURL(this.files[0]);
				Aplayer.currentTime = 0;
				play_pause.checked = false;
			};
			//再生、一時停止
			play_pause.onchange = () => {
				(play_pause.checked) ? Aplayer.play(): Aplayer.pause();
			};
			//ループ
			loop.onchange = () => {
				(loop.checked) ? Aplayer.loop = true: Aplayer.loop = false;
			};
			volume.addEventListener('input', () => gain.gain.value = volume.valueAsNumber);
			pitchAdj.addEventListener('input', () => Aplayer.playbackRate = pitchAdj.valueAsNumber);

			//エコー
			var delay = Actx.createDelay();
			var dry = Actx.createGain();
			var wet = Actx.createGain();
			var feedback = Actx.createGain();
			var delayFilter = Actx.createBiquadFilter();
			var lfo = Actx.createOscillator();
			var lfoG = Actx.createGain();

			lfo.frequency.value = 1;
			lfoG.gain.value = 0.0025;
			lfo.start(0);
			delayFilter.type = 'highpass';
			delayFilter.frequency.value = 200;
			delayFilter.Q.value = 0;
			dry.gain.value = 1.0;
			wet.gain.value = feedback.gain.value = 0.0;

			//ドライ、ディレイタイム、フィードバック、音量
			inputVolume.addEventListener('input', () => dry.gain.value = inputVolume.valueAsNumber);
			repeatRate.addEventListener('input', () => delay.delayTime.value = repeatRate.valueAsNumber);
			intensity.addEventListener('input', () => feedback.gain.value = intensity.valueAsNumber);
			echoVolume.addEventListener('input', () => wet.gain.value = echoVolume.valueAsNumber);

			//ルーティング
			source.connect(dry).connect(gain);
			source.connect(delay).connect(wet).connect(delayFilter).connect(gain);
			delay.connect(feedback).connect(delay);
			lfo.connect(lfoG).connect(delay.delayTime);

			gain.connect(Actx.destination);

			Aplayer.onended = () => {
				play_pause.checked = false;
				Aplayer.currentTime = 0;
			};
		};
```

```html
	</script>
</body>

</html>
```

別ファイルをロードした際にクリップするので、次回はその部分の修正とリバーブの制作を予定しています。