From 721d376f980350758b028bdaaf2ba2ca59be0a91 Mon Sep 17 00:00:00 2001 From: abdu11ahbaig Date: Sun, 13 Sep 2026 00:24:45 +0500 Subject: [PATCH] fix: disable mic AGC by default to stop Windows audio crackle Chromium's realtime AGC crackles on some Realtek/headset mics, heard as repeated breaking and pitch warble. The no-agc fix existed but was hidden behind an env var shipped builds never set. Make it the default; volume is still restored offline via the existing speechnorm/alimiter chain. --- electron/ipc/register/settings.ts | 2 +- src/hooks/useScreenRecorder.test.ts | 12 ++++++------ src/hooks/useScreenRecorder.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/electron/ipc/register/settings.ts b/electron/ipc/register/settings.ts index 93aee878..75b3f81f 100644 --- a/electron/ipc/register/settings.ts +++ b/electron/ipc/register/settings.ts @@ -21,7 +21,7 @@ import { import { parseJsonWithByteOrderMark } from "../utils"; const BROWSER_MICROPHONE_PROFILE_ENV = "RECORDLY_BROWSER_MIC_PROFILE"; -const DEFAULT_BROWSER_MICROPHONE_PROFILE = "processed"; +const DEFAULT_BROWSER_MICROPHONE_PROFILE = "no-agc"; const recordingPreferencesStore = createRecordingPreferencesStore(RECORDINGS_SETTINGS_FILE); const BROWSER_MICROPHONE_PROFILES = new Set([ "processed", diff --git a/src/hooks/useScreenRecorder.test.ts b/src/hooks/useScreenRecorder.test.ts index 1ddceb4e..8a55f8b7 100644 --- a/src/hooks/useScreenRecorder.test.ts +++ b/src/hooks/useScreenRecorder.test.ts @@ -34,12 +34,12 @@ function createMockMediaRecorder(initialState: RecordingState = "inactive") { } describe("createProcessedMicrophoneConstraints", () => { - it("requests browser voice processing with AGC for the default microphone", () => { + it("requests browser voice processing without AGC for the default microphone", () => { expect(createProcessedMicrophoneConstraints()).toEqual({ audio: { echoCancellation: true, noiseSuppression: true, - autoGainControl: true, + autoGainControl: false, channelCount: { ideal: 1 }, sampleRate: { ideal: 48000 }, }, @@ -53,7 +53,7 @@ describe("createProcessedMicrophoneConstraints", () => { deviceId: { exact: "device-123" }, echoCancellation: true, noiseSuppression: true, - autoGainControl: true, + autoGainControl: false, channelCount: { ideal: 1 }, sampleRate: { ideal: 48000 }, }, @@ -105,10 +105,10 @@ describe("createProcessedMicrophoneConstraints", () => { }); }); - it("normalizes invalid lab microphone profiles to production voice processing", () => { + it("normalizes invalid lab microphone profiles to the default voice processing", () => { expect(normalizeBrowserMicrophoneProfile("RAW")).toBe("raw"); - expect(normalizeBrowserMicrophoneProfile("unknown")).toBe("processed"); - expect(normalizeBrowserMicrophoneProfile(null)).toBe("processed"); + expect(normalizeBrowserMicrophoneProfile("unknown")).toBe("no-agc"); + expect(normalizeBrowserMicrophoneProfile(null)).toBe("no-agc"); }); }); diff --git a/src/hooks/useScreenRecorder.ts b/src/hooks/useScreenRecorder.ts index 45965241..6c0e4167 100644 --- a/src/hooks/useScreenRecorder.ts +++ b/src/hooks/useScreenRecorder.ts @@ -51,7 +51,7 @@ export type BrowserCaptureCursorPolicy = { hideOsCursorBeforeRecording: boolean; hideEditorOverlayCursorByDefault: boolean; }; -const DEFAULT_BROWSER_MICROPHONE_PROFILE: BrowserMicrophoneProfile = "processed"; +const DEFAULT_BROWSER_MICROPHONE_PROFILE: BrowserMicrophoneProfile = "no-agc"; const BROWSER_MICROPHONE_PROFILES = new Set([ "processed", "no-agc",