konrad
konrad

Reputation: 101

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!

Upvotes: 8

Views: 1308

Answers (2)

cwilso
cwilso

Reputation: 13908

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.

Upvotes: 13

Kevin Ennis
Kevin Ennis

Reputation: 14456

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.

The convolver requires an AudioBuffer that contains an impulse response. Short of trying to create one programatically (which would probably be pretty difficult), you're going to need to load one via XHR.

If you Google around a bit, you can find lots of free impulse responses as WAV or MP3 files.

Upvotes: 0

Related Questions