2015-12-27 19 views
12

Próbuję nauczyć/zrobić: Jak skonfigurować prosty convolver pracy (pogłos) do mojego kodu piaskownicy poniżej za pomocą odpowiedzi impulsowej. Myślałem, że to było podobne do ustawiania filtra, ale rzeczy wyglądają zupełnie inaczej.Web Audio Api: Jak dodać działający convolver?

Co próbowałem: jak w przypadku wszystkich nowych technologii rzeczy zmieniają się w szybkim tempie przez co trudno wiedzieć, które implementacja jest poprawna, a co nie jest. Spojrzałem na niezliczonych WebAudio api Convolver Poradniki, wiele były stare i inni pracowali, ale zbyt „nadęty” co trudno zrozumieć, co się dzieje. Starałem się wdrożyć niektóre przykłady z dokumentacji mozilla:

miałem już do obejrzenia: https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode/buffer

Moje pytanie: W jaki sposób zintegrować convolver odpowiednio w poniższej kontekście? Jak widać próbowałem, ale nie mogę tego zrozumieć.

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

jak można dać się 150 rep jeśli masz tylko 114? – dandavis

+0

@dandavis dobre pytanie – Asperger

Odpowiedz

7

To jest dość otwarte pytanie; Czego próbowaliście, to nie zadziałało, czy też brakuje wam czegoś, co ma być "reakcją na impuls"? Jeśli to drugie, wyszukaj "pliki odpowiedzi na impulsy", a znajdziesz mnóstwo darmowych plików, których możesz użyć. Możesz również generować szum na logarytmicznej krzywej zaniku w buforze, a otrzymasz podstawowy efekt pogłosu. Podstawowa metoda, aby stworzyć bufor charakterystyka impulsowa:

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

Twój kod ma zarówno BufferSourceNode i convolver wskazując tym samym buforze, który jest prawie na pewno źle; zazwyczaj nie odtwarza się pliku odpowiedzi impulsu za pomocą źródła bufora i zwykle nie używa się normalnego pliku dźwiękowego jako odpowiedzi impulsowej. (Spójrz splot Wikipedia jeśli rola odpowiedzi impulsowej nie jest jasne). Trzeba zrobić coś takiego:

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

będę tworzyć próbkę co próbowałem. Będę edytować moje pytanie, trzymaj się. Nie mogę wymyślić, w jaki sposób korzystać z convolver w tym kontekście (podłączenie, składnia itp.). Dokumentacja nie była bardzo pomocna, tylko dla filtrów. Tak czy inaczej będę teraz edytować mój kod. – Asperger

+0

Jak widać, problemem jest połączenie spinającego z resztą mojego kodu. – Asperger

+0

Proszę spojrzeć na mój zredagowany kod. Możesz zobaczyć, co próbowałem. Byłoby miło, gdybyś mógł poprowadzić mnie, jak właściwie go używać w danym przykładzie. Naprawdę trudno mi zrozumieć, jak to działa. – Asperger

5

podłączyć wyjście z convolver do czegoś. To, co masz teraz, to źródło połączone z nawijaczem, ale nawijacz nie jest z niczym połączony. Jako pierwsze cięcie, convolver.connect(context.destination).

+0

Ale czy reszta jest poprawnie ustawiona? Nie użyłem żadnych XMLhttprequests – Asperger

+0

Nie można ustawić właściwości 'buffer' w 'AudioBufferSourceNode': Podana wartość nie jest typu 'AudioBuffer. Szczerze mówiąc, byłabym wdzięczna, gdybyś pokazała mi, jak to się robi, jako że jestem bardziej wzrokowcem. To jest naprawdę mylące. Podłączyłem convolver do miejsca docelowego, ale teraz dostaję ten błąd. – Asperger

+2

Tak, musisz użyć XMLhttprequest, aby załadować plik hall.mp3 i użyć polecenia decodeAudio, aby przekonwertować mp3 na źródło bufora. Lub użyj funkcji impulseResponse @ cwilso, aby utworzyć odpowiedź impulsową do testowania, że ​​masz rzeczy ustawione tak, jak chcesz. –

Powiązane problemy