# Win Dictation - Source Notes

## Architecture (current)

**Push-to-talk, batch mode.** Press record, speak, press again. The full audio clip is passed to `whisper_full` once on stop. No streaming, no VAD, no ring buffer.

- Audio: SDL2 capture at 16kHz mono
- Inference: `whisper_full` with physical-core threads
- UI: Single-surface GDI+ immediate-mode painting (no child-window chrome)
- Progress: Self-calibrating linear estimator fused with whisper's chunk-boundary callbacks

## Key files

| File | Purpose |
|------|---------|
| `main.cpp` | Window, painting, interaction, settings, clipboard |
| `transcriber.h` / `transcriber.cpp` | Audio capture, whisper preload/inference, callbacks |
| `timing.h` | Per-model online least-squares timing model + live progress estimator |
| `settings.h` | INI file read/write for persistent settings |
| `text_util.h` | Transcript concatenation |
| `logging.h` | Timestamped log to `win-dictation.log` |

## Building

```powershell
cmake -S . -B build -G "Visual Studio 18 2026" -DSDL2_DIR="deps/SDL2-2.28.5/cmake"
cmake --build build --config Release
```

Output: `build\bin\Release\win-dictation.exe`

Target machine: 2-core / 4-thread Intel i5-7th-gen, GPU CUDA disabled.

## Model placement

Drop `.bin` files in `models/` next to the executable. The app scans for:
- `ggml-tiny.en.bin`
- `ggml-tiny.en-q8_0.bin`
- `ggml-base.en-q5_1.bin`
- `ggml-base.en.bin`

First available is used. Toggle in the model popup.

## Settings

Stored in `win-dictation.ini` next to the executable. Sections:
- `[app]`: window position, hotkey, model, capture device, pinned/autopaste/autohide flags
- `[timing-ggml-*.bin]`: per-model timing accumulators (learned transcription speed)
