Подтвердить что ты не робот

Web Audio Api: Как добавить рабочий сверла?

Что я пытаюсь изучить/сделать: Как настроить простой рабочий сверток (реверберацию) в мою песочницу кода ниже, используя импульсный отклик. Я думал, что это похоже на настройку фильтра, но все выглядит совсем по-другому.

То, что я пробовал: Как и во всех новых технологиях, все меняется быстро, что затрудняет понимание, какая реализация правильная, а что нет. Я посмотрел на бесчисленные WebAudio Api Convolver Tutorials, многие из них были старыми, а другие работали, но слишком "раздувались", что затрудняло понимание происходящего. Я попытался реализовать некоторые из примеров из документации mozilla:

Я уже посмотрел: https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode/buffer

Мой вопрос: Как правильно интегрировать сверток в контексте ниже? Как вы можете видеть, я попытался, но не могу понять это.

 window.addEventListener('load', init, false);

function init() {
    setupWebAudio();
}

function setupWebAudio() {
    var audio = document.getElementById('music');
    var context = new AudioContext();
    var source = context.createMediaElementSource(audio);
    var filter = context.createBiquadFilter();
    var convolver = context.createConvolver();
    var inpulseRes = "hall.mp3";

    var hallBuffer = inpulseRes;
    soundSource = context.createBufferSource();
    soundSource.buffer = hallBuffer;
    convolver.buffer = hallBuffer;

    filter.type = 'lowpass';
    filter.frequency.value = 400;

var theParent = document.getElementById("test");
    theParent.addEventListener("mousedown", doSomething, false);
    function doSomething(e) {
        if (e.target !== e.currentTarget) {
            if(e.target == theParent.children[0]){
                filter.frequency.value += 200;
            }
            else if(e.target == theParent.children[1]){
                 filter.frequency.value -= 200;
            }
            else if(e.target == theParent.children[2]){
                 filter.type = 'highpass';
            }               
        }
        e.stopPropagation();
    }

    source.connect(filter);
    source.connect(convolver);
    filter.connect(context.destination);
    audio.play();
}
4b9b3361

Ответ 1

Это довольно открытый вопрос; что вы пробовали, что не сработало, или это то, что вам не хватает, что "импульсная реакция" должна быть? Если последний, найдите "файлы импульсного ответа", и вы найдете множество бесплатных файлов, которые вы можете использовать. Вы также можете генерировать шум на логарифмической кривой затухания в буфер, и вы получите базовый эффект реверберации. Основной метод создания буфера ImpulseResponse:

function impulseResponse( duration, decay, reverse ) {
    var sampleRate = audioContext.sampleRate;
    var length = sampleRate * duration;
    var impulse = audioContext.createBuffer(2, length, sampleRate);
    var impulseL = impulse.getChannelData(0);
    var impulseR = impulse.getChannelData(1);

    if (!decay)
        decay = 2.0;
    for (var i = 0; i < length; i++){
      var n = reverse ? length - i : i;
      impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);
      impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);
    }
    return impulse;
}

В вашем коде есть как BufferSourceNode, так и convolver, указывающие на тот же буфер, что почти наверняка неверно; вы обычно не воспроизводите файл импульсного ответа с использованием буферизатора, и обычно вы не используете обычный звуковой файл в качестве импульсного ответа. (Смотрите свертку в Википедии, если роль импульсного ответа не ясна.) Вам нужно сделать что-то вроде:

function setupWebAudio() {
    var audio = document.getElementById('music');
    var context = new AudioContext();
    var source = context.createMediaElementSource(audio);
    var convolver = context.createConvolver();
    var irRRequest = new XMLHttpRequest();
    irRRequest.open("GET", "hall.mp3", true);
    irRRequest.responseType = "arraybuffer";
    irRRequest.onload = function() {
        context.decodeAudioData( irRRequest.response, 
            function(buffer) { convolver.buffer = buffer; } );
    }
    irRRequest.send();
// note the above is async; when the buffer is loaded, it will take effect, but in the meantime, the sound will be unaffected.

    source.connect( convolver );
    convolver.connect( context.destination );
}

Ответ 2

Подключите вывод сверточного устройства к чему-либо. Теперь у вас есть источник, связанный со сверткой, но сверток не связан ни с чем. В качестве первого разреза convolver.connect(context.destination).