Skip to main content

Noise & echo cancellation

Achieve crystal-clear audio for video conferencing and voice AI.

Overview

User microphones can capture unwanted audio such as background noise (traffic, music) and even echoes from their own speakers. This degrades the experience for other participants in a call. In voice AI apps, it can also interfere with turn detection and reduce transcription quality.

LiveKit Cloud includes access to advanced noise cancellation models (Krisp and ai-coustics) so agents receive crystal-clear audio. Audio sent through LiveKit Cloud can use these models regardless of where your agent runs. See Agents for setup. For pricing details, see the AI voice and video agents and Media transport sections of the pricing page.

LiveKit SDKs support WebRTC noise and echo cancellation for conferencing apps via echoCancellation and noiseSuppression in any deployment. WebRTC cancellation runs in the client only, so it applies to conferencing. For agents and telephony (where there is no browser frontend), use the LiveKit Cloud models above. Adjust WebRTC settings with the AudioCaptureOptions type during connection. See WebRTC noise and echo cancellation in the Frontend section for more information.

To hear the effect of enhanced noise cancellation, play the samples below:

Agents

Enhanced noise cancellation is available when you use LiveKit Cloud for realtime transport. This applies noise cancellation to inbound audio and is the recommended approach for most voice AI use cases. There are two types of noise cancellation:

Voice isolation works well when there is a single speaker, while background noise suppression is better for multiple speakers and diarization. LiveKit supports two providers for enhanced noise cancellation: Krisp and ai-coustics.

Tip

The ai-coustics plugin is built for use in the Python and Node.js agents SDK only, and is not supported on clients for video conferencing.

Try the free noise canceller tool with your LiveKit Cloud account to test your own audio samples.

Tip

When using noise or background voice cancellation in the agent code, do not enable noise cancellation models in the frontend. Noise cancellation models are trained on raw audio and might produce unexpected results if the input has already been processed by a noise cancellation model in the frontend.

Standard noise cancellation and the separate echo cancellation feature can be left enabled.

Installation

Install the package for your chosen provider (Krisp or ai-coustics):

# Krisp
uv add "livekit-plugins-noise-cancellation~=0.2"
# ai-coustics
uv add "livekit-plugins-ai-coustics"
# Krisp
pnpm add @livekit/noise-cancellation-node
# ai-coustics
pnpm add @livekit/plugins-ai-coustics

Voice isolation

Voice isolation emphasizes the primary speaker and suppresses competing speech and background noise. It improves clarity for the agent when multiple people or noise are present.

Upcoming pricing changes

Krisp BVC usage will incur an additional cost beginning May 1, 2026.

Available models

ModelDescription
Krisp BVCRemoves background voices and noise for headset or earbud users. Includes built-in noise cancellation (NC). Optimized for single-speaker scenarios where cross-talk from nearby people could confuse transcriptions or turn detection.
Krisp BVCTelephonyBackground voice cancellation optimized for telephony applications. Use for SIP participants. In Python, use a selector to dynamically choose BVCTelephony or BVC per participant. In Node.js, pass TelephonyBackgroundVoiceCancellation() directly as the fixed model.
ai-coustics QUAIL_VF_LVoice Focus mode with realtime audio enhancement and speaker isolation. Optimized for agent pipelines to improve STT accuracy and turn detection.

Listen to the same gym membership sample with original audio, Krisp BVC, and ai-coustics Voice Focus (QUAIL_VF_L). Transcripts are from Deepgram Nova 3. Segments marked with a strikethrough indicate unwanted content that would confuse the agent.

Original

STT by Deepgram Nova 3
Can I get you the How peaceful Okay? Did you catch the halftime show? I think about that it was a Spanish Yes. I've just received an email that my gym membership is canceled.

Krisp BVC

STT by Deepgram Nova 3
Oh, please. Four. Okay. Yes. I've just received an email that my gym membership is canceled.

ai-coustics Voice Focus (QUAIL_VF_L)

STT by Deepgram Nova 3
How peaceful? Okay. Yes. I've just received an email that my gym membership is canceled.

The following table compares word error rate (WER) for the original audio and each model. WER is the percentage of errors (insertions, deletions, and substitutions) relative to the total words in a reference transcript:

ModelWER
Original117.6%
Krisp BVC23.5%
ai-coustics Voice Focus (QUAIL_VF_L)11.8%

Basic implementation

Include the filter in the room input options when starting your agent session:

from livekit.agents import room_io
from livekit.plugins import ai_coustics # or noise_cancellation
# ...
await session.start(
# ...,
room_options=room_io.RoomOptions(
audio_input=room_io.AudioInputOptions(
noise_cancellation=ai_coustics.audio_enhancement(model=ai_coustics.EnhancerModel.QUAIL_VF_L),
# or noise_cancellation.BVC()
# or noise_cancellation.BVCTelephony()
),
),
)
# ...
import * as aiCoustics from '@livekit/plugins-ai-coustics';
// or BackgroundVoiceCancellation from '@livekit/noise-cancellation-node'
// or TelephonyBackgroundVoiceCancellation from '@livekit/noise-cancellation-node'
// ...
await session.start({
// ...,
inputOptions: {
noiseCancellation: aiCoustics.audioEnhancement({ model: 'quailVfL' }),
},
});
// ...

Custom implementation

Use this when you create an AudioStream from a track yourself. Apply the filter when constructing the stream so that the frames you read are already filtered:

from livekit.rtc import AudioStream
from livekit.plugins import ai_coustics # or noise_cancellation
stream = AudioStream.from_track(
track=track,
noise_cancellation=ai_coustics.audio_enhancement(model=ai_coustics.EnhancerModel.QUAIL_VF_L),
# or noise_cancellation.BVC()
# or noise_cancellation.BVCTelephony()
)
import { AudioStream } from '@livekit/rtc-node';
import * as aiCoustics from '@livekit/plugins-ai-coustics';
// or BackgroundVoiceCancellation from '@livekit/noise-cancellation-node'
// or TelephonyBackgroundVoiceCancellation from '@livekit/noise-cancellation-node'
const stream = new AudioStream(track, {
noiseCancellation: aiCoustics.audioEnhancement({ model: 'quailVfL' }),
});

Background noise suppression

Background noise suppression reduces non-speech noise such as traffic, fans, and music. Use it when the main challenge is environmental noise rather than competing speakers. For voice removal, see Voice isolation.

Available models

ModelDescription
Krisp NCRemoves environmental background noise such as traffic, fans, and music while preserving all speech.
ai-coustics QUAIL_LMachine-optimized audio enhancement for agent performance.

Listen to the same gym membership sample with original audio, Krisp NC, and ai-coustics Quail (QUAIL_L). Transcripts are from Deepgram Nova 3. Segments marked with a strikethrough indicate unwanted content that would confuse the agent.

Original

Original light waveform
STT by Deepgram Nova 3
Can I get you the How peaceful Okay? Did you catch the halftime show? I think about that it was a Spanish Yes. I've just received an email that my gym membership is canceled.

Krisp NC

Krisp NC light waveform
STT by Deepgram Nova 3
Oh, peaceful. Okay. That's an off time show? I just received an email that my gym membership is canceled.

ai-coustics Quail (QUAIL_L)

ai-coustics Quail (QUAIL_L) light waveform
STT by Deepgram Nova 3
How peaceful? Okay. I buy that with Yes. I've just received an email that my gym membership is canceled.

Basic implementation

Include the filter in the room input options when starting your agent session:

from livekit.agents import room_io
from livekit.plugins import ai_coustics # or noise_cancellation
# ...
await session.start(
# ...,
room_options=room_io.RoomOptions(
audio_input=room_io.AudioInputOptions(
noise_cancellation=ai_coustics.audio_enhancement(model=ai_coustics.EnhancerModel.QUAIL_L),
# or noise_cancellation.NC()
),
),
)
# ...
import * as aiCoustics from '@livekit/plugins-ai-coustics';
// or NoiseCancellation from '@livekit/noise-cancellation-node'
// ...
await session.start({
// ...,
inputOptions: {
noiseCancellation: aiCoustics.audioEnhancement({ model: 'quailL' }),
},
});
// ...

Custom implementation

Use this when you create an AudioStream from a track yourself. Apply the filter when constructing the stream so that the frames you read are already filtered:

from livekit.rtc import AudioStream
from livekit.plugins import ai_coustics # or noise_cancellation
stream = AudioStream.from_track(
track=track,
noise_cancellation=ai_coustics.audio_enhancement(model=ai_coustics.EnhancerModel.QUAIL_L),
# or noise_cancellation.NC()
)
import { AudioStream } from '@livekit/rtc-node';
import * as aiCoustics from '@livekit/plugins-ai-coustics';
// or NoiseCancellation from '@livekit/noise-cancellation-node'
const stream = new AudioStream(track, {
noiseCancellation: aiCoustics.audioEnhancement({ model: 'quailL' }),
});

Additional options

The following options apply on top of the voice isolation or background noise suppression setup above.

Selectors

ONLY Available in
Python

When you pass a fixed model, every participant in the session receives the same noise cancellation. A selector lets the SDK call your function for each new participant and track, so different participants can receive different models in the same session without additional routing logic. For example, use BVCTelephony for SIP participants and BVC for others:

from livekit import rtc
from livekit.plugins import noise_cancellation
# Pass as the noise_cancellation argument in AudioInputOptions:
noise_cancellation=lambda params: noise_cancellation.BVCTelephony()
if params.participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP
else noise_cancellation.BVC(),

Enhancement level (ai-coustics)

The ai-coustics plugin exposes an enhancement level parameter (enhancement_level in Python, enhancementLevel in Node.js) to control how aggressively the model processes audio. The value ranges from 0.0 (minimal processing) to 1.0 (maximum enhancement). When omitted, the model applies its built-in default.

The ai-coustics audio samples on this page use an enhancement level of 0.8.

from livekit.plugins import ai_coustics
ai_coustics.audio_enhancement(
model=ai_coustics.EnhancerModel.QUAIL_L,
model_parameters=ai_coustics.ModelParameters(
enhancement_level=0.8,
),
)
import * as aiCoustics from '@livekit/plugins-ai-coustics';
aiCoustics.audioEnhancement({
model: 'quailL',
modelParameters: {
enhancementLevel: 0.8,
},
})

VAD adapter (ai-coustics)

The ai-coustics plugin includes a built-in VAD adapter for turn detection. Because VAD runs inside the ai-coustics model, you can skip running a separate VAD (such as Silero) entirely. Pass VAD() to AgentSession and the noise cancellation filter in room_options (Python) or inputOptions (Node.js) when calling session.start():

from livekit.agents import AgentSession, room_io
from livekit.plugins.ai_coustics import audio_enhancement, VAD, EnhancerModel
session = AgentSession(
vad=VAD(),
# ...
)
await session.start(
# ...,
room_options=room_io.RoomOptions(
audio_input=room_io.AudioInputOptions(
noise_cancellation=audio_enhancement(model=EnhancerModel.QUAIL_L),
),
),
)
import { voice } from '@livekit/agents';
import * as aic from '@livekit/plugins-ai-coustics';
const session = new voice.AgentSession({
vad: aic.vad(),
// ...
});
await session.start({
// ...,
inputOptions: {
noiseCancellation: aic.audioEnhancement(),
},
});

Telephony

Krisp noise cancellation can be applied directly at your SIP trunk for inbound or outbound calls. This uses the standard Krisp noise cancellation (NC) model. Other models are not available for SIP.

Inbound

Include krisp_enabled: true in the inbound trunk configuration.

{
"trunk": {
"name": "My trunk",
"numbers": ["+15105550100"],
"krisp_enabled": true
}
}

See the full inbound trunk docs for more information.

Outbound

Include krisp_enabled: true in the CreateSipParticipant request.

request = CreateSIPParticipantRequest(
sip_trunk_id = "<trunk_id>",
sip_call_to = "<phone_number>",
room_name = "my-sip-room",
participant_identity = "sip-test",
participant_name = "Test Caller",
krisp_enabled = True,
wait_until_answered = True
)

See the full outbound call docs for more information.

Frontend

Noise cancellation in the frontend applies to outbound audio before it is sent to the room.

Krisp

The following examples show how to set up noise cancellation in the frontend using Krisp. This applies noise cancellation to outbound audio. The BVC model is available in the JavaScript frontend; other frontend SDKs support the NC model only.

PlatformOutboundBVCPackage
Web@livekit/krisp-noise-filter
SwiftLiveKitKrispNoiseFilter
Androidio.livekit:krisp-noise-filter
Flutterlivekit_noise_filter
React Native@livekit/react-native-krisp-noise-filter
UnityN/A
Tip

When using noise or background voice cancellation in the frontend, do not enable Krisp noise cancellation in the agent code. Standard noise cancellation and the separate echo cancellation feature can be left enabled.

Installation

npm install @livekit/krisp-noise-filter

This package includes the Krisp SDK but not the models, which download at runtime to minimize the impact on your application's bundle size.

React components usage

LiveKit Components includes a convenient useKrispNoiseFilter hook to easily integrate Krisp into your React app:

import { useKrispNoiseFilter } from '@livekit/components-react/krisp';
function MyKrispSetting() {
const krisp = useKrispNoiseFilter();
return (
<input
type="checkbox"
onChange={(ev) => krisp.setNoiseFilterEnabled(ev.target.checked)}
checked={krisp.isNoiseFilterEnabled}
disabled={krisp.isNoiseFilterPending}
/>
);
}

Base JS SDK usage

For other frameworks or advanced use cases, use the KrispNoiseFilter class directly:

import { type LocalAudioTrack, Room, RoomEvent, Track } from 'livekit-client';
const room = new Room();
// We recommend a dynamic import to only load the required resources when you enable the plugin
const { KrispNoiseFilter } = await import('@livekit/krisp-noise-filter');
room.on(RoomEvent.LocalTrackPublished, async (trackPublication) => {
if (
trackPublication.source === Track.Source.Microphone &&
trackPublication.track instanceof LocalAudioTrack
) {
if (!isKrispNoiseFilterSupported()) {
console.warn('Krisp noise filter is currently not supported on this browser');
return;
}
// Once instantiated, the filter will begin initializing and will download additional resources
const krispProcessor = KrispNoiseFilter();
console.log('Enabling LiveKit Krisp noise filter');
await trackPublication.track.setProcessor(krispProcessor);
// To enable/disable the noise filter, use setEnabled()
await krispProcessor.setEnabled(true);
// To check the current status use:
// krispProcessor.isEnabled()
// To stop and dispose of the Krisp processor, simply call:
// await trackPublication.track.stopProcessor()
}
});

Available models

The JavaScript noise filter supports the standard Krisp noise cancellation (NC) and background voice cancellation (BVC) models.

Compatibility

Not all browsers support the underlying Krisp SDK (including Safari <17.4). Use isKrispNoiseFilterSupported() to check if the current browser is supported.

Installation

Add the package to your build.gradle file:

dependencies {
implementation "io.livekit:krisp-noise-filter:0.0.10"
}

Get the latest SDK version number from Maven Central.

Usage

val krisp = KrispAudioProcessor.getInstance(getApplication())
coroutineScope.launch(Dispatchers.IO) {
// Only needs to be done once.
// This should be executed on the background thread to avoid UI freezes.
krisp.init()
}
// Pass the KrispAudioProcessor into the Room creation
room = LiveKit.create(
getApplication(),
overrides = LiveKitOverrides(
audioOptions = AudioOptions(
audioProcessorOptions = AudioProcessorOptions(
capturePostProcessor = krisp,
)
),
),
)
// Or to set after Room creation
room.audioProcessingController.setCapturePostProcessing(krisp)

Available models

The Android noise filter supports only the standard Krisp noise cancellation (NC) model.

Installation

Add a new package dependency to your app by URL:

https://github.com/livekit/swift-krisp-noise-filter

Or in your Package.swift file:

.package(url: "https://github.com/livekit/swift-krisp-noise-filter.git", from: "0.0.7"),

Usage

Here is a simple example of a SwiftUI app that uses Krisp in its root view:

import LiveKit
import SwiftUI
import LiveKitKrispNoiseFilter
// Keep this as a global variable or somewhere that won't be deallocated
let krispProcessor = LiveKitKrispNoiseFilter()
struct ContentView: View {
@StateObject private var room = Room()
var body: some View {
MyOtherView()
.environmentObject(room)
.onAppear {
// Attach the processor
AudioManager.shared.capturePostProcessingDelegate = krispProcessor
// This must be done before calling `room.connect()`
room.add(delegate: krispProcessor)
// You are now ready to connect to the room from this view or any child view
}
}
}

For a complete example, view the Krisp sample project.

Available models

The Swift noise filter supports only the standard Krisp noise cancellation (NC) model.

Compatibility

Installation

npm install @livekit/react-native-krisp-noise-filter

This package includes both the Krisp SDK and the required models.

Usage

import { KrispNoiseFilter } from '@livekit/react-native-krisp-noise-filter';
import { useLocalParticipant } from '@livekit/components-react';
import { useMemo, useEffect } from 'react';
function MyComponent() {
let { microphoneTrack } = useLocalParticipant();
const krisp = useMemo(() => KrispNoiseFilter(), []);
useEffect(() => {
const localAudioTrack = microphoneTrack?.audioTrack;
if (!localAudioTrack) {
return;
}
localAudioTrack?.setProcessor(krisp);
}, [microphoneTrack, krisp]);
}

Available models

The React Native noise filter supports only the standard Krisp noise cancellation (NC) model.

Installation

Add the package to your pubspec.yaml file:

dependencies:
livekit_noise_filter: ^0.1.0

Usage

import 'package:livekit_client/livekit_client.dart';
import 'package:livekit_noise_filter/livekit_noise_filter.dart';
// Create the noise filter instance
final liveKitNoiseFilter = LiveKitNoiseFilter();
// Configure room with the noise filter
final room = Room(
roomOptions: RoomOptions(
defaultAudioCaptureOptions: AudioCaptureOptions(
processor: liveKitNoiseFilter,
),
),
);
// Connect to room and enable microphone
await room.connect(url, token);
await room.localParticipant?.setMicrophoneEnabled(true);
// You can also enable/disable the filter at runtime
// liveKitNoiseFilter.setBypass(true); // Disables noise cancellation
// liveKitNoiseFilter.setBypass(false); // Enables noise cancellation

Available models

The Flutter noise filter supports only the standard Krisp noise cancellation (NC) model.

Compatibility

The Flutter noise filter is currently supported only on iOS, macOS, and Android platforms.

WebRTC noise and echo cancellation

As an alternative to Krisp, the LiveKit SDKs support built-in outbound noise and echo cancellation based on the WebRTC implementations of echoCancellation and noiseSuppression. You can adjust these settings with the AudioCaptureOptions type in the LiveKit SDKs during connection. Leaving these WebRTC settings on is strongly recommended when you are not using enhanced noise cancellation (Krisp or ai-coustics).

Original

Original light waveform

WebRTC noiseSuppression

WebRTC noiseSuppression light waveform