ElBruno.Speech.OpenTelemetry
OpenTelemetry instrumentation for ElBruno.Speech β activities, metrics, and Aspire-compatible setup.
Install
| Product | Versions |
|---|---|
| .NET |
README
ElBruno.Speech

Local-first speech runtime for .NET β VAD β STT β LLM β TTS ποΈ
A reusable, local-first speech runtime for .NET 8 and .NET 10. Built on Microsoft.Extensions.AI provider boundaries β works with local models (Whisper, VibeVoice, Qwen-TTS, Ollama) and cloud providers (Azure OpenAI, OpenAI) without changing orchestration code.
Audio input
β
Audio normalization Β· resampling Β· framing Β· buffering
β
Voice Activity Detection (Silero VAD)
β
Turn detection Β· utterance assembly
β
ISpeechToTextClient
β
IChatClient
β
Streaming text segmentation
β
ITextToSpeechClient
β
Audio output
What's New
| Date | Version | Highlights |
|---|---|---|
| 2026-08-02 | 1.1.0 | BlazorComponents β ElBruno.Speech.BlazorComponents Razor Class Library with six ready-to-use speech pipeline UI components |
| 2026-08-02 | 1.0.0 | First stable release β production pipeline, 70+ tests, OpenTelemetry, CLI tool, and Aspire sample |
| 2026-07-30 | 0.6.0 | Dependency updates β MEAI 10.8.1, ONNX Runtime 1.28.0, and Extensions 10.0.10 |
| 2026-07-21 | 0.5.4 | Production hardening β STT timeout and error isolation per pipeline stage |
| 2026-07-05 | 0.5.3 | MEAI IRealtimeClient adapter β SpeechPipelineRealtimeAdapter wrapping the pipeline as an IRealtimeClient |
Packages
Installation
dotnet add package ElBruno.Speech.Pipeline
dotnet add package ElBruno.Speech.Vad.Silero
Install the CLI tool globally:
dotnet tool install -g ElBruno.Speech.Cli
elbrunospeech --help
Quick Start
// Register providers
services.AddWhisper(o => o.Model = KnownWhisperModels.WhisperBaseEn);
services.AddLocalLLMs(o => o.Model = KnownModels.Phi35MiniInstruct);
services.AddVibeVoiceTTS(o => o.SampleRate = 24_000);
services.AddSileroVad(o => o.MinimumSilenceDuration = TimeSpan.FromMilliseconds(500));
// Build the pipeline
services.AddSpeechPipeline(builder =>
{
builder
.UseVoiceActivityDetector<SileroVoiceActivityDetector>()
.UseSpeechToText(sp => sp.GetRequiredService<ISpeechToTextClient>())
.UseChatClient(sp => sp.GetRequiredService<IChatClient>())
.UseTextToSpeech(sp => sp.GetRequiredService<ITextToSpeechClient>())
.UseSentenceChunking(o =>
{
o.MinimumCharacters = 24;
o.MaximumCharacters = 220;
o.FlushTimeout = TimeSpan.FromMilliseconds(350);
})
.UseBargeIn(o => o.CancelOnSpeechStart = true);
});
// Use it
var pipeline = sp.GetRequiredService<ISpeechPipeline>();
await using var session = await pipeline.CreateSessionAsync();
await session.WriteAudioAsync(frame);
await foreach (var update in session.GetUpdatesAsync())
{
// SpeechStartedUpdate, FinalTranscriptUpdate, AssistantAudioChunkUpdate, ...
}
Experimental multilingual Parakeet STT
An opt-in local Parakeet TDT v3 provider is available in 1.6.0-preview.1 as
ElBruno.Speech.Stt.Parakeet, using the verified
elbruno ONNX model bundle.
It supports Spanish and other model languages without changing Whisper defaults.
Native token-start metadata is preserved; word/segment intervals and language ID
are explicitly unavailable. See usage, requirements, and evaluation limits.
Opt-in Whisper large-v3
ElBruno.Speech.Stt.Whisper is currently source-only, pending the unpublished
1.6.0-preview.2 release. It adds a separate local whisper.cpp CPU provider
without replacing the existing ElBruno.Whisper package or changing defaults.
It uses a pinned, explicitly downloaded multilingual large-v3 model.
See setup, native requirements, and limitations and the
fixed-reference FLEURS comparison.
CLI Tool
elbrunospeech devices # list audio input/output devices
elbrunospeech transcribe recording.wav # transcribe a WAV file
elbrunospeech vad recording.wav # run voice activity detection
elbrunospeech talk "Hello world" out.wav # synthesize text to WAV
Observability
builder.Services.AddOpenTelemetry()
.AddSpeechPipelineTelemetry(); // meter: ElBruno.Speech, source: ElBruno.Speech
// Aspire automatically configures OTLP export via OTEL_EXPORTER_OTLP_ENDPOINT
Samples
| Sample | Description |
|---|---|
FileToSpeech |
WAV file β transcript β answer β WAV output |
ParakeetTranscribe |
Local WAV β Parakeet transcript and native token-start JSON (opt-in) |
WhisperTranscribe |
Local WAV β opt-in Whisper large-v3 transcript and unreviewed native segment JSON |
LocalVoiceAgent |
Microphone β VAD β Whisper β LLM β VibeVoice β speaker (barge-in) |
WebSocketVoiceAgent |
ASP.NET Core WebSocket endpoint + browser client |
AspireVoiceAgent |
Full Aspire AppHost with tracing, metrics, and dashboard |
Related Repositories
- ElBruno.Whisper β
ISpeechToTextClientvia ONNX Whisper - ElBruno.LocalLLMs β
IChatClientfor local LLMs - ElBruno.VibeVoiceTTS β
ITextToSpeechClientvia VibeVoice - ElBruno.QwenTTS β
ITextToSpeechClientvia Qwen3-TTS - ElBruno.HuggingFace.Downloader β model downloads
Requirements
- .NET 8.0 or .NET 10.0
- Windows, Linux, or macOS
- NAudio package requires Windows (microphone/speaker I/O)
Building from Source
git clone https://github.com/elbruno/ElBruno.Speech.git
cd ElBruno.Speech
dotnet restore
dotnet build
dotnet test --filter "Category!=Integration"
Speech test fixtures
Reusable Spanish/English speech fixtures, CC BY 4.0 licensing, offline validation, and opt-in model evaluation are documented in Speech test fixtures.
Working with Copilot and Squad
Normal Copilot sessions can work on this repository without loading Squad.
Squad is optional: select the Squad custom agent in your client or run
copilot --agent squad to use its team orchestration and safety rules.
The coordinator integrity check runs only in that custom agent.
If a normal session reports that the Squad coordinator is missing or truncated,
update your checkout to include the instruction-scope fix and start a new
Copilot session so it reloads .github/copilot-instructions.md. Existing
sessions can retain the old instructions. If you select Squad and its loaded
instructions are incomplete, stop orchestration and restart with the complete
custom agent; do not add a canary to bypass the check.
π License
MIT β see LICENSE.
The FLEURS audio and reference transcripts under tests/fixtures/speech are
separately licensed CC BY 4.0. See their attribution and license notices.
π About the Author
Hi! I'm ElBruno π§‘, a passionate developer and content creator exploring AI, .NET, and modern development practices.
Made with β€οΈ by ElBruno
If you like this project, consider following my work across platforms:
- π» Podcast: No Tienen Nombre β Spanish-language episodes on AI, development, and tech culture
- π» Blog: ElBruno.com β Deep dives on embeddings, RAG, .NET, and local AI
- πΊ YouTube: youtube.com/elbruno β Demos, tutorials, and live coding
- π LinkedIn: @elbruno β Professional updates and insights
- π Twitter: @elbruno β Quick tips, releases, and tech news
π Acknowledgments
- Microsoft.Extensions.AI β ISpeechToTextClient, IChatClient, ITextToSpeechClient interfaces
- Silero VAD β voice activity detection model
- ONNX Runtime β local model inference
- NAudio β Windows audio I/O
Changes from Previous Version
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.