JavaScript
HTML5
WebAudioAPI
オーディオ

再生/一時停止をAudioタグで管理し、AudioBufferで加工する。

AudioBufferのみだと一時停止やシークが難しくなるので、そのような操作はMediaElement(Audioタグ)に任せて、AudioBufferに結線してから加工する方法をとってみました。

確認のためにディレイをインサートしています。他のFXをどんどん入れていくと冗長になるので、外部モジュール化する予定です。

ちなみに、再生速度の変更はMediaElementだと音程は維持できますが音が切れます。
AudioBufferだと滑らかに遷移しますが、音程が速度に比例します。

html
<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="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" step="0.05">echo volume
javascript
//ファイルの読み込み
Afile.onchange = function() {
    Aplayer.src = URL.createObjectURL(this.files[0]);
    play_pause.checked = false;
};
//再生、一時停止
play_pause.onchange = function() {
    (play_pause.checked) ? Aplayer.play(): Aplayer.pause();
};
//ループ
loop.onchange = function() {
    (loop.checked) ? Aplayer.loop = true: Aplayer.loop = false;
};

window.onload = function() {
    var source;
    var Actx = new(window.AudioContext || window.webkitAudioContext);
    var gain = Actx.createGain();
    source = Actx.createMediaElementSource(Aplayer);
    //ディレイ
    var delay = Actx.createDelay();
    var delayIn, delayOut = Actx.createGain();
    var dry, wet, feedback = Actx.createGain();
    delayIn.gain.value = delayOut.gain.value = dry.gain.value = 1.0;
    wet.gain.value = feedback.gain.value = 0.0;

    //ルーティング
    delayIn.connect(dry).connect(delayOut);
    delayIn.connect(delay).connect(wet).connect(delayOut);
    delay.connect(feedback).connect(delay);
    source.connect(delayIn)
    delayOut.connect(gain).connect(Actx.destination);
    //再生速度の変更
    pitchAdj.addEventListener('input', function() {
        Aplayer.playbackRate = this.valueAsNumber;
    });
    //音量
    volume.addEventListener('input', function() {
        gain.gain.value = this.valueAsNumber;
    });
    //ディレイタイム
    repeatRate.addEventListener('input', function() {
        delay.delayTime.value = this.valueAsNumber;
    });
    //フィードバック
    intensity.addEventListener('input', function() {
        feedback.gain.value = this.valueAsNumber;
    });
    //ディレイボリューム
    echoVolume.addEventListener('input', () => wet.gain.value = this.valueAsNumber);
};