# Speech to Text in C#, Offline: Whisper in Your .NET Process

> Transcribe audio files from C# with OpenAI's Whisper running locally: no API key, no Python, no whisper.cpp build. One NuGet package, timestamps per segment, and 3 minutes of speech transcribed in 25 seconds on a CPU.

Source: https://kjarni.ai/blog/speech-to-text-csharp/ (published 2026-11-07)

Transcribing audio from C# usually means sending it to a cloud API, or building
whisper.cpp and wrapping it yourself. This runs OpenAI's Whisper model inside your .NET
process, from one NuGet package, with no network after the first download:

```csharp
using Kjarni;

using var transcriber = new Transcriber("whisper-small", language: "en", quiet: true);
var transcript = transcriber.TranscribeFile("jfk.wav");
Console.WriteLine(transcript.Text);
```

```
 And so my fellow Americans, ask not what your country can do for you, ask what you can do for your country.
```

## Try it

You need the [.NET 8 SDK](https://dotnet.microsoft.com/download).

```bash
dotnet new console -o SpeechToText
cd SpeechToText
dotnet add package Kjarni
curl -LO https://github.com/ggml-org/whisper.cpp/raw/master/samples/jfk.wav
```

Replace `Program.cs` with:

```csharp
using System.Diagnostics;
using Kjarni;

var path = args.Length > 0 ? args[0] : "jfk.wav";

using var transcriber = new Transcriber("whisper-small", language: "en", quiet: true);

var sw = Stopwatch.StartNew();
var transcript = transcriber.TranscribeFile(path);

Console.WriteLine(transcript.Text);
Console.WriteLine();
foreach (var segment in transcript.Segments)
    Console.WriteLine($"[{segment.Start,6:F2} -> {segment.End,6:F2}] {segment.Text}");

Console.Error.WriteLine($"\n{transcript.DurationSecs:F1} s of audio transcribed in {sw.Elapsed.TotalSeconds:F1} s");
```

```bash
dotnet run
```

The first run downloads whisper-small (920 MB) and caches it. `jfk.wav` is the 11-second
sample from the whisper.cpp repository, a public domain recording of John F. Kennedy.

## A longer recording

For something with more than one sentence, here is a 3 minute 19 second public domain
address from Wikimedia Commons, converted to WAV with ffmpeg:

```bash
curl -L -o columbia.ogg https://upload.wikimedia.org/wikipedia/commons/1/1f/George_W_Bush_Columbia_FINAL.ogg
ffmpeg -i columbia.ogg -ar 16000 -ac 1 columbia.wav
dotnet run -- columbia.wav
```

```
 My fellow Americans, this day has brought terrible news and great sadness to our country. At 9 o'clock this morning, ...

[  0.00 ->   9.00]  My fellow Americans, this day has brought terrible news and great sadness to our country.
[  9.00 ->  18.00]  At 9 o'clock this morning, Mission Control in Houston lost contact with our space shuttle Columbia.
[ 18.00 ->  24.00]  A short time later, debris was seen falling from the skies above Texas.
[ 24.00 ->  27.00]  The Columbia's lost.
[ 27.00 ->  29.00]  There are no survivors.
[ 29.54 ->  37.14]  On board was a crew of seven, Colonel Rick Husband, Lieutenant Colonel Michael Anderson,
...
198.7 s of audio transcribed in 25.1 s
```

`Segments` carries start and end times in seconds, which is what you need for subtitles,
for jumping to a moment in a player, or for searching a recording by what was said.

## How fast, and how good

On an Intel i7-13700 (24 threads), with the model already downloaded:

| Model | Download | 3 min 19 s of speech | Faster than real time |
|---|---|---|---|
| `whisper-small` | 920 MB | 25 s | 8× |
| `whisper-large-v3` | 2.9 GB | 124 s | 1.6× |

whisper-small got almost all of the address right. It dropped one short phrase ("In the
words of the prophet Isaiah"), which large-v3 kept, and both models misheard one name:
astronaut Kalpana Chawla came out as "Kultna Shavla". That is typical of Whisper: common
words are reliable, rare names are not. Check names, numbers and terms of art before you
publish a transcript.

Use whisper-small by default, and large-v3 when accuracy matters more than time, for
accented speech or for languages other than English.

## Formats: WAV in, ffmpeg for the rest

`TranscribeFile` reads WAV files, at any sample rate, mono or stereo; Kjarni resamples to
the 16 kHz mono Whisper expects. Kjarni 0.4.2 does not decode MP3, Ogg or FLAC, so
convert those first:

```bash
ffmpeg -i meeting.mp3 -ar 16000 -ac 1 meeting.wav
```

If you already have the audio in memory, from a microphone or a decoder library such as
NAudio, pass the samples directly:

```csharp
float[] samples = ...;   // mono, -1.0 to 1.0
var transcript = transcriber.Transcribe(samples, sampleRate: 16000);
```

## Languages and translation

Whisper is multilingual. Pass the language if you know it, or `null` to let the model
detect it from the first seconds of audio:

```csharp
using var detect = new Transcriber("whisper-small", language: null, quiet: true);
var t = detect.TranscribeFile("interview.wav");
Console.WriteLine(t.Language);   // e.g. "de"
```

`translate: true` turns speech in any supported language into English text in the same
pass:

```csharp
using var toEnglish = new Transcriber("whisper-small", translate: true, quiet: true);
```

## What it does not do

- **No live streaming from a microphone.** It transcribes files or sample buffers that
  you have. For near-live captions, transcribe chunks of a few seconds as they arrive.
- **No speaker labels.** Whisper does not say who is speaking.
- **CPU by default.** `device: "gpu"` uses a GPU through Vulkan, DirectX 12 or Metal.

## FAQ

### How do I convert speech to text in C# offline?

Install the `Kjarni` NuGet package and call `new Transcriber("whisper-small").TranscribeFile("audio.wav")`.
The Whisper model runs inside your process; after the first download nothing goes over
the network.

### Does it need Python, whisper.cpp or an API key?

No. The package includes the native library for Windows x64, Linux x64 and arm64, and
macOS on Apple Silicon.

### Which audio formats does it read?

WAV, at any sample rate, mono or stereo. Convert MP3, Ogg, FLAC and video files to WAV
with ffmpeg first.

### How accurate is it?

whisper-small gets everyday English nearly word for word and makes mistakes on rare names.
whisper-large-v3 is more accurate and about five times slower.

## Getting it

```
Install:  dotnet add package Kjarni
NuGet:    https://www.nuget.org/packages/Kjarni
GitHub:   https://github.com/olafurjohannsson/kjarni
```

## Related

- [Speech to text in Qt](/blog/qtspeech/): the same Whisper models in a Qt Quick app
- [Local LLM Chat in C#](/blog/localchat/): summarize or question the transcript locally
- [Transcriber reference](/reference/dotnet/kjarni-transcriber/)
