今までの学習のまとめです。
ローカルの音声ファイルをMediaElementで読み込み、AudioBufferでFXを付与して出力しています。
ディレイは原音とエフェクト音を分けて出力(センド・エフェクト)できるようにしています。
エフェクト音は通常のaudioContext.createDelay()に対してディレイタイムにLFOを掛け、HPFを通したものを出力しています。
これは音程に揺らぎを与え、低域の飽和を抑える役目をしています。
MEMO 追加予定
テープの劣化 = ディストーション
走行時のノイズ = ヒスノイズ
走行速度の揺れ = ディレイタイムにLFO
ハイダンプ/ローダンプ
<!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>
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;
};
};
</script>
</body>
</html>
別ファイルをロードした際にクリップするので、次回はその部分の修正とリバーブの制作を予定しています。