onespeech
Speech recognition for .NET, in C#. OneSpeech transcribes audio, times words, labels speakers and supports live sessions in managed .NET 10.
Open source, MIT or Apache-2.0, made by Recursive AI. Version 1.0.0 is on NuGet, for .NET 10. Open-weight models run on onemodel; oneaudio decodes and resamples audio. No native inference runtime is required. OneSpeech is unaffiliated with other products or companies named OneSpeech.
A quick look
One call returns a timed, diarized, language-tagged transcript. Failed word timing is null, never invented, and a speaker label is anonymous and local to the document.
The output shown is from a run on 1.0.0 from NuGet, on a three-second LibriSpeech recording whose reference text is “stuff it into you his belly counselled him”. The default file model, Whisper large-v3-turbo, heard “stuffered”. Getting started has the whole program.
Getting startedTranscript t = Speech.Transcribe( "1089-134686-0001.flac", language: "en"); Console.WriteLine(t.Text); // stuffered into you, his belly counseled him. foreach (Word w in t.Words.Take(3)) Console.WriteLine($"{w.Start} {w.Text}"); // 00:00:00.5460000 stuffered // 00:00:00.8660000 into // 00:00:01.1860000 you, foreach (Turn turn in t.Turns) Console.WriteLine(turn.Speaker.Id); // speaker-1 File.WriteAllText("t.json", t.ToJson());
What it does
Transcription
Whisper large-v3-turbo is the file default; Whisper tiny to large-v3, Qwen3-ASR 0.6B and 1.7B and Moonshine are selected by name. Long files are chunked at speech boundaries with constant PCM memory. Output as text, JSON, SRT or VTT.
Transcribing filesWord timing
Each word records how it was timed: native timestamps first, then Qwen3-ForcedAligner, omniASR-CTC and DTW. “Failed word timing is null, never invented.” Speech.Align times text you already have, up to 60 seconds.
Speaker labels
The default diarizer, Silero VAD with CAM++ embeddings and clustering, labels who spoke when, merged into the transcript. It doesn’t detect overlapping speech; Nemotron 3 Diarization is an opt-in, overlap-aware upgrade.
DiarizationLive sessions
Speech.Listen “emits replacing partials, immutable finals, endpoints and speaker turns on one audio clock.” It reads mono 16 kHz PCM you supply; it doesn’t capture a microphone. Moonshine streaming tiny is the live default.
Speaker recognition
Speech.Enroll, Identify and Verify, held in process memory only. Speaker embeddings are biometric data. Obtain informed consent, limit retention and access, and check applicable law, including Illinois BIPA and GDPR Article 9, before enrollment, identification or verification.
Offline and captions
Model packages put CAM++ English and Moonshine weights in your build, so a live session needs no download. .Media reads MP4, MKV and other containers and writes SRT, VTT, ASS and TTML; .Cli is the onespeech tool.
What it is compared with
Each row below is from the project’s release revalidation, on full LibriSpeech test-clean and test-other or 20,000 fixed speaker trials. “‘Within noise’ means the difference interval includes zero.”
| OneSpeech, against | Verdict |
|---|---|
| Whisper large-v3-turbo and small, fp32, against openai-whisper 20250625 | Within noise |
| Whisper large-v3-turbo and small, mixed-int8, against faster-whisper 1.2.1 (CT2 4.8.5 int8) | Within noise |
| Moonshine streaming tiny, offline, against Transformers 5.22.2 | Within noise |
| CAM++ English against ModelScope 1.40.2, and ECAPA-TDNN against SpeechBrain 1.1.2 (EER and minDCF) | Within noise |
- Word error rate. Whisper large-v3-turbo fp32 scores 2.267% on test-clean against the reference’s 2.289%, and 4.275% on test-other against 4.331%.
- Speed. “The tier-1 live default meets real time on one core on both machines, with 0 B/chunk of our working allocation. This does not imply that all file models run in real time on one core: turbo’s measured RTF is 1.712 on 60 seconds and 1.332 on 600 seconds.”
- Scope. In the results’ own words, “these results are not a cross-hardware guarantee,” and “No speed comparison with a native implementation is made here.”
Models by role, and their licences
“Tier 1 is ungated MIT/Apache-2.0/BSD and may be redistributed and selected by default. Tier 2 loads only from pinned publisher files, never from our mirror or model packages, never by default.”
| Role | Models | Tier / licence | Selection |
|---|---|---|---|
| File recognition | Whisper tiny/base/small/large-v3; large-v3-turbo | 1 / Apache-2.0; turbo MIT | Turbo default |
| File recognition | Qwen3-ASR 0.6B / 1.7B | 1 / Apache-2.0 | By name; 1.7B accuracy option |
| Live / edge recognition | Moonshine English tiny/base and streaming tiny/small/medium | 1 / MIT | Streaming-tiny live default |
| Recognition | Parakeet-TDT-0.6B-v3 | 2 / CC-BY-4.0 | By name only |
| Timing | Qwen3-ForcedAligner-0.6B; omniASR-CTC-300M | 1 / Apache-2.0 | Timing policy |
| Voice activity | Silero VAD 6.2.3 | 1 / MIT | Embedded |
| Diarization | Silero + CAM++ + spectral/AHC clustering | 1 / MIT + Apache-2.0 | Default; no overlap detection |
| Diarization | Nemotron 3 Diarization | 2 / OpenMDW-1.1 | Explicit overlap-aware upgrade |
| Segmentation | pyannote segmentation-3.0 / community-1 | 2 / MIT gated / CC-BY-4.0 gated | Local segmentation-3.0 + our overlap-aware clustering; community-1 reference only |
| Speaker embeddings | CAM++ English/Chinese; ECAPA-TDNN | 1 / Apache-2.0 | CAM++ English default; Chinese for Chinese speech |
Known limits at 1.0.0
- Overlapping speech. “The default clustering diarizer does not detect overlapping speech.” The Nemotron upgrade “does not separate simultaneous voices.”
- No microphone.
Speech.Listenconsumes caller-supplied PCM. “It does not capture a microphone.” - First use. “The
modelargument selects a role, not the entire pipeline.” Transcription also needs a speaker embedder and, without native timings, aligners: “Even Whisper tiny can require several GB on first use.”Speech.PrefetchAsyncprepares a machine ahead of time. - Streaming and alignment.
TranscribeStream“does not perform whole-file speaker assignment,” and standaloneAlign“accepts at most 60 seconds.”
Voices are biometric data
“Speaker embeddings are biometric data. Obtain informed consent, limit retention and access, and check applicable law, including Illinois BIPA and GDPR Article 9, before enrollment, identification or verification.”
The library does not persist embeddings; your application remains responsible for audio, transcripts, logs and any copies it keeps. In the README’s words, “This is not legal advice.”
Status and packages
- Core
RecursiveAI.OneSpeech: recognition, alignment, diarization, speakers, live sessions and the transcript JSON. It depends on oneaudio and onemodel only. - Media
RecursiveAI.OneSpeech.Media: container input, SRT, VTT, ASS and TTML, and caption muxing, using onemedia. - Command line
RecursiveAI.OneSpeech.Cli: theonespeech.NET tool. - Model packages
RecursiveAI.,OneSpeech. Models. CamPlusEnglish .MoonshineTiny,.MoonshineBaseand.MoonshineStreamingTiny. Each covers only its own model, not every roleTranscribeuses. - Status
1.0.0, all seven packages on one version: the first release.
- .NET
.NET 10, C#. NativeAOT and trim clean, no native code. MIT or Apache-2.0.