1

UPDATE

I found an example of high pass filter using webAudio here. Implemented it like this in my code.

function modifyGain(audioTrack, gainValue){
  var ctx = new AudioContext();
  var src = ctx.createMediaStreamTrackSource(audioTrack);
  var dst = ctx.createMediaStreamDestination();
    // create a filter node
    var filterNode = ctx.createBiquadFilter();
 
    filterNode.type = 'highpass';
    filterNode.frequency.value = 0;
    // cutoff frequency: for highpass, audio is attenuated below this frequency
  var gainNode = ctx.createGain();
  gainNode.gain.value = 1;
   src.connect(filterNode);
   //filterNode.connect(dst);
   filterNode.connect(gainNode);

  gainNode.connect(dst);

    //alert(ctx.dst)
  return dst.stream.getTracks()[0];
}




try {
  webcamStream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
  document.getElementById("local_video").srcObject = webcamStream;
} catch(err) {
  handleGetUserMediaError(err);
  return;
}

// Add the tracks from the stream to the RTCPeerConnection

try {

  webcamStream.getTracks().forEach(
    function (track){
        if(track.kind === 'audio'){
            track = modifyGain(track, 0.5) //process only audio tracks
        }

        myPeerConnection.addTrack(track, webcamStream);
    });
  showLocalVideoContainer();
} catch(err) {
  handleGetUserMediaError(err);
}

Before I can actually test if low sounds are silenced by highpass filter I am facing an issue. Using modifyGain mutes audio completely after few seconds. I tried 0, 1500 etc. It goes silence after few seconds.

Original POST

I am using the below constraints to try to suppress noise.

var mediaConstraints = {
audio: {advanced: [
                    {
                        echoCancellation: {exact: true}
                    },
                    {
                        autoGainControl: {exact: true}
                    },
                    {
                        noiseSuppression: {exact: true}
                    }, 
                    {
                        highpassFilter: {exact: true}
                    }
                ]
    },
  video: { 
    facingMode: "user",
    width: { min: 160, ideal: 320, max: 640 },
    height: { min: 120, ideal: 240, max: 480 },
  }
 };

But I want to silence some higher frequencies too. Even if I slowly move my phone on some surface the mic catches the noise and sends it to other peer. It catches even my breathing sound and send that to other side when I place it near my check(like phone call). I want some control over the frequencies which can allow me to select a threshold below which sounds will be not picked by mic.

I have tried searching but I am not sure what exactly will work for my case and how should I do it. I think following are my choices, but I maybe wrong.

  1. Change SDP( codec params?).
  2. Use webAudio and process the mic input before passing it on to other peer.
  3. Use webAudio and process the received audio from other peer and direct it to output device(speaker).

Any help will be appreciated. Thanks

Newbie
  • 343
  • 2
  • 13
  • You can use [web audio](https://stackoverflow.com/questions/38873061/how-to-increase-mic-gain-in-webrtc/38880387#38880387) to do it. – jib Aug 22 '20 at 19:07
  • 1
    I'd avoid `advanced` constraints as they're rarely ever needed. Just do like you do for `video`. E.g. `audio: {echoCancellation: {exact: true}, ... }` etc. – jib Aug 22 '20 at 19:09
  • The link you posted is about gain and I already have `autoGainControl`. Also, I realized that `highpasssFilter` isn't supported in FireFox. I don't know about Chrome. Haven't tested it there yet. Maybe I what I need is something like `highPassFilter` which should pass only higher frequencies and attenuate low frequencies. – Newbie Aug 23 '20 at 06:03
  • I removed that `advanced` part. Thank you. – Newbie Aug 23 '20 at 06:03
  • @jib I have made an update to the post. Can you please see if you can help. Thank you – Newbie Aug 23 '20 at 07:39

1 Answers1

1

You can process the audio from your microphone by piping it through web audio & using the BiquadFilter:

const stream = await navigator.mediaDevices.getUserMedia({audio: true});
const ctx = new AudioContext();
const src = ctx.createMediaStreamSource(stream);
const dst = ctx.createMediaStreamDestination();
const biquad = ctx.createBiquadFilter();
[src, biquad, dst].reduce((a, b) => a && a.connect(b));
audio.srcObject = dst.stream;

biquad.type = "highpass";
biquad.gain = 25;
biquad.frequency.value = 1000;
rangeButton.oninput = () => biquad.frequency.value = rangeButton.value;

Here's a working fiddle.

It goes silent after few seconds.

Could be a garbage collection issue. If you're experiencing this, try assigning your stream to a global JS var.

jib
  • 40,579
  • 17
  • 100
  • 158