【问题标题】:WebRTC AGC (Automatic Gain Control): can it really be disabled?WebRTC AGC(自动增益控制):真的可以禁用吗?
【发布时间】:2021-02-28 13:19:05
【问题描述】:

:)

我已将 AppRTC (https://github.com/webrtc/apprtc) 安装到单独的服务器上,以尝试更灵活地控制 WebRTC 参数。

主要任务是禁用自动增益控制 (AGC)。

已执行以下步骤:

  1. 音频流的参数:
{
    video: 
    {
        frameRate: 30,
        width: 640,
        height: 480
    }, 
    audio: 
    {
        echoCancellation: true, 
        noiseSuppression: true, 
        autoGainControl: false
    }
}
  1. GainNode 过滤器已通过 audioContext.createGain() 添加,并已通过 gainNode.gain.value 接收到固定值

  2. 为了能够测试 AGC 的缺失 - 使用 audioContext.createScriptProcessor(...).onaudioprocess 添加了一个图形音频计


问题在于,事实上 AGC 并没有被禁用,Gain 仍然保持动态。

在长时间的单调响亮的声音中,分析仪会在 5-6 秒后降至显着较低的值。

然后在 5-6 秒的沉默后回到之前的范围。


所有这些都在 macOS Catalina 10.15.7 上的以下浏览器中进行了测试:

  • Mozilla Firefox 82.0.3,
  • 谷歌浏览器 86.0.4240.198,
  • Safari 14.0 (15610.1.28.1.9, 15610), 也适用于 iOS 14.2 Safari。

问题:是否有可能关闭 AGC 并不仅“通过听觉”而且通过仪表值来遵循它?

增益固定法的完整代码:

src/web_app/html/index_template.html

    var loadingParams = {
      errorMessages: [],
      isLoopback: false,
      warningMessages: [],

      roomId: '101',
      roomLink: 'https://www.xxxx.com/r/101',

//      mediaConstraints: {"audio": true, "video": true},
      mediaConstraints: {video: {frameRate: 30, width: 640, height: 480}, audio: {echoCancellation: true, noiseSuppression: true, autoGainControl: false}},
      offerOptions: {},
      peerConnectionConfig: {"bundlePolicy": "max-bundle", "iceServers": [{"urls": ["turn:www.xxxx.com:3478?transport=udp", "turn:www.xxxx.com:3478?transport=tcp"], "username": "demo", "credential": "demo"}, {"urls": ["stun:www.xxxx.com:3478"], "username": "demo", "credential": "demo"}], "rtcpMuxPolicy": "require"},
      peerConnectionConstraints: {"optional": []},
      iceServerRequestUrl: 'https://www.xxxx.com//v1alpha/iceconfig?key=',
      iceServerTransports: '',
      wssUrl: 'wss://www.xxxx.com:8089/ws',
      wssPostUrl: 'https://www.xxxx.com:8089',
      bypassJoinConfirmation: false,
      versionInfo: {"time": "Wed Sep 23 12:49:00 2020 +0200", "gitHash": "78600dbe205774c115cf481a091387d928c99d6a", "branch": "master"},
    };

src/web_app/js/appcontroller.js

AppController.prototype.gainStream = function (stream, gainValue) {

                        var max_level_L = 0;
                        var old_level_L = 0;

                        var cnvs = document.createElement('canvas');
                        cnvs.style.cssText = 'position:fixed;width:320px;height:30px;z-index:100;background:#000';
                        document.body.appendChild(cnvs);
                        var cnvs_cntxt = cnvs.getContext("2d");

  var videoTracks = stream.getVideoTracks();

  var context = new AudioContext();
  var mediaStreamSource = context.createMediaStreamSource(stream);
  var mediaStreamDestination = context.createMediaStreamDestination();
  var gainNode = context.createGain();

                        var javascriptNode = context.createScriptProcessor(1024, 1, 1);


  mediaStreamSource.connect(gainNode);
        mediaStreamSource.connect(javascriptNode);
  gainNode.connect(mediaStreamDestination);
        javascriptNode.connect(mediaStreamDestination);

                        javascriptNode.onaudioprocess = function(event){

                                var inpt_L = event.inputBuffer.getChannelData(0);
                                var instant_L = 0.0;

                                var sum_L = 0.0;
                                for(var i = 0; i < inpt_L.length; ++i) {
                                        sum_L += inpt_L[i] * inpt_L[i];
                                }
                                instant_L = Math.sqrt(sum_L / inpt_L.length);
                                max_level_L = Math.max(max_level_L, instant_L);
                                instant_L = Math.max( instant_L, old_level_L -0.008 );
                                old_level_L = instant_L;

                                cnvs_cntxt.clearRect(0, 0, cnvs.width, cnvs.height);
                                cnvs_cntxt.fillStyle = '#00ff00';
                                cnvs_cntxt.fillRect(10,10,(cnvs.width-20)*(instant_L/max_level_L),(cnvs.height-20)); // x,y,w,h

                        }

  gainNode.gain.value = gainValue;

  var controlledStream = mediaStreamDestination.stream;
  for (const videoTrack of videoTracks) {
    controlledStream.addTrack(videoTrack);
  }

  return controlledStream;
};

AppController.prototype.onLocalStreamAdded_ = function(stream) {
  trace('User has granted access to local media.');
  this.localStream_ = this.gainStream(stream, 100);
  this.infoBox_.getLocalTrackIds(this.localStream_);

  if (!this.roomSelection_) {
    this.attachLocalStream_();
  }
};

谢谢!

最好的问候, 安德烈·科斯滕科

【问题讨论】:

    标签: webrtc


    【解决方案1】:

    我认为您遇到的问题是 echoCancellationnoiseSuppression 也修改了信号。既然您提到您正在使用长单调的声音来测试您的代码,那么noiseSuppression 算法很可能试图减少这种“噪音”。

    不幸的是,没有办法知道为什么信号被修改了。您必须相信这里的浏览器实际上已经关闭了增益控制,并且所有剩余的修改都来自其他两种算法。

    如果您不想完全信任浏览器,您也可以尝试使用其他声音来运行测试。它不应该是“嘈杂的”,但很难说浏览器检测到什么是噪音,什么不是。

    【讨论】:

      猜你喜欢
      • 2014-05-07
      • 2012-09-02
      • 2014-04-01
      • 2016-09-16
      • 2014-06-19
      • 2014-12-16
      • 1970-01-01
      • 2021-10-27
      • 2019-10-04
      相关资源
      最近更新 更多