feat(lotus-denoise): AGC off for ML tier + init/build leak hardening
AEC/AGC audit fix + two hardening items from the engine review. - Add an `autoGainControl` capture param (UrlParams -> CallViewModel -> ConnectionFactory audioCaptureDefaults), mirroring echoCancellation/ noiseSuppression. Defaults true (unchanged); the host sets it false only for the ML tier so the browser's auto gain control doesn't fight the in-source ML denoiser (pumping). Echo cancellation stays on. Tests cover the URL parse and the audioCaptureDefaults wiring. - L1: init() now closes the owned AudioContext on a build failure (was orphaned; browsers cap live contexts, so repeated failures could exhaust them). - L2: buildGraph() disposes its partially-built nodes on failure (disposeGraph previously only cleaned the prior graph). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6ab52d9926
commit
940d71da92
@@ -504,6 +504,7 @@ export function createCallViewModel$(
|
||||
options.livekitRoomFactory,
|
||||
getUrlParams().echoCancellation,
|
||||
getUrlParams().noiseSuppression,
|
||||
getUrlParams().autoGainControl,
|
||||
);
|
||||
|
||||
const connectionManager = createConnectionManager$({
|
||||
|
||||
@@ -55,6 +55,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
||||
* @param livekitRoomFactory - Optional factory function (for testing) to create LivekitRoom instances. If not provided, a default factory is used.
|
||||
* @param echoCancellation - Whether to enable echo cancellation for audio capture.
|
||||
* @param noiseSuppression - Whether to enable noise suppression for audio capture.
|
||||
* @param autoGainControl - Whether to enable auto gain control for audio capture.
|
||||
*/
|
||||
public constructor(
|
||||
private client: OpenIDClientParts,
|
||||
@@ -66,6 +67,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
||||
livekitRoomFactory?: () => LivekitRoom,
|
||||
echoCancellation: boolean = true,
|
||||
noiseSuppression: boolean = true,
|
||||
autoGainControl: boolean = true,
|
||||
) {
|
||||
const defaultFactory = (): LivekitRoom =>
|
||||
new LivekitRoom(
|
||||
@@ -81,6 +83,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
||||
controlledAudioDevices: this.controlledAudioDevices,
|
||||
echoCancellation,
|
||||
noiseSuppression,
|
||||
autoGainControl,
|
||||
}),
|
||||
);
|
||||
this.livekitRoomFactory = livekitRoomFactory ?? defaultFactory;
|
||||
@@ -127,6 +130,7 @@ function generateRoomOption({
|
||||
controlledAudioDevices,
|
||||
echoCancellation,
|
||||
noiseSuppression,
|
||||
autoGainControl,
|
||||
}: {
|
||||
devices: MediaDevices;
|
||||
processorState: ProcessorState;
|
||||
@@ -137,6 +141,7 @@ function generateRoomOption({
|
||||
controlledAudioDevices: boolean;
|
||||
echoCancellation: boolean;
|
||||
noiseSuppression: boolean;
|
||||
autoGainControl: boolean;
|
||||
}): RoomOptions {
|
||||
return {
|
||||
...defaultLiveKitOptions,
|
||||
@@ -150,6 +155,7 @@ function generateRoomOption({
|
||||
deviceId: devices.audioInput.selected$.value?.id,
|
||||
echoCancellation,
|
||||
noiseSuppression,
|
||||
autoGainControl,
|
||||
},
|
||||
audioOutput: {
|
||||
// When using controlled audio devices, we don't want to set the
|
||||
|
||||
@@ -53,14 +53,13 @@ beforeEach(() => {
|
||||
|
||||
describe("ECConnectionFactory - Audio inputs options", () => {
|
||||
test.each([
|
||||
{ echo: true, noise: true },
|
||||
{ echo: true, noise: false },
|
||||
{ echo: false, noise: true },
|
||||
{ echo: false, noise: false },
|
||||
{ echo: true, noise: true, agc: true },
|
||||
{ echo: true, noise: false, agc: false },
|
||||
{ echo: false, noise: true, agc: false },
|
||||
{ echo: false, noise: false, agc: true },
|
||||
])(
|
||||
"it sets echoCancellation=$echo and noiseSuppression=$noise based on constructor parameters",
|
||||
({ echo, noise }) => {
|
||||
// test("it sets echoCancellation and noiseSuppression based on constructor parameters", () => {
|
||||
"it sets echoCancellation=$echo, noiseSuppression=$noise, autoGainControl=$agc based on constructor parameters",
|
||||
({ echo, noise, agc }) => {
|
||||
const RoomConstructor = vi.mocked(LivekitRoom);
|
||||
|
||||
const ecConnectionFactory = new ECConnectionFactory(
|
||||
@@ -76,6 +75,7 @@ describe("ECConnectionFactory - Audio inputs options", () => {
|
||||
undefined,
|
||||
echo,
|
||||
noise,
|
||||
agc,
|
||||
);
|
||||
ecConnectionFactory.createConnection(
|
||||
testScope,
|
||||
@@ -90,6 +90,7 @@ describe("ECConnectionFactory - Audio inputs options", () => {
|
||||
audioCaptureDefaults: expect.objectContaining({
|
||||
echoCancellation: echo,
|
||||
noiseSuppression: noise,
|
||||
autoGainControl: agc,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user