Hear your own mic in your headphones — sidetone for Windows — so you stop raising your voice just because you have headphones on. A single small native executable: event-driven WASAPI at the smallest period the drivers allow, with optional RNNoise noise suppression (the same suppressor Discord's classic "Noise Suppression" toggle used) so you don't hear your own keyboard.
Built for the setup where headset sidetone can't help: a desk mic (Shure, etc.) plus separate headphones. The two devices run on different clocks; Hearback corrects the drift by slipping single samples so latency can't creep up.
.\build.ps1 # needs Visual Studio Build Tools (C++ workload)
.\build\hearback.exe --list # see your devices
.\build\hearback.exe # default mic -> default outputPick devices by index or name substring:
.\build\hearback.exe --in mv6 --out g733| flag | meaning |
|---|---|
--list |
list devices with index, rate, and minimum period |
--in <sel> / --out <sel> |
device index (c1, r0) or name substring; default: system defaults |
--ns on|off |
RNNoise noise suppression (default on; requires the mic at 48000 Hz; adds 10 ms) |
--gate <0..1> |
additionally hard-mute when RNNoise's voice probability is below the threshold (try 0.6 to fully kill keyboard between sentences; default off) |
--deess <0..1> |
de-esser strength (default 0.5; off disables). Ducks the 5.5 kHz+ band only while an S is happening, zero added latency |
--gain <dB> |
sidetone volume, -30..+30 (default 0; output is soft-limited) |
--exclusive |
exclusive-mode output: lowest latency and invisible to recorders, but monopolizes the output device (see below) |
--raw |
bypass the mic's "audio enhancement" APOs for this stream |
--period <ms> |
force a larger period if you hear glitches |
--mute, --duration <s>, --quiet |
start muted / timed run / no status line |
While running: m mute, n toggle noise suppression, d toggle de-esser,
[ / ] gain ±2 dB, q quit.
Unity gain will sound much quieter than you actually are: the sidetone has to
compete with hearing yourself through bone conduction, plus the headset's
isolation, and desk mics are usually gain-staged conservatively. Talk normally
and tap ] until the playback feels as loud as your voice does with the
headphones off — typically +10 to +20 dB — then bake it in with e.g.
--gain 14. The output is soft-limited above roughly −3 dBFS, so getting loud
saturates gently instead of clipping in your ears.
Expect S sounds to feel harsher than "you": bone conduction never carries your
own sibilance to your ears, so hearing it at full mic fidelity is jarring even
when the signal is accurate. The de-esser (on by default) ducks the sibilant
band only while an S is happening; it affects the sidetone only, never what
calls hear. Toggle it with d to compare, tune with --deess.
True zero is only possible in hardware (a headset's own sidetone, or the headphone jack on the back of the mic). In software the floor is the sum of the two devices' buffer periods, which Hearback drives to the driver minimum and then protects with a governor that trims any backlog:
| stage | cost |
|---|---|
| capture period | device minimum (2.7–10 ms typical; shown in --list) |
| noise suppression | +10 ms when on (RNNoise processes 480-sample frames) |
| ring + render queue | ~1 render period + 2 ms safety each |
The status line shows the live ring depth; the startup banner prints the expected total. To minimize latency:
- Set both devices to 48000 Hz in Windows sound settings (Advanced tab). A mismatch forces a resampler and the mic rate gates RNNoise entirely.
- Prefer the physical mic over vendor "virtual" devices (Shure MOTIV Mix Virtual Output etc.) — those add their own processing buffers.
--exclusiveif the output isn't shared with games/Discord.- Toggle
nto feel the 10 ms difference; some people prefer raw + no NS.
The mic itself is recorded by whatever records your mic — that's unavoidable and usually the point. The question is whether the sidetone playback leaks into desktop-audio recordings and doubles your voice:
| recorder type | shared mode (default) | --exclusive |
|---|---|---|
| full-desktop loopback (OBS "Desktop Audio", ShadowPlay/Game Bar system audio, "Stereo Mix") | heard | silent |
| per-application capture (OBS "Application Audio Capture", Discord screen-share audio, game-process capture) | silent | silent |
Exclusive mode hands Hearback the endpoint directly, bypassing the Windows mixer — loopback taps the mixer, so there is nothing for it to capture. The cost: no other app can play to that output while Hearback runs, so use it on a dedicated output, not the headphones your game audio uses.
--ns runs the classic RNNoise GRU model (vendored under third_party/,
BSD-3-Clause) on the sidetone only — it does not change what other people hear
in calls; Discord/whatever still applies its own suppression to the mic.
RNNoise attenuates keyboard strongly while you speak; --gate 0.6 silences the
gaps completely. The gate opens in ~2 ms and releases over ~120 ms so speech
onsets don't clip.
- Silence, no meter movement — Windows Settings → Privacy → Microphone → allow desktop apps.
--exclusivefails — enable "Allow applications to take exclusive control" on the device's Advanced tab, close apps playing to it, and make sure its default format matches the mic rate.- Sidetone dips during calls — shouldn't happen (Hearback opts out of communications ducking); check Sound Control Panel → Communications tab.
- Crackles — try
--period 10, or check the status line:slip/trimare normal in small amounts, growingundermeans the machine is starving the audio threads.
Task Scheduler → Create Task → trigger At log on → action
...\build\hearback.exe --quiet, and tick "Run only when user is logged on"
so it can access your devices.