Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting convolverNode to an oscillatorNode with the web audio – the simple way

I am pretty new in js, so I was wondering if anybody could he help with this (for some) quite simple problem I am dealing with. I am trying to make an oscillatorNode connect to a convolverNode, an achieve a hall reverb. I still haven't made it work even though it's probably really simple. Now, there are plenty of examples on how to do it when you load sounds with the XMLHttpRequest, but I am not interested in doing it with loaded sound. I guess I am just longing for a good and super short example/fiddle of how that would be done and how to make the buffer work with oscillatorNodes. Here's the basics of how to make a convolverNode, now how to make the rest?

// Make a source node for the sample.
var source = context.createBufferSource();
source.buffer = this.buffer;

// Make a convolver node for the impulse response.
var convolver = context.createConvolver();
convolver.buffer = this.impulseResponseBuffer;

// Connect the graph.
source.connect(convolver);
convolver.connect(context.destination);

Thank you so so much!

like image 974
konrad Avatar asked Mar 20 '14 07:03

konrad


1 Answers

I think you're asking if you can connect an oscillator to a ConvolverNode, but that's pretty easy to do:

var osc = context.createOscillator();
osc.connect(convolver);
osc.start(0);

so perhaps you are, as Kevin guessed, trying to generate (rather than download) an impulse response. You don't really want to use an oscillator for this - an impulse response needs to be finite in length. You could generate a sine wave of finite duration in a buffer, but that's going to do something different than reverb.

Presuming you're trying to algorithmically generate a basic reverb impulse response to avoid a download, it's actually relatively easy to do - you can just use noise on a logarithmic decay. Here's a function I wrote a while ago:

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

Try starting out with

var impulseBuffer = impulseResponse(4,4,false);

and set your convolverNode.buffer to that. That will give a decent start. Play with the duration and decay params as you like. This may not be as smooth or as interesting as a recorded impulse response, but it'll do for most basic purposes.

like image 152
cwilso Avatar answered Oct 20 '22 08:10

cwilso