SPEAKSEE LAB · POC

Auto-Detect Language

How often a speech-to-text API changes language when the speaker did not — and how fast it follows a change that is real.

Which APIs can be measured in real time?

4 of 13 vendor(s) can be called from this box right now, 4 of them over a realtime stream. Everything else is in the folded list below.

ProviderLive auto-detectCan we call it? How we reach itWhat its detector does
Azure AI Speech docs ↗ yes measured with LID
linked and measured with its detector switched on — the recipe as delivered states a language, and this POC carries the configuration that takes that back out, so it is applied for this vendor whether or not the run asked for it
realtime stream
LID available
detects and keeps switching mid-stream
Deepgram docs ↗ yes measured with LID
linked and measured with its detector switched on — the recipe as delivered states a language, and this POC carries the configuration that takes that back out, so it is applied for this vendor whether or not the run asked for it
realtime stream
LID available
detects and keeps switching mid-stream
Soniox Speech-to-Text docs ↗ yes measured
linked to this POC and callable without naming the language
realtime stream
LID available
detects and keeps switching mid-stream
Speechmatics docs ↗ yes measured with LID
linked and measured with its detector switched on — the recipe as delivered states a language, and this POC carries the configuration that takes that back out, so it is applied for this vendor whether or not the run asked for it
realtime stream
LID available
detects and keeps switching mid-stream
3 linked vendor(s) are measured with their detector switched on. Azure AI Speech, Deepgram, Speechmatics state a language in the recipe as delivered, so a plain call would be told the answer this POC measures. The configuration that takes that statement back out (src/lid.py, or the portal's detect block) is applied for these vendors on every run — ticked or not.
What the columns mean two different questions, and why a vendor is skipped
Live auto-detect is what the vendor's own docs claim — the hypothesis under test. Can we call it? is whether a run can put audio in front of it today, which is about the portal's recipes and what has been linked. A vendor whose recipe states a language is skipped rather than measured: the call would be told the answer this POC exists to measure.

7 of 13 vendor(s) claim live detection. A realtime stream is one connection for the whole sample, paced at 1×, every result stamped with the moment it arrived — the only method here with no window floor in its latencies.
The other 9 provider(s) batch-only, not linked, or no recipe on this box — none of them can be measured in real time from here
ProviderLive auto-detectCan we call it? How we reach itWhat its detector does
AssemblyAI docs ↗ no no recipe
the portal has no recipe for this vendor, so nothing here can call it at all
auto-detect only on pre-recorded audio, not live
AWS Transcribe docs ↗ yes no recipe
the portal has no recipe for this vendor, so nothing here can call it at all
detects once at the start, then holds that language
Cartesia Ink-Whisper docs ↗ unread not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
nobody has read this vendor's live-detection docs yet
ElevenLabs Scribe docs ↗ unread not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
nobody has read this vendor's live-detection docs yet
Fish Audio ASR docs ↗ unread not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
nobody has read this vendor's live-detection docs yet
Gladia docs ↗ yes no recipe
the portal has no recipe for this vendor, so nothing here can call it at all
detects and keeps switching mid-stream
Google Cloud Speech-to-Text docs ↗ yes not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
detects once at the start, then holds that language
Mistral Voxtral Transcribe docs ↗ unread not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
nobody has read this vendor's live-detection docs yet
OpenAI Whisper docs ↗ no not linked
the portal carries a recipe, but it is not linked to this POC — link it on the Providers tab to include it
auto-detect only on pre-recorded audio, not live

Run the language-change test

Samples that are each in one language, a different one every time, played down one open connection per API. The audio inside a sample never changes language, so every change a vendor makes there is a change nobody asked for — that count is the number this test is about.

→ 6 sample(s) of 12s, 2s apart · 5 real language change(s) per API · none at all inside a sample · about 84s of audio per API, paced at 1× and billed.

Also: how fast does it follow a real switch?

Samples that do change language, sent to every callable API above with no language named, scored against the sample's own millisecond-exact timeline.

→ 4 turns of 3.0s, up to 6 samples of about 13.2s each · sample set 1 of 20 · 4 vendor(s) over a realtime stream, the rest windowed at 1000 ms.

Every number below came out of a real call. This costs money. what is measured, and what the method still cannot see
The samples are human speech from FLEURS, spliced on a timeline this POC wrote itself, and you can play every one of them below. Every call names no language — naming one would hand the provider the answer this POC exists to measure.

Where the vendor has a realtime endpoint the sample is streamed to it over one connection, paced at 1× real time, and every result is stamped with the moment it arrived. That is the method that answers the question: no window floor, the vendor's own rolling context, and a lag that is what a viewer would really have waited. Where it has only a batch endpoint the sample is cut into 1000 ms windows and each is POSTed — one billed call per window — and every latency then carries a floor of one window, which is reported with it. Each provider's row says which method it was.

Language identification is asked per vendor, not per run. A vendor that can be called honestly as delivered is called unconfigured when the box is unticked — what most integrations actually ship — and configured when it is ticked; both are real measurements of different questions, and each provider's row says which one it was. A vendor whose recipe states a language is a different case: a plain call would hand it the answer, so this POC applies the configuration that removes that statement (src/lid.py, or the portal's detect block) for that vendor on every run, and its row carries the LID on badge. The alternative was not a plainer measurement of those vendors — it was no measurement at all, which is what this page used to print four paragraphs of.

Fetch · en, nl (dev)

done 14.3s
fetching 2 language(s) into /app/fixtures/corpus/fleurs the index for each language is fetched first — a wrong locale fails there, in a second, instead of after the audio archive en (en_us): index … en (en_us): audio archive (this is the big one) … en (en_us): unpacking … en (en_us): 394 file(s) nl (nl_nl): index … nl (nl_nl): audio archive (this is the big one) … nl (nl_nl): unpacking … nl (nl_nl): 171 file(s) done — 2/2 language(s), 565 recording(s) on disk