Skip to content
anecho.ai
All writing

8 kHz is where voice AI actually breaks

Every voice AI demo is 16 kHz from a laptop mic. Most revenue is 8 kHz from a phone line. We ran a full narrowband benchmark — nothing resampled, three native 8 kHz engines, a round-trip control — and the best path in it ties doing nothing by one word. We also tested the 'resample tax' we had been repeating, and it is not there.

Sofia Marchetti20 Jan 202618 min read
telephonypstnnarrowbandsignal-processingstt

Updated 14 August 2026 with the regenerated Null Test run (18 conditions) and with a new end-to-end narrowband experiment. This update retracts a claim. An earlier version of this post repeated a community report that a major framework's default resample path discards ~16% of caller audio. We built the control for it, and our measurement does not support it. The section is rewritten below rather than deleted.

Every voice AI demo you have seen runs at 16 kHz from a laptop microphone over WebRTC. Almost every dollar of production call volume arrives at 8 kHz from a phone line that has already thrown away the top half of the spectrum. Those are not the same problem, and the second one is where deployments quietly fail.

The gap is not a configuration detail. It is an octave of missing signal, a codec chain nobody controls, a platform layer where — as of writing, and this is our reading of the vendors' docs — you often cannot insert your own processing at all, and a model shelf on which nothing is actually built for the channel.

What a phone line actually removes

PSTN and SIP telephony are 8 kHz narrowband, carried as G.711 µ-law or A-law, with a passband of roughly 300 to 3400 Hz. Sampling at 8 kHz puts the Nyquist limit at 4 kHz, and the channel filter takes another 600 Hz off the top. Everything above 3.4 kHz is simply not present — and that band is where a specific, unusually costly set of phoneme cues lives.

CueWhere its energy isSurvives a 300–3400 Hz channel?
/s/ versus /f/ versus /θ/sibilant energy peaks roughly 4–8 kHzNo. This is the classic narrowband confusion.
Vowel identity (F1, F2)250–2500 HzYes
/r/ and F3 cuesroughly 2000–3500 HzMarginal, right at the cutoff
Plosive burst transientsbroadband, much of it above 4 kHzPartly; bursts are flattened
Nasal murmurbelow 1 kHzYes
Speaker fundamental F085–255 Hz for most adultsUsually below the 300 Hz cutoff; reconstructed perceptually from harmonics

So narrowband errors are not uniformly distributed across your transcript. They cluster exactly where voice agents carry the most business risk: digits ("six" and "fix" lose their most reliable discriminator), spelled-out names and email addresses, confirmation codes, and plurals that hinge on a word-final /s/ or /z/. A 3% aggregate WER lift can be a 30% error rate on the one field the call existed to capture.

The other half of the problem is the recognizer. Whisper and most modern STT models are trained on 16 kHz audio, so narrowband speech is out of distribution before any noise is added.

We tested the resample tax, and it is not there

An earlier version of this post led with a LiveKit community PSA of 7 August 2026 reporting that the default FrameProcessor resample pattern continuously discards audio — roughly 16% of the caller's speech, permanently, on every call — with one operator in the thread recovering nearly eighteen points of STT accuracy by fixing it. We repeated that. It was the most quotable thing in the post.

Then we built the control, and our own measurement does not support it.

The control is simple. Take the narrowband caller audio, send it 8 kHz → 16 kHz → 8 kHz, and measure the SI-SDR of what comes back against what went in. If a resample round trip destroys a fixed fraction of the signal, that number is bad, and it is worse for the sloppier resampler.

8 kHz → 16 kHz → 8 kHzSI-SDR vs its own input
naive — sample-repeat up, sample-drop down, no filtering at all150 dB
linear — linear interpolation, no anti-alias filter150 dB
soxr_hq — polyphase/sinc, library default38.45 dB
soxr_vhq — polyphase/sinc, the correct implementation38.28 dB

Read that twice. The deliberately broken resampler scores a perfect null — 150 dB is the ceiling our harness reports when the difference signal is numerically zero — and the correct one scores 112 dB worse.

Both results are right, and the reason is arithmetic rather than measurement error. At an exact 2:1 ratio, sample-repeat followed by sample-drop is algebraically the identity function — every original sample comes back bit-exact, so there is nothing left to measure. The polyphase resampler scores lower precisely because it does its job: it applies an anti-alias filter, and a filter changes the signal. Round-trip SI-SDR, used naively, rewards the broken implementation. That is the trap, and it is why this needed a control rather than an intuition. (At 44.1 kHz, where the ratio is not an integer, linear drops to 32.49 dB — the identity property is specific to the 2:1 case that telephony actually hits.)

Downstream, on transcription, it is the same story. With no model in the path at all, resampler choice is worth 0.18 points of WER: soxr_vhq scores 10.96% against linear's 11.14%, versus a raw 8 kHz control of 11.14%. On 1,140 reference words that is two words. It is a tie.

And with a model in the path, the result inverts. Across all six model-and-resampler pairs we tested, the naive resampler transcribed better — mean −3.0 points, every single pair negative, from −0.4 (aic-quail with naive) to −5.6 (fastenhancer-b with linear). The likely mechanism is that a polyphase resampler is an extra filtering stage the model was never trained on, while 2:1 nearest-neighbour is an identity, so the naive path hands the model a less altered signal.

So: we are not claiming resampling destroys caller audio, we are not repeating the 16% figure as if it were ours, and we will not sell resampling correctness as recovered accuracy. We do not know what the PSA author's instrumentation was measuring — frame accounting inside a specific pipeline is not the same experiment as ours, and their fix plainly helped their deployment. What we can say is that the general claim, in the form we repeated it, does not reproduce here.

If you take one action from this post, it is still: record the audio your recognizer actually receives, not what your SIP trunk delivers, and compare their durations. Frame accounting is worth checking. It is just not worth a WER point.

The upsampling that fixes nothing

Even a correct resampler restores nothing. You resample 8 kHz to 16 kHz because the model demands 16 kHz input; that satisfies the interface and adds no information. The 4 to 8 kHz octave stays empty, because there was never any energy there to interpolate. What the acoustic model sees is a 16 kHz spectrogram with a dead top half and a hard shelf at 3.4 kHz — a pattern that appears in its training data mostly as a degradation, if at all.

16 kHz mic capture            8 kHz PSTN, upsampled to 16 kHz

8k ┤▓▓▒▒░░ fricatives           8k ┤              (nothing)
6k ┤▓▓▓▒▒░                      6k ┤              (nothing)
4k ┤▓▓▓▓▒▒                      4k ┤──────────── hard shelf
2k ┤████▓▓  formants            2k ┤████▓▓  formants
0  ┤█████▓                      0  ┤ ███▓▓  (HPF at ~300 Hz)
   └──────── time                  └──────── time

So "we support telephony" in most stacks means "we resample and hope." The interesting failure is not the resampler — we just spent a section establishing that — it is that the model on the other side of it is being fed a distribution it never trained on.

What we measured: nothing on the shelf helps on the phone line

We ran the telephony path through Null Test, our open benchmark. Seven of its eighteen conditions are telephony: a G.711 µ-law round trip — resample to 8 kHz, encode, decode, resample back — the same round trip with noise at 10 dB SNR, and five carrier variants (A-law, G.722, Opus at 12 kbps, and bursty packet loss at 3% and 10%).

Provenance, because these numbers are worth exactly what their method is worth: single recogniser, faster-whisper base.en (CTranslate2 int8 CPU, greedy), Silero VAD, 10 speakers / 180 clips / roughly 1406 seconds of audio, about 190 reference words per condition, 18 conditions, 12 backends, Apple M1 Max, onnxruntime 1.28.0 pinned to one intra-op thread. At that sample size one word is worth roughly 0.5 points of WER; read the delta columns accordingly.

BackendG.711Δ vs rawG.711 + noise 10 dBΔ vs raw
Raw (no processing)5.8%10.5%
FastEnhancer-S (MIT)5.3%-0.514.2%+3.7
FastEnhancer-M (MIT)5.8%0.012.1%+1.6
ai-coustics Quail L7.4%+1.612.1%+1.6
ai-coustics Quail VF 2.2 L8.4%+2.69.5%-1.1
GTCRN (MIT)8.9%+3.211.1%+0.5
FastEnhancer-T (MIT)12.6%+6.817.4%+6.8
DeepFilterNet315.3%+9.520.0%+9.5

No enhancer produced a meaningful improvement on telephony audio, and several caused large degradations — FastEnhancer-T at +6.8 points on both conditions, DeepFilterNet3 at +9.5 on both.

Be precise about the two apparent wins, because they are the kind of thing that gets quoted without its error bar. FastEnhancer-S is -0.5 points on the clean row — inside one reference word of doing nothing — and 3.7 worse once noise is added. Quail VF is -1.1 on the noisy row and +2.6 on the clean one. Neither is a win, neither is a loss. The useful reading is that the upside is zero-shaped and the downside runs to ten points.

The five carrier conditions we added in this run tighten that reading rather than changing it. In none of them does any engine beat raw, and in four of the five the best an engine manages is an exact tie:

ConditionRawBest engineWorst engine
A-law7.4%7.4% (Quail L, tie)49.0% (FastEnhancer-M)
G.7225.3%5.3% (FastEnhancer-B, tie)6.8% (FastEnhancer-M)
Opus 12 kbps6.8%6.8% (FastEnhancer-S, tie)12.1% (GTCRN)
3% bursty loss11.1%11.1% (Quail VF, tie)24.7% (DeepFilterNet3)
10% bursty loss10.0%10.5% (Quail L)35.3% (FastEnhancer-T)

The FastEnhancer-M row on A-law is worth staring at: 49.0% against a raw baseline of 7.4%, driven by 61 insertions where raw has 2. Companded quantisation noise is not what that model expects, and it responds by hallucinating. This is the shape of the whole category on a phone line — the ceiling is a tie and the floor is a catastrophe.

DeepFilterNet3's number needs its caveat every time: we measure it through a block-online adapter, because no public ONNX export carries recurrent state tensors, so per-frame streaming is impossible with the published weights. Its rows are a lower bound on quality and an upper bound on cost. The ai-coustics rows are a proprietary baseline run through the licensed SDK — a reference point, never a shipping code path for us.

The experiment that table was missing: 8 kHz end to end

Raw WER on our G.711 condition is 5.8%. That is an easy condition, and every backend in the matrix above is a wideband model pointed at a narrowband signal. It says something specific and limited — wideband enhancers do not help on a narrowband channel and can hurt a lot — and nothing about whether processing natively at 8 kHz beats resampling.

So we built the experiment that answers that. Sixty clips, six narrowband conditions, 8 kHz from end to end with nothing resampled anywhere in the arm, three genuinely native 8 kHz models, and the STT ingest resampler held constant at soxr_vhq in every arm including the controls. 1,140 reference words, so one word is worth 0.09 points of WER — that ratio travels with every number below.

PathWERvs raw 8 kHz
raw 8 kHz (control)11.14%
resample only, no model, soxr_vhq10.96%−0.18
resample only, no model, linear11.14%0.00
native 8 kHz quail-l-8khz11.05%−0.09
native 8 kHz quail-s-8khz11.32%+0.18
native 8 kHz rook-l-8khz12.46%+1.32
upsampled quail (16 kHz weights), soxr_vhq11.75%+0.61
upsampled quail-vf (16 kHz weights), soxr_vhq12.98%+1.84
upsampled gtcrn, soxr_vhq16.58%+5.44
upsampled fastenhancer-b, soxr_vhq17.63%+6.49
upsampled fastenhancer-m, soxr_vhq21.14%+10.00
upsampled fastenhancer-t, soxr_vhq24.82%+13.68

Three things fall out of it, and only one of them is the one we went looking for.

Native 8 kHz does beat resample-and-hope — by 0.7 points. Same vendor, same model family, the only difference being 8 kHz weights against 16 kHz weights on a resampled path: 11.05% against 11.75%. As far as we can find, that comparison has never been published by anyone. It is also about eight words out of 1,140, which makes it a real, directional, modest result and not a headline. It is a reason to build native. It is not a reason to buy anything.

Nothing beat the untouched caller audio. The best path in the table, quail-l-8khz at 11.05%, sits 0.09 points below the raw control's 11.14% — one word. That is a tie, not a win. Every other path is worse than doing nothing. On a narrowband phone call, in August 2026, the null hypothesis is undefeated.

And there is barely anything to test. Look at how short the native section is. Those three models are the entire population of genuinely narrowband enhancement weights we could obtain. GTCRN, FastEnhancer and DeepFilterNet3 have no 8 kHz checkpoint at all — not a worse one, none — so on a phone call they can only be run through a resample wrapper, which is why they appear in this table exclusively as upsampled rows. One vendor ships narrowband weights. Nobody ships narrowband speaker isolation: every ai-coustics Voice Focus model and their primary-speaker VAD is 16 kHz only, while the same vendor does ship 8 kHz for their general enhancer and their human-listening model. Krisp's telephony answer is a variant explicitly positioned as lighter than their main line.

That is the actual finding of this post, and it took us a while to see it because we were busy looking for damage. The problem on the phone line is not that something is breaking your audio. It is that the thing you would want to run on it was never built.

What the matrix still omits is best seen against the real signal chain below, of which our conditions model some stages and not others.

Nobody in the chain is on your side

Even before the band limit, the signal has been through several processing stages you do not control and cannot inspect.

StageTypical processingArtifact class it introducesModelled now?
HandsetAMR-WB or EVS encode, device noise suppression, AGCalready-suppressed speech, musical noise, pumping gainNo
Carrier interconnecttranscode to G.711 µ-law or A-law, G.722, low-bitrate Opus; downsample to 8 kHzband limit, companding quantization noiseYes
SIP trunkjitter buffer, packet loss concealment, DTX, comfort noisetime-domain splices, repeated frames, synthetic noise floorYes — bursty two-state loss at 3% and 10%
Echo pathhybrid or speakerphone return of the agent's own TTSfluent, confident insertionsNo — the biggest remaining gap
Your stackresample to 16 kHz, often a second suppression passempty upper band, cascaded suppressionPartly

The carrier and packet-loss rows moved from "No" to "Yes" in this update, and they are worth a note each.

Packet loss concealment is not silence. When a packet is lost, the jitter buffer synthesises a replacement from previous frames: a plausible waveform with no linguistic content, which a recognizer will happily decode words out of. These are insertions no enhancer can fix, because the signal is not degraded — it is fabricated. We model this as bursty two-state (Gilbert-Elliott) erasure of 20 ms frames with attenuated-repeat concealment, rather than independent random loss with silence fill: independent loss flatters every decoder and silence fill overstates the damage.

The handset already suppressed. The audio is usually suppressed once on the device before you touch it, so you are cascading a second neural suppressor over the artifacts of a first. Nobody has characterised that publicly, us included — though our results do show that a suppression pass over material that does not need one is reliably expensive; see The split pipeline.

Echo is the row that is still missing, and it is the one we most want. Acoustic echo with non-linear speaker distortion is the impairment behind the half of this product that cannot be fixed with a patch, and we have not built the condition for it yet. Until we do — and until Clearline is a row in these tables against a passthrough control allowed to beat it — we have measured the shelf, not our answer to it.

The platform gap

There is a structural reason 8 kHz is under-served: on the highest-volume path, the major platforms do not give you a place to stand. As of writing, and stated as our reading of the published docs:

  • LiveKit's SIP trunk integration exposes standard Krisp noise cancellation only — not the background-voice-cancellation variant available on other paths. The telephony leg, the one with the worst audio, gets the less capable of the two bundled options.
  • On Twilio there is no documented place to tap the media alongside <ConversationRelay> — but this is our inference, not their statement. <Connect> is documented as terminal and the ConversationRelay socket carries JSON only, so Twilio must terminate and re-originate the media. Twilio does not say <Stream> is incompatible, and it does not say it works either; a grep of the <Connect> reference, the ConversationRelay overview and the onboarding pages returns no body text either way. We stated this as fact before checking, which was wrong of us. It is settled by one phone call and we have not made it.
  • ai-coustics' own representative steers telephony customers away from their 8 kHz models toward the 16 kHz one. We read that as a candid engineering answer rather than a slip: the narrowband models are not where their quality is.
  • Every speaker-isolation model in the market is 16 kHz. ai-coustics ships 8 kHz weights for their general enhancer and for their human-listening model, but every Voice Focus variant and their primary-speaker VAD is 16 kHz only. Krisp's telephony entry is a variant positioned as lighter than their main line. Telephony is exactly where competing speakers are worst — contact-centre bullpens, speakerphones, a television in the background — and it is the one place the isolation models will not run.
  • The DNS Challenge — the field's main denoising benchmark series, which most published denoisers are tuned against — never had a narrowband track. If the benchmark that defines the state of the art never scored 8 kHz, the state of the art was never optimised for 8 kHz. Our telephony rows are what that omission looks like from the receiving end.

If any of those readings is wrong, or changes, we will correct this post and note the date. We have already done that once, at the top.

The consequence is that the audio-quality decision on your highest-revenue channel is made for you, by a bundled component you did not choose and cannot measure. Basic noise cancellation is free everywhere by now — that is not the scarce thing. The scarce thing is a model trained for the actual channel, and evidence about whether it helps downstream.

What Clearline is, and what it has to prove

One thing it deliberately does not lead with is bandwidth extension. Predicting the missing 4 to 8 kHz band is possible, but it is generative: it does not recover the caller's /s/, it synthesises a plausible one. That is a real gain for a listener and a large PESQ number, and for a recognizer it is a new way to produce a confident substitution — the error moves from "unrecoverable" to "confidently wrong". The same objective mismatch as everywhere else, at its widest on narrowband.

Clearline is a telephony product rather than a general denoiser. Three commitments, ordered by how much of the argument each one carries:

  • Native 8 kHz primary-speaker isolation. The gap the table above exposes. The model runs at the channel's sample rate, and it keeps the person on the phone rather than the room behind them. Nobody ships this at 8 kHz today; that is the whole reason to build it.
  • Residual echo suppression. A hybrid or a speakerphone leaks the agent's own TTS back into the recogniser as fluent, confident insertions. That is not ambient noise and a denoiser does not fix it. It also does not yet have a condition in our benchmark, which we consider a bigger hole than any number in this post.
  • Correct resampling. Sample counts in equal sample counts out, verified in CI. We are demoting this one deliberately. We used to call it a product feature; the control earlier in this post is why we now call it hygiene. It is correct because correctness is cheap, not because it buys you accuracy.

Where the model itself actually stands, since we would rather say it than be asked. The first Clearline proof of concept has trained and converged, and it is weak: +1.41 dB SI-SDR over the unprocessed mixture (2.90 → 4.31) across 1,200 held-out validation mixtures, where competent target-speaker-extraction systems reach +8 to +12 dB. Architecture experiments are running now. What that result buys us is a working training pipeline on licence-clean data and a model that demonstrably learns; what it does not buy us is a competitive model. Clearline has no WER number, and it appears in no table on this site until it earns one.

The number arrives when Clearline is a row in Null Test, on telephony conditions that include echo, against a passthrough control allowed to beat it — a control that, on the evidence above, currently beats everything. If it does not clear that control, that publishes too. Anything else makes the rest of the numbers on this site worthless, which is the actual asset here.

Also unfilled: how much of narrowband WER is codec artifacts versus band limit, whether bandwidth extension is net-positive for WER, and whether streaming recognizers degrade differently from batch on a narrowband channel.

Where to go next

If you run phone traffic, the first step is not to buy anything. Measure your own 8 kHz path against a passthrough control and read the error decomposition rather than the aggregate. Insertions clustered around silence usually mean packet loss concealment or echo return. Substitutions on sibilants and digits mean the band limit. Deletions of short function words mean something upstream is already suppressing too hard.

The harness is open at github.com/anecho and the full matrix — including every cell where we lose — is at /benchmark. Trying Clearline on your own audio takes an API key, not a sales call: /docs.

Next