---
updatedAt: 2026-10-16T10:34:59.000Z
agentTools:
  projectIndex: https://sdk-docs.krisp.ai/llms.txt
---

# VIVA SDK

Krisp VIVA SDK samples in Python, Node.js, Go, Rust and C++ for Voice Isolation, Turn-Taking and VAD on your servers.

> 📘 Prefer cloud processing?
>
> Voice Isolation is also available as a cloud WebSocket endpoint in the [Krisp API](https://sdk-docs.krisp.ai/docs/realtime-api-overview), with no native library to bundle. See [SDK or API](https://sdk-docs.krisp.ai/docs/sdk-or-api) to compare.

Krisp VIVA SDK is designed to improve turn-taking and STT accuracy in Voice AI Agents.

This is accomplished via 3 very small, CPU-based AI models:

* Voice Isolation model
* Turn-Taking model
* VAD model.

The SDK is designed to be deployed server-side and supports multiple language bindings:

* Python, Node.js, Go, Rust, C++, C

# Voice Isolation model

This model removes background voices and noises from audio stream in real-time by adding a minimum latency (\~20ms). This makes the underlying turn-taking model way more accurate in real-life scenarios where user's audio would have secondary voices.

### Sample Code

```python
import krisp_audio

def log_callback(log_message, log_level):
    print(f"[{log_level}] {log_message}", flush=True)

# initialize Krisp SDK global instance
krisp_audio.globalInit("", log_callback, krisp_audio.LogLevel.Off)

model_info = krisp_audio.ModelInfo()
model_info.path = "/path_to_the/model.kef"

# Create Noise Cleaner with the specified configuration
nc_cfg = krisp_audio.NcSessionConfig()
nc_cfg.inputSampleRate = krisp_audio.SamplingRate.Sr16000Hz
nc_cfg.inputFrameDuration = krisp_audio.FrameDuration.Fd10ms
nc_cfg.outputSampleRate = krisp_audio.SamplingRate.Sr16000Hz
nc_cfg.modelInfo = model_info
# Set to True to enable fp16 low-precision execution for reduced CPU usage on AVX-512 / Armv8-A hardware
nc_cfg.enableLowPrecisionExecution = True
ncFloat = krisp_audio.NcFloat.create(nc_cfg)

noise_suppression_level = 100.0  # 0-100.0
# audio_frames: your 16 kHz mono audio split into 10 ms frames (160 samples each)
for frame in audio_frames:
    processed_frame = ncFloat.process(frame, noise_suppression_level)

# Free the Krisp SDK global instance
ncFloat = None
krisp_audio.globalDestroy()
```
```javascript Node.js
// VIVA Node.js SDK v1.7.0+. UAR build: '@krisp/viva-uar-node-sdk'; v1.6.0 and older: 'krisp-audio-node-sdk'
const krispAudioSdk = require('@krisp/viva-node-sdk');

krispAudioSdk.globalInit("");
const config = {
  inputSampleRate: krispAudioSdk.enums.SamplingRate.Sr16000Hz,
  inputFrameDuration: krispAudioSdk.enums.FrameDuration.Fd10ms,
  outputSampleRate: krispAudioSdk.enums.SamplingRate.Sr16000Hz,
  modelInfo: {
    path: "/path_to_the/model.kef"
  },
  enableLowPrecisionExecution: true // Enable fp16 low-precision execution for reduced CPU usage on avx512 / armv8a hardware
};
let ncFloat = krispAudioSdk.NcFloat.create(config);
let noiseSuppressionLevel = 100.0; // 0-100.0
for (let i = 0; i < numberOfFrames; i++) {
  let frame = getFrame(i);
  const processedFrame = ncFloat.process(frame, noiseSuppressionLevel);
}
ncFloat.destroy();
krispAudioSdk.globalDestroy();
```
```go
package main

import (
	"log"

	"krisp"
)

func main() {
	if err := krisp.GlobalInit(""); err != nil {
		log.Fatal("Failed to initialize Krisp SDK:", err)
	}
	defer krisp.GlobalDestroy()
	ncConfig := krisp.NCSessionConfig{
		InputSampleRate:             krisp.SR24000Hz,
		OutputSampleRate:            krisp.SR24000Hz,
		InputFrameDuration:          krisp.FD10ms,
		EnableLowPrecisionExecution: true, // Set to true to allow fp16 inference on supported AVX-512 or Armv8-A hardware.
		ModelInfo: &krisp.ModelInfo{
			Path: "/path_to_the/model.kef",
		},
	}
	nc, err := krisp.CreateNcFloat(&ncConfig)
	if err != nil {
		log.Fatalf("Failed to create noise cancellation instance: %v", err)
	}
	defer nc.Close()
	noiseSuppressionLevel := 100 // 0-100
	for i := 0; i < len(floatAudioBuf); i += samplesPerFrame {
		err := nc.ProcessFloat(frameFloat, outputFrameFloat, float32(noiseSuppressionLevel))
		if err != nil {
			log.Fatalf("Failed to process frame: %v", err)
		}
	}
}
```
```rust
use krisp_audio_sdk_rust::{
    krisp_global_init, krisp_global_destroy, version, NcSession, NcSessionConfig,
    SamplingRate, FrameDuration, AudioSampleType,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    krisp_global_init(Some(working_dir))?;
    let config = NcSessionConfig {
        input_sample_rate: SamplingRate::Rate24000Hz,
        output_sample_rate: SamplingRate::Rate24000Hz,
        input_frame_duration: FrameDuration::Ms10,
        model_path: model_canonical_path.into_boxed_path(),
        enable_low_precision_execution: true, // fp16 low-precision inference on supported avx512/armv8a hardware
    };
    let mut session = NcSession::new(config, AudioSampleType::Float)?;
    for frame in input_frames.iter() {
        session.process_float(&frame.input, &mut frame.output, noise_suppression_level)?;
    }
    krisp_global_destroy()?;
    Ok(())
}
```
```cplusplus
void logCallback(const std::string& message, Krisp::AudioSdk::LogLevel level)
{
    std::cout << message << std::endl;
}

int main()
{
try
{
    globalInit(L"", logCallback, Krisp::AudioSdk::LogLevel::Off);
    ModelInfo ncModelInfo;
    ncModelInfo.path = weightFilePath; // .kef file
    NcSessionConfig ncCfg =
    {
        inRate,
        frameDurationMillis,
        outRate,
        &ncModelInfo,
        withStats,
        nullptr, // Ringtone model cfg for inbound stream case
        lowPrecisionExecution // Enable fp16/int8/int4 low-precision inference when the model and CPU/runtime support it
    };
    std::shared_ptr<Nc<SamplingFormat>> ncSession = Nc<SamplingFormat>::create(ncCfg);
    while(frameAvailable)
    {
        ncSession->process(inFrame, inFrameSize, outFrame, outFrameSize,
                           noiseSuppressionLevel, withStats ? &perFrameStats : nullptr);
    }
    // ncSession is a shared_ptr. Free pointer before globalDestroy()
    ncSession.reset();
    globalDestroy();
}
catch(std::exception& ex)
{
    // Handle exception
}
}
```

# TT (Turn-Taking)

This model predicts turns and interrupts for Voice AI Agent. It provides much better results than a traditional VAD-only turn-taking algorithm. [Check this article](https://krisp.ai/blog/turn-taking-for-voice-ai/) for more technical details.

End-of-Turn Prediction (TTv3) quickly predicts the end of the user's turn, so human-to-bot conversation stays responsive. The `krisp-viva-tp-v3` model works with all languages. It's used together with VAD: once VAD reports voice, the SDK starts buffering; once VAD reports silence for about 200 ms, it scans the last few seconds of buffered audio to compute the probability that the turn has ended. Pass the voice-activity and bot-speaking state for every frame.

**Models:** `krisp-viva-tp-v3.kef` (from `krisp-viva-tt-models-v9.18`), together with the VAD model `krisp-viva-vad-v2.kef` (from `krisp-viva-vad-models-v9.17`). Moving from TTv2? See the [TTv3 migration guide](https://sdk-docs.krisp.ai/docs/ttv3-migration).

### Sample Code

```python
import krisp_audio

model_info = krisp_audio.ModelInfo()
model_info.path = "krisp-viva-tp-v3.kef"

tt_cfg = krisp_audio.TtSessionConfig()
tt_cfg.inputSampleRate = krisp_audio.SamplingRate.Sr16000Hz
tt_cfg.inputFrameDuration = krisp_audio.FrameDuration.Fd20ms
tt_cfg.modelInfo = model_info

tt_session = krisp_audio.TtFloat.create(tt_cfg)

# called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
tt_output = tt_session.process(input_samples, voice_detected, bot_speaking)
```
```javascript Node.js
const krispAudioSdk = require('@krisp/viva-node-sdk');

const ttConfig = {
    inputSampleRate: krispAudioSdk.enums.SamplingRate.Sr16000Hz,
    inputFrameDuration: krispAudioSdk.enums.FrameDuration.Fd20ms,
    modelInfo: { path: "krisp-viva-tp-v3.kef" }
};

const ttSession = krispAudioSdk.TtFloat.create(ttConfig);

// called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
const ttOutput = ttSession.process(inputFrame, voiceDetected, botSpeaking);
```
```go
config := krisp.TTSessionConfig{
    InputSampleRate:    krisp.SR16000Hz,
    InputFrameDuration: krisp.FD20ms,
    ModelInfo:          &krisp.ModelInfo{Path: "krisp-viva-tp-v3.kef"},
}

ttSession, err := krisp.CreateTTFloat(&config)
if err != nil {
    // handle error
}
defer ttSession.Close()

// called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
ttOutput, err := ttSession.ProcessFloat(inputSamples, voiceDetected, botSpeaking)
```
```rust
use krisp_audio_sdk::{TtSession, TtSessionConfig, SamplingRate, FrameDuration, AudioSampleType};
use std::path::Path;

let config = TtSessionConfig {
    input_sample_rate: SamplingRate::Rate16000Hz,
    input_frame_duration: FrameDuration::Ms20,
    model_path: Path::new("krisp-viva-tp-v3.kef").into(),
};

let tt_session = TtSession::new(config, AudioSampleType::Float)?;

// called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
let tt_output = tt_session.process_float(&input_samples, voice_detected, bot_speaking)?;
```
```cplusplus C++
#include "krisp-audio-sdk-tt.hpp"

Krisp::AudioSdk::ModelInfo modelInfo;
modelInfo.path = L"krisp-viva-tp-v3.kef";

Krisp::AudioSdk::TtSessionConfig config;
config.inputSampleRate = Krisp::AudioSdk::SamplingRate::Sr16000Hz;
config.inputFrameDuration = Krisp::AudioSdk::FrameDuration::Fd20ms;
config.modelInfo = &modelInfo;

auto ttSession = Krisp::AudioSdk::Tt<float>::create(config);

float ttOutput = 0.0f;
// called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
ttSession->process(inputSamples, numInputSamples, voiceDetected, botSpeaking, &ttOutput);
```
```c C
#include "c_api/krisp-audio-sdk-tt-c.h"

KrispModelInfo modelInfo = {0};
modelInfo.path = L"krisp-viva-tp-v3.kef";

KrispTtSessionConfig config = {0};
config.inputSampleRate = Sr16000Hz;
config.inputFrameDuration = Fd20ms;
config.modelInfo = &modelInfo;

krispTtHandle ttHandle = krispCreateTtFloat(&config);

float ttOutput = 0.0f;
// called once per incoming audio frame, with voice-activity and bot-speaking state for that frame
krispProcessTtFloat(ttHandle, inputSamples, numInputSamples, voiceDetected, botSpeaking, &ttOutput);

krispDestroyTt(ttHandle);
```

# VAD (Voice Activity Detection)

This model is high-quality VAD. It's trained with Krisp's other models (their outputs) and provides higher-accuracy than industry's other models. It's highly recommended to use Krisp's all components together for maximum value.

### Sample Code

```python
import krisp_audio

def log_callback(log_message, log_level):
    print(f"[{log_level}] {log_message}", flush=True)

# Initialize Krisp SDK
krisp_audio.globalInit("", log_callback, krisp_audio.LogLevel.Off)

model_info = krisp_audio.ModelInfo()
model_info.path = "/path_to_the/model.kef"

# Create VAD session with the specified configuration
vad_cfg = krisp_audio.VadSessionConfig()
vad_cfg.inputSampleRate = krisp_audio.SamplingRate.Sr16000Hz
vad_cfg.inputFrameDuration = krisp_audio.FrameDuration.Fd10ms
vad_cfg.modelInfo = model_info
vadFloat = krisp_audio.VadFloat.create(vad_cfg)

# Processing fixed sized audio frames
for frame in audioFrames:
    voiceProbability = vadFloat.process(frame)
    if voiceProbability > 0.5:
        # Consider voice is detected in the frame
        print("Voice detected")

# Free the resource allocated for the audio stream processing
vadFloat = None
# Free the resources allocated by Krisp SDK
krisp_audio.globalDestroy()
```
```cplusplus
void logCallback(const std::string& message, Krisp::AudioSdk::LogLevel level)
{
    std::cout << message << std::endl;
}

int main()
{
try
{
    globalInit(L"", logCallback, Krisp::AudioSdk::LogLevel::Off);
	
    ModelInfo modelInfo;
    modelInfo.path = weightFilePath; // .kef file
    VadSessionConfig vadCfg =
    {
        inRate,
        frameDurationMillis,
        &modelInfo
    };
	
    float voiceProbability = 0.0;
    std::shared_ptr<Vad<SamplingFormat>> vadSession = Vad<SamplingFormat>::create(vadCfg);
    while(frameAvailable)
    {
        vadSession->process(inFrame, inFrameSize, &voiceProbability);
        if (voiceProbability > 0.5)
        {
            // Consider voice is detected in the frame
        }
    }
	
    // vadSession is a shared_ptr. Free pointer before globalDestroy()
    vadSession.reset();
    globalDestroy();
}
catch(std::exception& ex)
{
    // Handle exception
}
}
```

# Krisp SDK Action Sequence

| Action                                    | Description                                                                                                                                                                                                                                                                                                 |
| :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SDK initialization                        | SDK library should be loaded and initialized before being used. The SDK occupies resources that should be released once the SDK is no longer needed.                                                                                                                                                        |
| Model initialization                      | SDK ships with voice isolation, Turn-Taking and VAD models. Each model has specific requirements for the device and the sampling rate. Each model should be initialized and loaded into the memory before it can be used.                                                                                   |
| Audio stream handling preparation         | In order to process the sound stream a **session** object should be created. The **session** creation is coupled to the AI model which should be specified during the **session** creation process. The **session** object also requires the specification of the **sampling rate** and **frame duration**. |
| Frame processing                          | Frame processing is done using the **session** object which works only for the given **sampling rate** for the given **frame duration** using the loaded AI model.                                                                                                                                          |
| Releasing audio stream handling resources | Resources occupied by the **session** should be released once the **session** is no longer used.                                                                                                                                                                                                            |
| Unloading the SDK                         | Resources loaded by the SDK should be released once the SDK is no longer needed                                                                                                                                                                                                                             |

<Callout icon="📘" theme="info">
  * Multiple sessions can be created and used at the same time
  * Each session can be processed in a different thread on another audio stream
  * A dummy Session can preload model into memory, while a separate Session could handle the actual stream processing. This approach may be helpful to reduce latency before processing begins, as the second Session will utilize the cached model data preloaded by the first Session and will be created much faster than the first Session.
</Callout>

<Callout icon="❗️" theme="warn">
  The SDK should be unloaded only after the release of all sessions
</Callout>

# Sub pages

* [Platforms](https://sdk-docs.krisp.ai/docs/supported-platforms-server.md)
* [Known Issues](https://sdk-docs.krisp.ai/docs/troubleshooting.md)

# Sibling pages

* [RTC SDK](https://sdk-docs.krisp.ai/docs/getting-started-with-rtc-sdk.md)
* [Web SDK Reference](https://sdk-docs.krisp.ai/docs/api-reference.md)