2015-12-27 10 views
12

Was ich versuche zu lernen/tun: Wie man einen einfachen funktionierenden Convolver (Reverb) in meinem Code-Sandkasten unter Verwendung einer Impulsantwort einrichtet. Ich dachte, es wäre ähnlich, einen Filter zu setzen, aber die Dinge scheinen ganz anders zu sein.Web Audio API: Wie füge ich einen funktionierenden Convolver hinzu?

Was ich versucht habe: Wie bei allen neuen Technologien ändern sich die Dinge in einem schnellen Tempo, was es schwierig macht zu wissen, welche Implementierung korrekt ist und welche nicht. Ich sah mir unzählige WebAudio Api Convolver Tutorials an, viele waren alt und andere arbeiteten, aber viel zu "aufgebläht", was es schwer machte zu verstehen, was vor sich ging. Ich habe versucht, einige der Beispiele aus der mozilla Dokumentation zu implementieren:

Ich hatte schon einen Blick auf: https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode/buffer

Meine Frage: Wie integriere ich einen Convolver richtig im Kontext unten? Wie Sie sehen können, habe ich es versucht, kann es aber nicht herausfinden.

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(); 
} 
+0

Wie können Sie 150 rep vergeben, wenn Sie nur 114 haben? – dandavis

+0

@dandavis gute Frage – Asperger

Antwort

7

Dies ist eine ziemlich offene Frage; Was hast du versucht, das hat nicht funktioniert, oder fehlt dir das Stück, was die "Impulsantwort" sein soll? Suchen Sie im letzteren Fall nach "impulse response files" und Sie werden jede Menge kostenloser Dateien finden, die Sie verwenden können. Sie können auch Rauschen auf einer logarithmischen Abklingkurve in einen Puffer erzeugen, und Sie erhalten einen grundlegenden Reverb-Effekt. Basic-Methode einen Impulsantwort-Puffer zu erstellen:

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; 
} 

Ihr Code hat sowohl eine BufferSourceNode und die Convolver auf dem gleichen Puffer zeigt, die mit ziemlicher Sicherheit falsch ist; Normalerweise geben Sie eine Impulsantwortdatei nicht mit einer Pufferquelle wieder, und Sie verwenden normalerweise keine normale Audiodatei als Impulsantwort. (Look up Faltung auf Wikipedia, wenn die Rolle einer Impulsantwort ist nicht klar.) Sie müssen, wie etwas zu tun ist:

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); 
} 
+0

Ich werde eine Probe von dem, was ich versucht habe, erstellen. Ich werde meine Frage bearbeiten, warten. Ich kann nicht herausfinden, wie man den Convolver in diesem Zusammenhang benutzt (Verbindung, Syntax usw.). Die Dokumentation war nicht sehr hilfreich, nur für die Filter. Jedenfalls werde ich meinen Code jetzt bearbeiten. – Asperger

+0

Wie Sie sehen, besteht das Problem darin, den Convolver mit dem Rest meines Codes zu verbinden. – Asperger

+0

Bitte schauen Sie sich meinen bearbeiteten Code an. Sie können sehen, was ich versuchte. Es wäre schön, wenn Sie mich im gegebenen Beispiel anleiten könnten, wie man es richtig benutzt. Es fällt mir wirklich schwer zu verstehen, wie es funktioniert. – Asperger

5

Verbinden Sie den Ausgang des Convolver zu etwas. Was Sie jetzt haben, ist die Quelle, die mit dem Convolver verbunden ist, aber der Convolver ist mit nichts verbunden. Als ein erster Schnitt, convolver.connect(context.destination).

+0

Aber ist der Rest richtig eingestellt? Ich habe keine XMLhttprequests – Asperger

+0

Fehler beim Festlegen der "Puffer" -Eigenschaft auf "AudioBufferSourceNode": Der angegebene Wert ist nicht vom Typ "AudioBuffer. Ehrlich, ich wäre dankbar, wenn Sie mir zeigen könnten, wie das gemacht wird, da ich eher ein visueller Lerner bin. Das ist wirklich verwirrend. Ich habe den Convolver mit dem Ziel verbunden, aber ich bekomme diesen Fehler jetzt. – Asperger

+2

Ja, Sie müssen XMLhttprequest verwenden, um Ihre Datei hall.mp3 zu laden und mit decodeAudio das MP3 in eine Pufferquelle zu konvertieren. Oder verwenden Sie die impulseResponse-Funktion von @ cwilso, um eine Impulsantwort zu erzeugen, um zu testen, ob Sie die Dinge so eingerichtet haben, wie Sie möchten. –