LoginSignup
2
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-04-13

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

ローカルの音声ファイルを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>

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

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4