Search code examples
javascriptaudiomicrophonegetusermedia

How to generate negative audio waves from input sound in javascript?


I found a javascript that captures the current microphone input just to send it out again. You can see it here:

https://codepen.io/MyXoToD/pen/bdb1b834b15aaa4b4fcc8c7b50c23a6f?editors=1010 (only works with https).

I was wondering how I can generate the "negative" waves of the sound captured. Just like "noise cancellation" works. So the script detects the current noise around me and whenever there is a wave going up I want to generate a wave that is going down to cancel each other out. Is there a way to do this in javascript?

So this outputs the current sound recored:

var input = audio_context.createMediaStreamSource(stream);
volume = audio_context.createGain();
volume.gain.value = 0.8;
input.connect(volume);
volume.connect(audio_context.destination);

The question is how to produce the negative of this sound and output this instead.


Solution

  • You're already streaming your signal through a Web Audio chain. What you need to do is chain an AudioWorklet node between the input and output nodes (after or before the gain node, doesn't matter). The script for the worklet would be a very simple sign inversion.

    await audio_context.audioWorklet.addModule("negate.js")
    const negateNode = new AudioWorkletNode(audio_context, "negate")
    input.connect(negationNode)
    negateNode.connect(volume)
    

    The worklet ("negate.js") :

    class AudioNegator extends AudioWorkletProcessor {
      process([input], [output]) {
        for (let channel = 0; channel < input.length; channel++)
          for (let i = 0; i < 128; i++)
            output[channel][i] = -input[channel][i]
        return false
      }
    }
    registerProcessor("negate", AudioNegator)