Pisum Transcribe is a push-to-talk dictation app for Windows and macOS.
C#
0
54 commits
updated Sep 28, 2026
Pisum Transcribe is a push-to-talk dictation app for Windows and for Macs with Apple silicon. It runs in the system tray on Windows and in the menu bar on the Mac. Hold the hotkey, speak, and release it: the app transcribes your speech and inserts the text at the cursor in the active window. By default it translates German speech into English text.
The Mac app is released since 1.4.0. It works like the Windows app; where it differs, this README says so.
Speech recognition runs on your computer with an NVIDIA Canary model and the transcribe.cpp engine. Audio and text never leave the machine. The app goes online to download a speech model and, unless you turn it off in the settings, once a day to ask GitHub whether a new version exists.
Pisum.Transcribe_<version>_win-x64.msi from the latest release. It is about 77 MB.The installer asks no questions and needs no administrator rights. It installs the app for your user into %LOCALAPPDATA%\Programs\Pisum Transcribe\, about 230 MB, and adds Pisum Transcribe to the Start Menu. Nothing else needs to be installed: the installer contains .NET and the Visual C++ runtime. A GPU with a Vulkan driver is optional.
The app starts when the installation finishes. On the first start, it opens the window Download a speech model. Choose a model and download it. The download is checked against its SHA-256 hash, and the model loads when it is complete. The tray tooltip shows Ready (Vulkan) or Ready (CPU) when you can dictate.
Only one instance runs at a time. A second start waits up to 6 seconds for the first instance to exit and then exits itself.
Open the MSI of a newer release. If the app is running, Windows Installer says The following applications should be closed before continuing the install and lists Pisum.Transcribe. Choose OK, and it closes the app. The new version starts when the upgrade finishes. Your settings, speech models, logs and Start with Windows stay as they are.
A final release installs over its release candidates, such as 0.1.0 over 0.1.0-rc.2. An older release doesn't install over a newer one: the installer says A newer version of Pisum Transcribe is already installed. To go back, uninstall first.
Uninstall Pisum Transcribe in Windows Settings under Apps > Installed apps. This removes the program, its Start Menu entry and its Start with Windows entry. It keeps %LOCALAPPDATA%\Pisum Transcribe\ with your settings, speech models and logs, so a new installation picks them up again. Delete that folder to remove them too.
Pisum.Transcribe_<version>_osx-arm64.pkg from the latest release. It is about 56 MB.Pisum Transcribe.app into /Applications.The installer refuses Intel Macs and macOS 13 or older. The app contains .NET, so nothing else needs to be installed.
The app starts when the installation finishes and shows its icon in the menu bar. On the first start, it opens the setup window with the model download and four permissions:
Every release is signed with the project's own certificate, so macOS keeps these permissions when you install a newer release.
Open the package of a newer release, as for the first installation. The installer quits a running Pisum Transcribe as Quit Pisum Transcribe does, and starts the new version when it finishes. Your settings, speech models, logs, permissions and Open at login stay as they are. A final release installs over its release candidates. An older release doesn't install over a newer one: the installer says A newer version of Pisum Transcribe is already installed.
If Open at login is on, turn it off in the settings first: macOS keeps the login item after the app is moved to the Trash, even after the Trash is emptied, although it can't start anything any more. Then quit Pisum Transcribe from its menu, and move /Applications/Pisum Transcribe.app to the Trash. Your settings and speech models in ~/Library/Application Support/Pisum Transcribe/ and the logs in ~/Library/Logs/Pisum Transcribe/ stay, so a new installation picks them up again. To remove them too, and the installer's receipt and the permissions:
rm -rf ~/Library/Application\ Support/Pisum\ Transcribe ~/Library/Logs/Pisum\ Transcribe
sudo pkgutil --forget io.github.mschnecke.pisum-transcribe
tccutil reset All io.github.mschnecke.pisum-transcribe
Releases up to 0.1.0-rc.1 came as a zip. Exit the zip's app from its tray menu, install the MSI, and then delete the extracted Pisum Transcribe folder. The installed app uses the same settings and models. On its first start, it points an existing Start with Windows entry to itself.
You need the .NET SDK 10.0.400 or a later feature band that global.json allows. Build and start the app:
git clone https://github.com/mschnecke/pisum-transcribe.git
cd pisum-transcribe
dotnet run --project src/Pisum.Transcribe -f net10.0-windows10.0.19041.0 # Windows
dotnet run --project src/Pisum.Transcribe -f net10.0 # Mac
On a Mac, the build also needs the Xcode Command Line Tools (xcode-select --install). CLAUDE.md describes how the Mac build signs the app, and how to keep its permissions across builds.
A tap shorter than 0.3 seconds is ignored. A recording stops at the maximum length the model accepts (400 seconds for Canary 1B v2). What was recorded up to then is transcribed and inserted.
The app can't always insert the text. It leaves the text on the clipboard and shows a notification when:
Paste the text with Ctrl+V.
Right-click the tray icon:
| Item | What it does |
|---|---|
| Settings… | Opens the settings window. A left click on the tray icon does the same. |
| Download model… | Opens the download window. Shown only while the selected model is not installed. |
| Cancel transcription | Stops the running transcription. Shown only while a dictation is transcribed. |
Pisum Transcribe <version> is available… | Opens the release page in the browser. Shown only when a newer version is released. |
| Exit | Ends the app. |
The settings window applies changes when you save them, without a restart. It has five sections:
Run registry key, or Open at login on the Mac, which adds the app to System Settings > General > Login Items, and check for updates automatically, which asks GitHub once a day whether a new version exists. The update check is on by default.The settings are saved in settings.json. A file with the defaults looks like this:
{
"schemaVersion": 1,
"model": { "selectedModelId": "canary-1b-v2-q8_0" },
"transcription": { "backend": "auto", "task": "translate", "sourceLanguage": "de", "targetLanguage": "en" },
"recording": { "hotkey": ["VcRightControl"] },
"textInsertion": { "method": "clipboardPaste", "restoreClipboard": true },
"voiceActivity": { "enabled": true },
"updates": { "checkAutomatically": true }
}
Hotkey names are SharpHook KeyCode names, such as VcRightControl or VcF9. Languages are ISO 639-1 codes.
| Model | Download size | Languages |
|---|---|---|
| Canary 1B v2 (Q8_0), the default | 1.07 GB | 25 European languages |
| Canary 1B v2 (Q4_K_M) | 701 MB | 25 European languages |
| Canary 180M Flash (Q8_0) | 208 MB | German, English, French, Spanish |
The models are GGUF conversions of NVIDIA's Canary models by handy-computer, downloaded from Hugging Face. NVIDIA licenses them under CC BY 4.0. Translation goes from English into another language or from another language into English.
All data is stored per user in %LOCALAPPDATA%\Pisum Transcribe\, and nothing roams:
| Path | Contents |
|---|---|
settings.json | The settings |
models\ | Downloaded speech models |
logs\ | A daily log file. The last 7 files are kept. |
On the Mac, the settings and models are in ~/Library/Application Support/Pisum Transcribe/, and the logs in ~/Library/Logs/Pisum Transcribe/.
The log contains durations, lengths and status codes. It never contains audio or transcript text.
Once a day, unless you turn off Check for updates automatically in the settings, the app asks GitHub whether a new version exists. The update check sends no audio, text, settings, logs or identifiers. Its request carries only what every HTTPS request carries: your IP address, and a user agent that names the app without its version. When a newer version is released, the tray menu and a notification say so. The app doesn't download or install it.
dotnet build Pisum.Transcribe.slnx
dotnet test Pisum.Transcribe.slnx # unit and integration tests
dotnet test Pisum.Transcribe.slnx --filter-class "*.JsonSettingsStoreTests" # one test class
dotnet test Pisum.Transcribe.slnx --filter-trait "Category=Hardware" --explicit on # needs a microphone, GPU, model or internet access
The solution uses the .slnx format, so pass it to dotnet commands explicitly. The tests use xunit v3 on Microsoft.Testing.Platform, with Shouldly and FakeItEasy. Hardware tests are marked explicit, so the default test run needs no microphone, GPU, downloaded model or internet access.
The app is an Avalonia app on the .NET Generic Host, with no main window. Each feature lives in its own folder and namespace under src/Pisum.Transcribe/:
| Folder | Contents |
|---|---|
Hosting/ | Host setup, single instance, logging and shutdown |
Tray/ | Tray icon and menu, the app icon and the status glyph, whose icons tools/generate-tray-icon.cs renders |
Notifications/ | Windows notifications from Pisum Transcribe |
Settings/ | Settings model and JSON store |
SpeechModels/ | Model catalog, download and verification, setup window |
Transcription/ | transcribe.cpp engine with Vulkan and CPU fallback |
Recording/ | Push-to-talk hotkey and microphone recording (WASAPI) |
VoiceActivity/ | Silence trimming with Silero VAD |
TextInsertion/ | Paste or type at the cursor, clipboard restore |
Dictation/ | The dictation workflow, overlay and notifications |
SettingsWindow/ | Settings window |
Updates/ | The daily update check and its tray notice |
CLAUDE.md describes the conventions for shutdown, the UI thread, settings, logging, code style and tests. packaging/README.md describes how the MSI is built and how a release is published.
openspec/specs/, and the changes, open and archived, are in openspec/changes/.main through pull requests.The v1 feature set on the roadmap is implemented. GitHub Actions builds, tests and packages every pull request and every push to main, and each release is published with an MSI installer for Windows and a package for the Mac on GitHub Releases. Automatic updates, code signing of the MSI and notarization of the Mac package are not done yet.
THIRD-PARTY-NOTICES.md lists the third-party components the app ships and their licenses. Every release also carries the source of libuiohook (LGPL), which both installers contain, and WiX (MS-RL), which the MSI contains.
C#
96.5%
Swift
1.4%
PowerShell
1.2%
Pisum Transcribe is a push-to-talk dictation app for Windows and macOS.
C#
0
54 commits
updated Sep 28, 2026
Pisum Transcribe is a push-to-talk dictation app for Windows and for Macs with Apple silicon. It runs in the system tray on Windows and in the menu bar on the Mac. Hold the hotkey, speak, and release it: the app transcribes your speech and inserts the text at the cursor in the active window. By default it translates German speech into English text.
The Mac app is released since 1.4.0. It works like the Windows app; where it differs, this README says so.
Speech recognition runs on your computer with an NVIDIA Canary model and the transcribe.cpp engine. Audio and text never leave the machine. The app goes online to download a speech model and, unless you turn it off in the settings, once a day to ask GitHub whether a new version exists.
Pisum.Transcribe_<version>_win-x64.msi from the latest release. It is about 77 MB.The installer asks no questions and needs no administrator rights. It installs the app for your user into %LOCALAPPDATA%\Programs\Pisum Transcribe\, about 230 MB, and adds Pisum Transcribe to the Start Menu. Nothing else needs to be installed: the installer contains .NET and the Visual C++ runtime. A GPU with a Vulkan driver is optional.
The app starts when the installation finishes. On the first start, it opens the window Download a speech model. Choose a model and download it. The download is checked against its SHA-256 hash, and the model loads when it is complete. The tray tooltip shows Ready (Vulkan) or Ready (CPU) when you can dictate.
Only one instance runs at a time. A second start waits up to 6 seconds for the first instance to exit and then exits itself.
Open the MSI of a newer release. If the app is running, Windows Installer says The following applications should be closed before continuing the install and lists Pisum.Transcribe. Choose OK, and it closes the app. The new version starts when the upgrade finishes. Your settings, speech models, logs and Start with Windows stay as they are.
A final release installs over its release candidates, such as 0.1.0 over 0.1.0-rc.2. An older release doesn't install over a newer one: the installer says A newer version of Pisum Transcribe is already installed. To go back, uninstall first.
Uninstall Pisum Transcribe in Windows Settings under Apps > Installed apps. This removes the program, its Start Menu entry and its Start with Windows entry. It keeps %LOCALAPPDATA%\Pisum Transcribe\ with your settings, speech models and logs, so a new installation picks them up again. Delete that folder to remove them too.
Pisum.Transcribe_<version>_osx-arm64.pkg from the latest release. It is about 56 MB.Pisum Transcribe.app into /Applications.The installer refuses Intel Macs and macOS 13 or older. The app contains .NET, so nothing else needs to be installed.
The app starts when the installation finishes and shows its icon in the menu bar. On the first start, it opens the setup window with the model download and four permissions:
Every release is signed with the project's own certificate, so macOS keeps these permissions when you install a newer release.
Open the package of a newer release, as for the first installation. The installer quits a running Pisum Transcribe as Quit Pisum Transcribe does, and starts the new version when it finishes. Your settings, speech models, logs, permissions and Open at login stay as they are. A final release installs over its release candidates. An older release doesn't install over a newer one: the installer says A newer version of Pisum Transcribe is already installed.
If Open at login is on, turn it off in the settings first: macOS keeps the login item after the app is moved to the Trash, even after the Trash is emptied, although it can't start anything any more. Then quit Pisum Transcribe from its menu, and move /Applications/Pisum Transcribe.app to the Trash. Your settings and speech models in ~/Library/Application Support/Pisum Transcribe/ and the logs in ~/Library/Logs/Pisum Transcribe/ stay, so a new installation picks them up again. To remove them too, and the installer's receipt and the permissions:
rm -rf ~/Library/Application\ Support/Pisum\ Transcribe ~/Library/Logs/Pisum\ Transcribe
sudo pkgutil --forget io.github.mschnecke.pisum-transcribe
tccutil reset All io.github.mschnecke.pisum-transcribe
Releases up to 0.1.0-rc.1 came as a zip. Exit the zip's app from its tray menu, install the MSI, and then delete the extracted Pisum Transcribe folder. The installed app uses the same settings and models. On its first start, it points an existing Start with Windows entry to itself.
You need the .NET SDK 10.0.400 or a later feature band that global.json allows. Build and start the app:
git clone https://github.com/mschnecke/pisum-transcribe.git
cd pisum-transcribe
dotnet run --project src/Pisum.Transcribe -f net10.0-windows10.0.19041.0 # Windows
dotnet run --project src/Pisum.Transcribe -f net10.0 # Mac
On a Mac, the build also needs the Xcode Command Line Tools (xcode-select --install). CLAUDE.md describes how the Mac build signs the app, and how to keep its permissions across builds.
A tap shorter than 0.3 seconds is ignored. A recording stops at the maximum length the model accepts (400 seconds for Canary 1B v2). What was recorded up to then is transcribed and inserted.
The app can't always insert the text. It leaves the text on the clipboard and shows a notification when:
Paste the text with Ctrl+V.
Right-click the tray icon:
| Item | What it does |
|---|---|
| Settings… | Opens the settings window. A left click on the tray icon does the same. |
| Download model… | Opens the download window. Shown only while the selected model is not installed. |
| Cancel transcription | Stops the running transcription. Shown only while a dictation is transcribed. |
Pisum Transcribe <version> is available… | Opens the release page in the browser. Shown only when a newer version is released. |
| Exit | Ends the app. |
The settings window applies changes when you save them, without a restart. It has five sections:
Run registry key, or Open at login on the Mac, which adds the app to System Settings > General > Login Items, and check for updates automatically, which asks GitHub once a day whether a new version exists. The update check is on by default.The settings are saved in settings.json. A file with the defaults looks like this:
{
"schemaVersion": 1,
"model": { "selectedModelId": "canary-1b-v2-q8_0" },
"transcription": { "backend": "auto", "task": "translate", "sourceLanguage": "de", "targetLanguage": "en" },
"recording": { "hotkey": ["VcRightControl"] },
"textInsertion": { "method": "clipboardPaste", "restoreClipboard": true },
"voiceActivity": { "enabled": true },
"updates": { "checkAutomatically": true }
}
Hotkey names are SharpHook KeyCode names, such as VcRightControl or VcF9. Languages are ISO 639-1 codes.
| Model | Download size | Languages |
|---|---|---|
| Canary 1B v2 (Q8_0), the default | 1.07 GB | 25 European languages |
| Canary 1B v2 (Q4_K_M) | 701 MB | 25 European languages |
| Canary 180M Flash (Q8_0) | 208 MB | German, English, French, Spanish |
The models are GGUF conversions of NVIDIA's Canary models by handy-computer, downloaded from Hugging Face. NVIDIA licenses them under CC BY 4.0. Translation goes from English into another language or from another language into English.
All data is stored per user in %LOCALAPPDATA%\Pisum Transcribe\, and nothing roams:
| Path | Contents |
|---|---|
settings.json | The settings |
models\ | Downloaded speech models |
logs\ | A daily log file. The last 7 files are kept. |
On the Mac, the settings and models are in ~/Library/Application Support/Pisum Transcribe/, and the logs in ~/Library/Logs/Pisum Transcribe/.
The log contains durations, lengths and status codes. It never contains audio or transcript text.
Once a day, unless you turn off Check for updates automatically in the settings, the app asks GitHub whether a new version exists. The update check sends no audio, text, settings, logs or identifiers. Its request carries only what every HTTPS request carries: your IP address, and a user agent that names the app without its version. When a newer version is released, the tray menu and a notification say so. The app doesn't download or install it.
dotnet build Pisum.Transcribe.slnx
dotnet test Pisum.Transcribe.slnx # unit and integration tests
dotnet test Pisum.Transcribe.slnx --filter-class "*.JsonSettingsStoreTests" # one test class
dotnet test Pisum.Transcribe.slnx --filter-trait "Category=Hardware" --explicit on # needs a microphone, GPU, model or internet access
The solution uses the .slnx format, so pass it to dotnet commands explicitly. The tests use xunit v3 on Microsoft.Testing.Platform, with Shouldly and FakeItEasy. Hardware tests are marked explicit, so the default test run needs no microphone, GPU, downloaded model or internet access.
The app is an Avalonia app on the .NET Generic Host, with no main window. Each feature lives in its own folder and namespace under src/Pisum.Transcribe/:
| Folder | Contents |
|---|---|
Hosting/ | Host setup, single instance, logging and shutdown |
Tray/ | Tray icon and menu, the app icon and the status glyph, whose icons tools/generate-tray-icon.cs renders |
Notifications/ | Windows notifications from Pisum Transcribe |
Settings/ | Settings model and JSON store |
SpeechModels/ | Model catalog, download and verification, setup window |
Transcription/ | transcribe.cpp engine with Vulkan and CPU fallback |
Recording/ | Push-to-talk hotkey and microphone recording (WASAPI) |
VoiceActivity/ | Silence trimming with Silero VAD |
TextInsertion/ | Paste or type at the cursor, clipboard restore |
Dictation/ | The dictation workflow, overlay and notifications |
SettingsWindow/ | Settings window |
Updates/ | The daily update check and its tray notice |
CLAUDE.md describes the conventions for shutdown, the UI thread, settings, logging, code style and tests. packaging/README.md describes how the MSI is built and how a release is published.
openspec/specs/, and the changes, open and archived, are in openspec/changes/.main through pull requests.The v1 feature set on the roadmap is implemented. GitHub Actions builds, tests and packages every pull request and every push to main, and each release is published with an MSI installer for Windows and a package for the Mac on GitHub Releases. Automatic updates, code signing of the MSI and notarization of the Mac package are not done yet.
THIRD-PARTY-NOTICES.md lists the third-party components the app ships and their licenses. Every release also carries the source of libuiohook (LGPL), which both installers contain, and WiX (MS-RL), which the MSI contains.
C#
96.5%
Swift
1.4%
PowerShell
1.2%