Newbie
Newbie

Reputation: 373

webRTC - suppress lower sounds

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

Upvotes: 1

Views: 932

Answers (1)

jib
jib

Reputation: 42450

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.

Upvotes: 1

Related Questions