The Krisp JavaScript SDK provides a powerful noise cancellation solution for web-based applications. By integrating the Krisp JS SDK into your React app, you can create a seamless audio communication experience for your users by removing background noise from their audio streams.

This guide will walk you through the steps to integrate the Krisp JS SDK into your React app, and provide you with the code snippets necessary to get started. By following this guide, you'll be able to take full advantage of Krisp's advanced noise cancellation technology and provide your users with crystal-clear audio.

Let’s go over the steps.

Step 1: Creating a React app using create-react-app

The first step is to create a new React app using the create-react-app command. This will create a new project directory with all the necessary files and dependencies to get started. You can name your app anything you like, but for this example, we'll call it "my-app". If you’re integrating into an existing React project, skip this step.

npx create-react-app my-app

Step 2: Adding Krisp's JS SDK to your project

The next step is to add Krisp's JS SDK to your project. Copy the dist folder into your project directory. This folder contains the necessary JS SDK code and models.

Step 3: Importing KrispSDK in your App.js file

Once you have added the Krisp JS SDK to your project, you can import it into your App.js file using the import statement.

import KrispSDK from './dist/krispsdk';

if you are using typescript, you should also import IAudioFilterNode

import KrispSDK,{ IAudioFilterNode } from './dist/krispsdk';

Step 4: Initializing necessary states to store SDK information

In order to keep track of the status of the SDK, you'll need to initialize some states. You can do this using the useState hook. In this example, we initialize the states for whether the SDK has started, whether it is ready, and whether it is enabled.

const [started, setStarted] = useState(false); 
const [isReady, setIsReady] = useState(false); 
const [isEnabled, setIsEnabled] = useState(null);

Step 5: Initializing refs for corresponding elements

You'll also need to initialize some refs to correspond with different elements in your application. This will allow you to interact with these elements from within your code.

const audioElement = useRef(); // to play the audio
const sdk = useRef(); // to store our sdk
const stream = useRef(); // to store user media
const filterNode = useRef(); // to store our filter
const audioContext = useRef(new AudioContext()); // to store AudioContext
const source = useRef(); // to store MediaStreamSource
const destination = useRef(); // to store MediaStreamDestination

Note: if you are using typescript, IAudioFilterNode will be used as a type for the filterNode

const filterNode = useRef<IAudioFilterNode>();

Step 6: Handling the SDK start

In order to start using the SDK, you'll need to create an async handler function that initializes the SDK and sets up the necessary audio elements. This involves creating a new KrispSDK instance, getting user media with your preferred audio settings, resuming the audio context, initializing the SDK, creating a new noise filter, and connecting the filter to the audio elements.

The code will look something like this

const onStart = async () => {
    setStarted(true);

    sdk.current = new KrispSDK({
      params: {
        logProcessStats: false,
        debugLogs: false,
        models: {
          model8: "/dist/models/model_8.kw",
          model16: "/dist/models/model_16.kw",
          model32: "/dist/models/model_32.kw",
        },
        useSharedArrayBuffer: false
      },
      callbacks: {
        errorCallback: () => {},
      },
    });

    const audioSettings = {
      audio: {
        echoCancellation: true,
        noiseSuppression: false,
        autoGainControl: false,
      },
    };

    stream.current = await navigator.mediaDevices.getUserMedia(audioSettings);

    await audioContext.current.resume();
    sdk.current.init();

    filterNode.current = await sdk.current.createNoiseFilter(
      audioContext.current,
      () => setIsReady(true)
    );

    source.current = audioContext.current.createMediaStreamSource(
      stream.current
    );
    destination.current = audioContext.current.createMediaStreamDestination();

    source.current.connect(filterNode.current);
    filterNode.current.connect(destination.current);

    if (audioElement.current) {
      audioElement.current.srcObject = destination.current.stream;
      audioElement.current.play();
    }
};

Step 7: Handling the filter node toggle functionality

Once the SDK is up and running, you can handle the filter node toggle functionality using another handler function. This function toggles the enabled state of the filter node.

const onToggle = () => {
    if (filterNode.current?.isEnabled()) {
      filterNode.current.disable();
      setIsEnabled(false);
    } else {
      filterNode.current?.enable();
      setIsEnabled(true);
    }
  };

Step 8: Handling the SDK destroy

Finally, you'll need to create an async handler function to destroy the SDK and clean up any audio elements. This involves disconnecting the source and destination, stopping all the tracks of the audio stream, disconnecting and disposing the filter node, suspending the audio context, disposing the SDK, and pausing the audio element.

The code will look something like this

const onDestroy = async () => {
    if (source.current) source.current.disconnect();
    if (destination.current) destination.current.disconnect();
    if (stream.current)
      stream.current.getTracks().forEach((track) => track.stop());
    if (filterNode.current) filterNode.current.disconnect();
    await filterNode.current?.dispose();
    if (audioContext) await audioContext.current.suspend();

    sdk.current?.dispose();
    audioElement.current?.pause();

    setStarted(false);
    setIsEnabled(null);
};

Step 9: Add the audioElement ref to JSX

To render the audio in your React app, you will need to add the audioElement ref to your JSX code. This is done by creating an audio tag and assigning the ref to the audioElement ref. You can also add attributes such as autoPlay and controls to customize the appearance and behavior of the audio tag.

<audio
  ref={audioElement}
  id="audio"
  autoPlay={true}
  controls={true}
/>

In conclusion, by following these steps, you can easily integrate Krisp's JS SDK into your React app and use it to remove background noise from audio input and output. Remember to handle the SDK start, filter node toggle functionality, and SDK destroy properly to ensure smooth performance and resource management.