OneSpeech also does speaker verification: get a similarity score for two voice recordings. It’s a score, not a probability or a yes/no decision.
dotnet add package RecursiveAI.OneSpeechRequires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using OneSpeech; double score = Speech.Verify( "first.wav", "second.wav"); Console.WriteLine( $"Cosine similarity: {score:0.0000}"); Speech.ClearSpeakers();
The zip includes the two synthetic speech files used here.
Unzip the example, then dotnet run. It prints:
Cosine similarity: 0.8994Full program
The sample files use an eSpeak NG synthetic voice, not an identifiable person. first.wav says “This is a synthetic voice sample for a software demonstration.” second.wav says “A second sentence lets us compare two recordings of the same synthetic voice.” These demonstration recordings are provided under CC0; their score is not a biometric test result.
The full program clears loaded speaker models in finally. English CAM++ is the default speaker-embedding model. On first use it downloads 29.4 MB of publisher weights and creates another 29.4 MB of converted model files in the cache (decimal MB, rounded). Samples are downmixed and resampled to mono 16 kHz; each must contain at least 45 ms and at most 60 seconds, or the call refuses it.
using OneSpeech; try { double score = Speech.Verify("first.wav", "second.wav"); Console.WriteLine($"Cosine similarity: {score:0.0000}"); } finally { Speech.ClearSpeakers(); }
Output from dotnet run:
Cosine similarity: 0.8994Variations
Read encoded audio streams instead of paths. This replaces the full program and prints the same output above. The streams remain open until the using declarations dispose them.
using OneSpeech; using var first = File.OpenRead("first.wav"); using var second = File.OpenRead("second.wav"); try { double score = await Speech.VerifyAsync(first, second); Console.WriteLine($"Cosine similarity: {score:0.0000}"); } finally { Speech.ClearSpeakers(); }
Related recipes
The short answer
Use Speech.Verify(firstPath, secondPath) to get the raw cosine similarity of two speaker embeddings. No enrollment is needed. The result is a score, not a yes/no authentication decision and not the probability that the recordings contain the same person. The speaker recognition documentation defines this distinction explicitly.
What is the range of cosine similarity values?
The verification helper returns a cosine in the range [-1, 1]. A larger score means the embedding vectors point in more similar directions. It does not mean that the same fraction of identity has been established. The example’s synthetic recordings produce 0.8994; interpreting that as “89.94% certain” would be wrong.
There is no universal threshold in the example. A threshold turns scores into decisions and must be evaluated on disjoint development trials for the actual application. The library’s low-level registry permits a caller-controlled threshold, but an illustrative value is not a biometric operating point for every population or recording environment. Evaluate both erroneous matches and rejected genuine comparisons before adopting a policy.
Keep formatting separate from decisions. Rounding the score for display is convenient, but the displayed decimal string should not become your stored measurement or a claimed confidence level. The walkthrough prints four decimal places only to make the example easy to compare when you run it.
What is speaker identification?
Identification compares a query against enrolled names. Verification compares two samples directly. In OneSpeech, Enroll and Identify serve the first task; Verify serves the second. An empty enrollment registry cannot establish an identity, and verification does not need that registry to contain anything.
Diarization is different again: it labels who spoke when with anonymous recording-local IDs. A label such as speaker-1 is not a person’s name and is not evidence of a verified identity. Even a document containing multiple named clusters has not automatically merged those clusters into one speaker timeline. Choose the operation that matches your application rather than treating all speaker-related output as interchangeable.
Can voice recognition identify a person?
An embedding comparison can support a speaker-matching workflow, but this helper does not make a security decision. The synthetic audio in the download demonstrates the API without comparing real people. It does not establish accuracy, spoof resistance or suitability for access control.
For real recordings, supply one speaker’s speech per sample. The file helpers do not automatically isolate speech or separate multiple speakers. Silence or extremely short samples cannot establish a reliable identity. Meeting recordings with overlapping participants therefore need more preparation than simply passing both file paths to Verify.
English CAM++ is the default; Chinese language selection chooses the Chinese CAM++ model. Explicit selectors must name supported embedders, not speech recognition models. Keep the model choice consistent across comparisons; enrollment spaces are separate per model.
Speaker embeddings are biometric data. Loaded speaker models stay in memory until ClearSpeakers. Enrollment vectors are not persisted by the library, but clearing is best effort rather than protection against memory dumps or runtime copies. Your application remains responsible for its audio, transcripts, logs and retained copies. In-memory library operation is not a legal-compliance determination. See the privacy and consent note before processing real voices. OneSpeech is unaffiliated with other products or companies named OneSpeech.