Skip to content

Repository files navigation

PTT Dictation

CI

PTT Dictation is a dark-mode-first Windows push-to-talk dictation app that runs speech recognition locally. Hold your selected hold-to-talk key, speak, and release: the app records a temporary 16 kHz mono WAV and inserts live transcription into the original textbox when its editor supports safe text replacement. The final recognition result replaces that recording's text in place. Other supported editable fields receive one final paste. The defaults are Right Ctrl for hold-to-talk and Right Shift for toggle-to-talk.

It is named for the workflow rather than a particular AI vendor or model. Parakeet through parakeet.cpp provides live preview. On computers with an NVIDIA CUDA GPU, an optional local Qwen3-ASR 1.7B worker can provide the final transcript after Stop. Qwen controls are hidden on AMD-, Intel-, and CPU-only systems. Existing installations continue using Parakeet until Qwen is selected in Settings. See Qwen final transcription for setup and behavior.

Overview

  • Local by design: Audio and transcripts stay on the machine during transcription. Network access is used only to download selected runtime and model assets.
  • Native Windows workflow: Global push-to-talk capture, local inference, live transcript display, and automatic paste work from the system tray without requiring a browser tab.
  • Replaceable AI boundary: Dictation orchestration depends on ITranscriber; the current adapter provisions parakeet.cpp and Parakeet GGUF models.
  • Defensive asset handling: Built-in downloads use pinned SHA-256 hashes, runtime archives are checked before extraction, and temporary recordings are deleted after use.
  • Reproducible delivery: Windows CI uses locked NuGet restore, dependency auditing, release packaging, checksums, a CycloneDX SBOM, and build provenance attestations.
  • Stack: C#, .NET 10, Windows Forms, WASAPI, Windows keyboard hooks, parakeet.cpp, GGUF models, and GitHub Actions.

Features

  • Independently configurable hold-to-talk and toggle-to-talk keys.
  • Live text in supported destination textboxes, without a floating recording or processing overlay. Existing audible state feedback and tray cancellation remain available.
  • Focus changes pause insertion while recording continues. Return to the original textbox to resume. After stopping, PTT waits up to five seconds for focus to return before ending with an error and keeping the completed transcript in Session History. The app does not switch windows for you.
  • If text insertion fails or Windows loses access to the captured editor reference, PTT automatically stops recording, finishes recognition, and keeps the transcript in Session History. The textbox may still be visible when its automation reference fails. Final recognition remains cancellable; after completion, another dictation can start normally.
  • If Windows loses that reference after every final word was confirmed inserted, PTT completes with the inserted preview instead of reporting failure for unapplied capitalization or final punctuation. History preserves the actual inserted text and the separately formatted final recognition. Missing words, an unconfirmed write, or a changed document still produce a failure with the transcript retained.
  • Cancellable finalization and first-use runtime/model downloads.
  • Local transcription with downloadable Parakeet runtime/model assets. Optional Qwen final recognition keeps the existing live preview and hotkeys, then revises the completed transcript after Stop. Each recording keeps the final-engine choice it started with.
  • Session-only transcript history with raw preview, corrected preview, final recognition, phrase replacements, and final formatting comparisons. Failed insertion preserves the completed transcript here for copying.
  • Runtime/model path overrides for local experimentation.
  • Dark-mode-first Windows Forms UI.

How it works

PTT Dictation workflow: hold the selected key and speak, capture audio locally, transcribe on your PC, apply saved corrections, paste into the original app, then restore the clipboard and delete temporary audio.

Implementation highlights:

  • Native shell UX: NotifyIcon tray app, dark Windows Forms settings/history windows, non-activating topmost status overlay, and audible state feedback.
  • Audio path: WASAPI shared-mode capture writes 16-bit, 16 kHz, mono PCM WAV files for parakeet-cli.
  • Runtime management: CPU is the safe first-run default. A saved CUDA choice remains authoritative across app updates, with an automatic CPU retry path if CUDA transcription fails.
  • Asset integrity: Runtime zip files and built-in GGUF models use pinned SHA-256 checks; extracted runtime files are revalidated through a manifest.
  • Archive hardening: Runtime zip entries are checked before extraction so archive paths cannot escape the runtime directory.
  • Operational polish: Process timeout/cancellation handling, single-instance guard, local transcript corrections with preview, best-effort clipboard restoration, session-only transcript history, and cleanup warnings if a temporary WAV cannot be deleted.

Transcription engines

The current app downloads and runs parakeet.cpp with a supported Parakeet GGUF model. That is an implementation choice, not the product identity. Core recording and dictation flows depend on the ITranscriber contract, so another local engine can be added behind the same session, live transcript, correction, history, and paste workflow.

Start with the interesting code

  • ChunkedTranscribingDictationSession.cs — serial recognition scheduling, latest-snapshot coalescing, revisable full-recording previews, and legacy overlapping-chunk assembly.
  • ParakeetCliTranscriber.csparakeet.cpp process integration, streaming, cancellation, and CUDA-to-CPU fallback.
  • CoreBehaviorTests.cs — behavioral coverage for chunk reconciliation, transcription modes, asset validation, and failure paths.

Privacy

PTT Dictation is designed for local dictation. Temporary recordings are made on the local machine while dictation is active, transcription is performed by a local parakeet-cli runtime, and transcript history is session-only. The app does download runtime/model assets on first use or when you choose a model download in settings.

Trust-boundary notes:

  • Insertion uses the Windows clipboard. Live dictation temporarily places each revised transcript on the clipboard, checks the original textbox and owned text range, inserts it, and attempts to restore the prior clipboard. Other local apps with clipboard access may observe interim and final transcripts. The app does not force focus back after a window change.
  • Windows UI Automation reads the destination's text and selection to protect surrounding content; those editor snapshots are transient and are not added to transcript history. Password and known read-only fields are excluded. If the editor changes unexpectedly after insertion begins, automatic replacement stops and the completed transcript is kept in Session History.
  • Cancelling stops further insertion; it does not undo text already inserted. Recognition-stage comparisons stay in memory for the current app session.
  • This development checkpoint enables local diagnostic traces under %LOCALAPPDATA%\PttDictation\diagnostics\experimental. They include dictated text, recognition stages, timing, and errors, and retain up to three complete recordings. Logs rotate at 4 MiB. These files are separate from session history and may contain sensitive speech; they are not uploaded automatically or included in the repository. Original clipboard contents and surrounding textbox text are not logged.
  • Transcript correction rules are stored locally with settings and are applied before history and paste.
  • The configurable hold and toggle keys use a low-level Windows keyboard hook. The hook consumes only the selected keys and is used for hotkey state, not transcript collection.
  • Runtime/model downloads leave the local machine to fetch third-party artifacts; transcription itself runs locally.

Requirements

  • Windows 11, or Windows 10 installations still receiving security updates.
  • A working audio input device.
  • An internet connection for the first runtime/model download.

Supported releases target Windows 10/11 on x64. An NVIDIA GPU is optional. Without one, Settings offers CPU Parakeet transcription and hides CUDA/Qwen choices that the machine cannot use.

Install

The release installer uses Windows PowerShell 5.1 or newer, verifies the published package checksum, installs for the current user, creates a Start-menu shortcut, and starts the app:

$installer = Join-Path $env:TEMP 'Install-PttDictation.ps1'
Invoke-WebRequest https://github.com/DiscoStew6082/ptt-dictation/releases/latest/download/Install-PttDictation.ps1 -OutFile $installer
powershell -NoProfile -ExecutionPolicy Bypass -File $installer

The default destination is %LOCALAPPDATA%\Programs\PttDictation. To install anywhere else on a local drive:

powershell -NoProfile -ExecutionPolicy Bypass -File $installer -InstallDirectory 'D:\Apps\PttDictation'

For an offline or manually downloaded install, download PttDictation-win-x64.zip, its .sha256 file, and Install-PttDictation.ps1 from the latest GitHub release, then run:

powershell -NoProfile -ExecutionPolicy Bypass -File .\Install-PttDictation.ps1 `
  -PackagePath .\PttDictation-win-x64.zip `
  -ChecksumPath .\PttDictation-win-x64.zip.sha256

Release builds are self-contained, so users do not need to install the .NET SDK or runtime. The app is not code-signed yet, so Windows SmartScreen may display a warning.

The runtime preference and other user settings are stored separately in %LOCALAPPDATA%\PttDictation\settings.json. A new profile starts on CPU. Reinstalling or updating the program files does not rewrite that file, so a later CPU or CUDA choice remains selected. The development updater changes settings only when -SettingsSource is explicitly supplied.

First Run

Launch PttDictation.exe and leave it running in the system tray. By default, hold Right Ctrl while speaking and release it to transcribe and paste; Right Shift starts or stops toggle dictation mode. Open Settings to choose separate keys for both actions.

On first use the app downloads assets under %LOCALAPPDATA%\PttDictation:

  • parakeet.cpp v0.4.0 Windows CPU runtime by default.
  • The CUDA runtime plus its matching dependency archive only after CUDA is selected in Settings.
  • Default tdt_ctc-110m-f16.gguf model from mudler/parakeet-cpp-gguf.

Expect first-run downloads to be hundreds of MB for the default model and runtime assets. The optional larger multilingual model is about 1.4 GB.

The tray icon is red while recording or processing and green when idle, including after completion, cancellation, or failure. Open the tray menu for settings, model downloads, transcript correction preview, and session-only transcript history.

To try the low-latency realtime display, open settings and select one of the experimental realtime models:

  • Parakeet Realtime EOU 120M Q8_0
  • Parakeet Realtime EOU 120M F16

Leave transcription mode on Auto. The app warms one persistent local parakeet-server process when recording begins, reuses the loaded model for overlapping live updates, and sends the complete recording through that same loaded model after release. Realtime EOU models are continued after every pause marker until the entire recording has been consumed. This avoids both first-pause truncation and launching a separate CLI process for every update. If a downloaded runtime does not include the local server, the app falls back to the selected batch or parakeet-cli --stream mode.

Downloaded Assets

This repository is licensed under MIT. The runtime and model assets downloaded on first use are third-party artifacts from their upstream projects:

  • parakeet.cpp runtime archives are downloaded from the mudler/parakeet.cpp GitHub release v0.4.0. Runtime archives are verified with pinned SHA-256 hashes before extraction.
  • GGUF model files are downloaded from mudler/parakeet-cpp-gguf on Hugging Face. Built-in model downloads are checked for minimum expected size and pinned SHA-256 hashes; configure a local model path in settings only when you trust that local model file.

Review the upstream repositories for their own license terms before redistributing bundled runtime or model assets.

Release Verification

Every published release should include a SHA-256 checksum for the downloadable zip. Users should compare the published checksum with:

Get-FileHash .\PttDictation-win-x64.zip -Algorithm SHA256

Release builds from this repository publish the installer, zip, checksum, and CycloneDX SBOM. Public tag builds also create a GitHub artifact attestation and publish the GitHub Release so the latest-release installer works without a manual release step. Recommended additional hardening for broad public distribution includes code signing.

Current limitations

  • Supported builds target Windows 10/11 on x64 only.
  • Hotkey choices currently include left/right Ctrl, Shift, and Alt plus F1 through F24.
  • First use requires large runtime/model downloads unless you configure trusted local paths.
  • Release artifacts are not code-signed yet, so Windows SmartScreen may warn on broad public distribution.

Build from Source

Contributors need .NET SDK 10.0.400 or newer. Run the test suite and create a self-contained Windows build with:

dotnet test PttDictation.sln
dotnet publish src\PttDictation.App\PttDictation.App.csproj -c Release -r win-x64 --self-contained true -o publish\next-build

The build is staged in publish\next-build. To update the default per-user installation, run pwsh -File scripts\Update-LocalApp.ps1 -StagedPath publish\next-build. For a custom installation, also pass its existing -InstallDirectory. The updater verifies the files and running process at that stable path and attempts rollback if installation fails. See CONTRIBUTING.md for verification and the complete development and release workflow.

Validation

Run:

dotnet test PttDictation.sln
dotnet publish src\PttDictation.App\PttDictation.App.csproj -c Release -r win-x64 --self-contained true -o publish\next-build

Real smoke test performed with parakeet-v0.4.0-bin-win-cpu-x64.zip and tdt_ctc-110m-f16.gguf against a generated speech WAV:

{"text":"Hello parakeet push to talk."}

Chunked dictation smoke checks on July 3, 2026 with the locally installed CPU runtime and default tdt_ctc-110m-f16.gguf model:

  • parakeet-cli transcribe --json returns word-level words timing metadata for smoke\sample.wav.
  • parakeet-cli transcribe --timestamps prints word timestamps for the same WAV.
  • parakeet-cli transcribe --stream is available in the CLI help, but the default model rejects it because streaming requires a cache-aware model such as parakeet_realtime_eou_120m-v1.

An overlapped local chunk smoke manually split smoke\sample.wav into 2.5 second chunks with 0.8 second overlap and transcribed each chunk through the installed CPU parakeet-cli:

Model: tdt_ctc-110m-f16.gguf (f16)

Context Wall time Transcript
chunk 1 160 ms Hello parakeet push to talk.
chunk 2 149 ms to talk.
full sample 199 ms Hello parakeet push to talk.

Manual microphone validation using the default keys still needs to confirm end-to-end overlay latency and final paste quality on a real input device:

1. Start PTT Dictation from a local build.
2. Hold Right Ctrl and speak for at least 8 seconds with a pause near a chunk boundary.
3. Confirm partial text appears while recording remains active.
4. Release Right Ctrl and confirm the final pasted transcript is clean.
5. Repeat with Right Shift toggle mode and confirm the second press finalizes transcription.

Realtime streaming model smoke can be rerun with:

powershell -ExecutionPolicy Bypass -File .\scripts\Test-RealtimeStreaming.ps1 -Runtime both -Iterations 3

The script downloads/verifies the two realtime EOU models through hf when needed, runs the local smoke WAV through the CPU and CUDA runtimes, and writes smoke\streaming-smoke-results.md.

Contributing

See CONTRIBUTING.md for development setup and pull request guidance.

License

PTT Dictation is available under the MIT License.

About

Local push-to-talk dictation for Windows with replaceable transcription engines and Parakeet models built in.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages