# Captioneer Local, live English captions for the audio playing through your default PulseAudio/PipeWire output device. It captures that output's monitor source, runs the Parakeet TDT v2 model locally, and writes captions to the terminal. Everything runs on your machine after the one-time model download. No audio is uploaded anywhere. ## Requirements - Linux on `amd64` / x86_64 - Go 1.26.2 or newer - `pactl` and `parec` available on `PATH` (on Debian/Ubuntu: `sudo apt install pulseaudio-utils`) - `curl` and `tar` to download the models - A working PulseAudio-compatible server, including PipeWire's PulseAudio compatibility layer The application listens to the monitor of the current default audio sink. Check it with: ```bash pactl get-default-sink ``` ## Setup Clone the project, then download the required models once: ```bash git clone cd captioneer ./scripts/download-models.sh ``` The download installs the Parakeet TDT v2 int8 model and Silero VAD into `models/`. They are intentionally not committed to Git because they are large. ## Run Use VAD mode for normal live captions. It shows a temporary `…` caption while speech is active, then prints a timestamped final caption after 0.5 seconds of silence: ```bash go run ./src/cmd/captioneer --mode=vad ``` Use fixed mode to decode exact time slices, even through silence: ```bash go run ./src/cmd/captioneer --mode=fixed --chunk-duration=1s ``` Build a reusable executable instead of using `go run`: ```bash go build -o captioneer ./src/cmd/captioneer ./captioneer --mode=vad ``` Press Ctrl+C to stop. Pending audio is flushed before exit. ## Options `--mode` is required. All other options have defaults. | Option | Default | Description | | --- | --- | --- | | `--mode=vad` | — | Speech-aware captions. This is the recommended everyday mode. | | `--mode=fixed` | — | Decode every fixed-duration audio chunk. | | `--chunk-duration=1s` | `1s` | Fixed chunk length, or VAD preview refresh interval. Go duration syntax is used, e.g. `500ms`, `1s`, `2s`. | | `--models-dir=models` | `models` | Directory containing `parakeet-tdt-v2/` and `silero_vad_v5.onnx`. | | `--threads=2` | `2` | CPU threads used by Parakeet and VAD. Increase only if your CPU has spare capacity. | | `--preview-threshold-dbfs=-45` | `-45` | RMS level that begins a provisional VAD caption. Raise it (for example, `-35`) if background audio starts previews; lower it (for example, `-55`) if quiet speech does not. | Examples: ```bash # Faster fixed chunks go run ./src/cmd/captioneer --mode=fixed --chunk-duration=500ms # Fewer VAD preview redraws and four CPU threads go run ./src/cmd/captioneer --mode=vad --chunk-duration=2s --threads=4 # Store or reuse models outside this repository go run ./src/cmd/captioneer --mode=vad --models-dir=/path/to/models ``` There are no environment variables to configure. All supported configuration is supplied with command-line options. ## Source layout All Go code lives in `src/` as focused packages: - `cmd/captioneer` is the executable entrypoint. - `config` defines command-line options. - `audio` contains PCM conversion and audio calculations. - `capture` reads the default system-audio monitor. - `models` owns Parakeet and Silero model resources. - `captions` handles fixed chunks, VAD segments, and terminal output. ## Output and troubleshooting Final captions go to standard output in this form: ```text [12.34s-15.67s] This is a completed caption. ``` Startup messages and overload warnings go to standard error, so you can save final captions separately: ```bash go run ./src/cmd/captioneer --mode=vad > captions.txt ``` - **Missing model files:** run `./scripts/download-models.sh` again. - **`pactl` or `parec` not found:** install `pulseaudio-utils` and start a PulseAudio-compatible audio server. - **No captions while audio plays:** verify the default sink with `pactl get-default-sink`; the app records that sink's `.monitor` source. - **Overload warning:** recognition is behind real time. Try `--threads=4` (or another suitable value) or `--chunk-duration=2s`. ## Verify changes ```bash go test ./... go build -o captioneer ./src/cmd/captioneer ```