Build Krisp
KINDAreplaces $16/mosaves $192/yrback to the verdict
A virtual microphone that appears in every application's input list, pulls from your real microphone, runs a noise suppression model in the audio callback without ever missing a deadline, and offers a lower latency model for live calls and a heavier one for recordings.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree if you own one
Why The virtual device is a Core Audio server plug-in, which is a macOS concept. The equivalent on other platforms is a different project.
Get it Apple menu, then About This Mac.
Verify
About This Mac reports macOS 13 or higher - installfree
Why Builds the application and the plug-in, and provides Instruments for the timing work in Phase 2.
Get it Mac App Store or developer.apple.com/xcode. open ↗
Verify
xcodebuild -version prints 16 or higher - decidefree
Why An audio callback that allocates or blocks produces clicks the user hears and you cannot reproduce. This is the one part of the build where the usual habits are actively wrong.
Get it Read about real-time safety before Phase 2. The rule is short: no allocation, no locks, no system calls, no unbounded work.
Verify
You can state why a mutex in the audio callback is a bug rather than a risk - have readyfree, but check each licence for redistribution
Why These are the two models the profiles use. Their latency and compute difference is the product decision in Phase 3.
Get it Build RNNoise from its repository, which is small and BSD licensed. DeepFilterNet ships a real-time capable build; check its current licence before bundling. open ↗
Verify
Both process a test file and their added latency is measured - have readyfree
Why Steady fan noise is where every model succeeds. The differences appear on background speech, sudden clatter and reverberation.
Get it Record them yourself: a fan, a café, a keyboard and a room with hard walls. Keep them as fixtures.
Verify
All four are saved with their noise floor measured
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- This is a real-time audio path, so the state that matters is timing rather than tables. - device · the published virtual input, its sample rate, its buffer size and its channel count - profiles(id, name, model, expected_latency_ms, cpu_budget_pct) · one for calls, one for recordings - stats · rolling callback duration, deadline misses, dropouts, all visible in the interface - The deadline is the whole design: at a 48 kHz sample rate with a 256 frame buffer you have roughly 5.3 milliseconds to return, every time, without exception.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DEVICE_SAMPLE_RATE | required | 48000 | The published device's sample rate. Applications will resample if they need something else. |
DEVICE_BUFFER_FRAMES | required | 256 | Frames per callback. This sets the deadline: 256 frames at 48 kHz is roughly 5.3 milliseconds. |
DEFAULT_PROFILE | required | calls | Which profile is active by default. Calls means the lighter, lower latency model. |
DEADLINE_MISS_THRESHOLD | required | 5 | Misses per minute before the application falls back to the lighter model and says so. |
OFFLINE_OUTPUT_DIR | required | ~/Music/Denoised | Where offline processed files are written. Never the source directory. |
The build, in order
A virtual device that appears in other applications
Your device shows up in the input list of an application you did not write, and passes audio through unchanged.
A minimal Core Audio server plug-in publishing one input device with a fixed sample rate and channel count. Install it and restart the audio daemon to load it.
Files
plugin/terminalsudo killall coreaudiod
Real microphone in, virtual device out, no processing. Verify bit-for-bit where you can.
Files
plugin/passthrough.cA conferencing application and a recorder. Your own test harness will not reveal the sample rate and buffer size assumptions real applications make.
done when · tick each as it passeswatch out- A server plug-in runs inside a system audio daemon rather than in your application, so a crash in it takes down audio for the whole machine and a debugger cannot attach the way you expect. Keep the plug-in minimal and put every piece of logic you can into your own process, communicating over a shared buffer.
Processing without missing a deadline
Noise suppression runs in the audio path and the callback always returns in time.
Every buffer allocated at start-up, a lock-free ring buffer between threads, and no system calls in the callback.
Files
audio/ring.cIt expects a specific frame size, so buffer to that size rather than assuming the host's buffer matches.
Files
audio/denoise.cDuration and deadline misses, aggregated off the audio thread and shown in the interface.
Files
audio/stats.c
done when · tick each as it passeswatch out- Allocating memory, taking a lock or logging inside the audio callback will eventually block for longer than the deadline, and the result is a click that the user hears and you cannot reproduce. Preallocate everything, use a lock-free ring buffer, and move logging out to another thread.
Two models, two purposes
You can choose clean audio or low latency, and the interface tells you the cost.
Same buffer contract, different implementation. Switching is swapping the processor, not rebuilding the path.
Files
audio/models/Round trip through the device, measured rather than quoted. Hardware varies enough that the paper figure is not your figure.
Files
audio/latency.cCalls and recordings, with the measured numbers shown underneath. Not good and better.
Files
ui/Profiles.swift
done when · tick each as it passeswatch out- Roughly 40 milliseconds of added latency is not noticeable when you listen back to a recording and is very noticeable in a conversation, where it sits on top of network delay and makes people talk over each other. Label the profiles by purpose rather than by quality, so the choice is obvious.
Recording mode, where latency does not matter
Files get the best available quality because nothing is waiting on them.
No deadline, full lookahead, best model. This is a different code path on purpose.
Files
offline/process.cWrite a new file alongside. Checksum the source before and after as a test.
Files
offline/process.cA noise floor measurement from a silent passage, so the improvement is a number rather than an impression.
Files
offline/report.c
done when · tick each as it passeswatch out- Reusing the real-time path for files throws away the one advantage offline processing has, which is that it can look ahead. Run the file path without the deadline and without the streaming constraints, and it will beat the live path on the same recording.
Behaving well on a real machine
It survives the things that actually happen: devices changing, sleep, and processor pressure.
Subscribe to Core Audio device notifications and reconfigure the path. Test by unplugging things during a stream.
Files
audio/devices.cTear down and rebuild the path around sleep rather than assuming it survives.
Files
audio/lifecycle.cIf deadline misses rise, switch to the lighter model and tell the user. A dropout is worse than a quality reduction.
Files
audio/adaptive.c
done when · tick each as it passeswatch out- Audio device configuration changes at the worst moments: someone plugs in headphones mid-call. If the plug-in does not handle the change it either produces silence or crashes the audio daemon, and the user's call ends. Subscribe to device change notifications and reconfigure rather than assuming a stable configuration.
Signing, installation and model licencesproduct builder
It installs on someone else's machine, and every model you ship is one you may ship.
Hardened runtime for the application, correct signing for the plug-in, and an installer package.
terminalxcrun notarytool submit Denoise.zip --keychain-profile AC --wait
Removing a system plug-in by hand is not something you should ask of anyone. Test that audio still works afterwards.
Files
scripts/uninstall.shRNNoise is BSD licensed. Check the terms of anything else you bundle, because permissive is not universal.
Files
docs/models.md
done when · tick each as it passeswatch out- Installing a server plug-in means writing into a system location and restarting the audio daemon, which briefly interrupts audio for everything running. Warn before doing it, and never do it silently during a call.
That is the whole plan for Krisp. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- The commercial model's quality on hard noise.
- Echo cancellation.
- Mobile applications and per-application switching polish.
- Speaker-side suppression of what you hear.
- low-latency virtual microphone
- polished app switching
- model quality
- meeting integrations
- admin controls
- A meter showing suppressed noise in real time, which makes the effect visible
- Echo cancellation, accepting that it is a larger problem than suppression
- A Windows build, which needs an entirely different virtual device approach
Need the files? The project pack on the verdict page hands your agent the whole brief · more audio & video.