Vencord / Vesktop

Vesktop is a custom Discord App aiming to give you better performance and improve linux support
GNU General Public License v3.0
2.81k stars 142 forks source link

Automatic Gain Control toggle #161

Open Vendicated opened 8 months ago

Vendicated commented 8 months ago

Discord has a toggle for automatic gain control. It currently has no effect on vesktop though. it would be great to implement it

Plarpoon commented 7 months ago

Hi all, wanted to report that the problem described in issue #142 is still present in the current version!

I myself didn't realize it was Vesktop bug so I actually spent a day looking at pavucontrol and banging my head against it. Thank you for reporting that it cannot be disabled, you put my mind at peace!

PopLamina commented 5 months ago

This really needs to be fixed, very infuriating.

makidoll commented 5 months ago

It might be a little cursed but I cloned the project locally and added the source code from this chrome extension into src/renderer/index.ts. It patches getUserMedia and such to permanently disable agc.

https://chromewebstore.google.com/detail/disable-automatic-gain-co/clpapnmmlmecieknddelobgikompchkk

jessicamaybe commented 4 months ago

It might be a little cursed but I cloned the project locally and added the source code from this chrome extension into src/renderer/index.ts. It patches getUserMedia and such to permanently disable agc.

https://chromewebstore.google.com/detail/disable-automatic-gain-co/clpapnmmlmecieknddelobgikompchkk

Would you mind sharing your changes if possible?

makidoll commented 4 months ago
diff --git a/src/renderer/index.ts b/src/renderer/index.ts
index ebe6bc6..d891c26 100644
--- a/src/renderer/index.ts
+++ b/src/renderer/index.ts
@@ -57,3 +57,81 @@ VesktopNative.arrpc.onActivity(data => {

     arRPC.handleEvent(new MessageEvent("message", { data }));
 });
+
+// force disable automatic gain control
+
+(function () {
+    function setLegacyChromeConstraint(constraint, name, value) {
+        if (constraint.mandatory && name in constraint.mandatory) {
+            constraint.mandatory[name] = value;
+            return;
+        }
+        if (constraint.optional) {
+            const element = constraint.optional.find(opt => name in opt);
+            if (element) {
+                element[name] = value;
+                return;
+            }
+        }
+        // `mandatory` options throw errors for unknown keys, so avoid that by
+        // setting it under optional.
+        if (!constraint.optional) {
+            constraint.optional = [];
+        }
+        constraint.optional.push({ [name]: value });
+    }
+    function setConstraint(constraint, name, value) {
+        if (constraint.advanced) {
+            const element = constraint.advanced.find(opt => name in opt);
+            if (element) {
+                element[name] = value;
+                return;
+            }
+        }
+        constraint[name] = value;
+    }
+    function disableAutogain(constraints) {
+        console.log("Automatically unsetting gain!", constraints);
+        if (constraints && constraints.audio) {
+            if (typeof constraints.audio !== "object") {
+                constraints.audio = {};
+            }
+            if (constraints.audio.optional || constraints.audio.mandatory) {
+                setLegacyChromeConstraint(constraints.audio, "googAutoGainControl", false);
+                setLegacyChromeConstraint(constraints.audio, "googAutoGainControl2", false);
+            } else {
+                setConstraint(constraints.audio, "autoGainControl", false);
+            }
+        }
+    }
+
+    function patchFunction(object, name, createNewFunction) {
+        if (name in object) {
+            var original = object[name];
+            object[name] = createNewFunction(original);
+        }
+    }
+
+    patchFunction(navigator.mediaDevices, "getUserMedia", function (original) {
+        return function getUserMedia(constraints) {
+            disableAutogain(constraints);
+            return original.call(this, constraints);
+        };
+    });
+    function patchDeprecatedGetUserMedia(original) {
+        return function getUserMedia(constraints, success, error) {
+            disableAutogain(constraints);
+            return original.call(this, constraints, success, error);
+        };
+    }
+    patchFunction(navigator, "getUserMedia", patchDeprecatedGetUserMedia);
+    patchFunction(navigator, "mozGetUserMedia", patchDeprecatedGetUserMedia);
+    patchFunction(navigator, "webkitGetUserMedia", patchDeprecatedGetUserMedia);
+    patchFunction(MediaStreamTrack.prototype, "applyConstraints", function (original) {
+        return function applyConstraints(constraints) {
+            disableAutogain(constraints);
+            return original.call(this, constraints);
+        };
+    });
+    console.log("Disable Autogain by Joey Watts!", navigator.mediaDevices.getUserMedia);
+})();
Silvea12 commented 3 months ago

Hey, @Vendicated is there anything that the above patch would need for me to make an MR to fix this that would make this suitable to be merged into mainline? The issue is quite irritating, so I'll happily fix it myself if you're busy.

jvyden commented 1 month ago

For Nix users I wrote this to include the above patch by @makidoll with your build.

It also extends the patch to disable echo cancellation.

      (vesktop.overrideAttrs (previousAttrs: {
        patches = previousAttrs.patches ++ [
          (fetchpatch {
            name = "micfix-b0730e139805c4eea0d610be8fac28c1ed75aced.patch";
            url = "https://gist.githubusercontent.com/jvyden/4aa114a1118a06f3be96710df95f311c/raw/b0730e139805c4eea0d610be8fac28c1ed75aced/micfix.patch";
            hash = "sha256-EIK7/CtKpruf4/N2vn8XSCNkyDCL8I6ciXOljkvgz5A=";
          })
        ];
      }))
Foxite commented 1 month ago

Is there a reason there isn't a pull request with the fix, and why hasn't the fix made it into main yet?

VoidgirlChloe commented 1 day ago

Is there a chance of this being fixed? This thread seems awfully abandoned and it is an irritating issue... I'm not sure why it is even changing the system audio in the first place, but any way to disable it would be greatly appreaciated

PavelDobCZ23 commented 8 hours ago

For now, if anybody wants this resolved, add this argument to your .desktop file of Vesktop: --disable-features=WebRtcAllowInputVolumeAdjustment