mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 10:56:10 +00:00
Ship full-resolution WebP screenshots, drop em dashes everywhere
The screenshots were downscaled to 430 px wide, which made the UI text blurry. Restore them at native 1292 px as lossless WebP, which is also half the size of the original PNGs (72 KB against 155 KB for the largest). Rewrite every em dash in prose, comments, docstrings and interface strings as ordinary punctuation.
This commit is contained in:
@@ -5,19 +5,19 @@ transcription, a model on OpenRouter cleans it up (dropping the *uh*s, the
|
||||
restarts, the missing punctuation), and the result lands in your clipboard and
|
||||
is pasted into whatever window you were typing in.
|
||||
|
||||
Built for KDE Plasma 6 on Wayland. No dependencies beyond system packages —
|
||||
Built for KDE Plasma 6 on Wayland. No dependencies beyond system packages:
|
||||
just the Python standard library and PyQt6.
|
||||
|
||||
*[Türkçe README](README.tr.md)*
|
||||
|
||||
<p align="center">
|
||||
<img src="docs/settings-general.png" width="820" alt="Dikte settings — General">
|
||||
<img src="docs/settings-general.webp" width="820" alt="Dikte settings, General tab">
|
||||
</p>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| <img src="docs/settings-api.png" width="410" alt="API and models"> | <img src="docs/settings-cleanup.png" width="410" alt="Cleanup rules"> |
|
||||
| <img src="docs/settings-audio-file.png" width="410" alt="Audio file"> | <img src="docs/settings-history.png" width="410" alt="History"> |
|
||||
| <img src="docs/settings-api.webp" width="410" alt="API and models"> | <img src="docs/settings-cleanup.webp" width="410" alt="Cleanup rules"> |
|
||||
| <img src="docs/settings-audio-file.webp" width="410" alt="Audio file"> | <img src="docs/settings-history.webp" width="410" alt="History"> |
|
||||
|
||||
## Install
|
||||
|
||||
@@ -35,9 +35,9 @@ systemctl --user enable --now ydotool # needed for auto-paste
|
||||
|
||||
Two API keys go in the settings window:
|
||||
|
||||
- **OpenAI** — speech to text (`gpt-4o-transcribe`). Falls back to the
|
||||
- **OpenAI**: speech to text (`gpt-4o-transcribe`). Falls back to the
|
||||
`OPENAI_API_KEY` environment variable when left empty.
|
||||
- **OpenRouter** — transcript cleanup (`google/gemini-3.5-flash-lite` by
|
||||
- **OpenRouter**: transcript cleanup (`google/gemini-3.5-flash-lite` by
|
||||
default, any model on the list works). Falls back to `OPENROUTER_API_KEY`.
|
||||
Cleanup can be switched off entirely, in which case the raw transcript is
|
||||
pasted.
|
||||
@@ -59,26 +59,26 @@ working in.
|
||||
|
||||
## Silence never reaches the API
|
||||
|
||||
Handed near-silence, a transcription model does not return an empty string —
|
||||
it invents one. Whisper is notorious for answering a quiet two seconds with
|
||||
Handed near-silence, a transcription model does not return an empty string.
|
||||
It invents one. Whisper is notorious for answering a quiet two seconds with
|
||||
"Thanks for watching" or, in Turkish, "Altyazı M.K.". An accidental
|
||||
`Ctrl+Space` would otherwise cost you an API call and paste a sentence you
|
||||
never said.
|
||||
|
||||
Dikte checks before spending the call, and the check is relative rather than
|
||||
absolute — microphone gain varies far too much between machines for a fixed
|
||||
threshold to mean anything. A recording is dropped when any of these holds:
|
||||
absolute, because microphone gain varies far too much between machines for a
|
||||
fixed threshold to mean anything. A recording is dropped when any of these holds:
|
||||
|
||||
- the loud end of it sits below the absolute floor (default −55 dBFS);
|
||||
- the loud end of it sits below the absolute floor (default -55 dBFS);
|
||||
- nothing rose 10 dB above *this recording's own* noise floor for at least
|
||||
0.3 s — which is also what removes steady fan or hiss, however loud;
|
||||
0.3 s, which is also what removes steady fan or hiss, however loud;
|
||||
- the level never moved at all near the floor.
|
||||
|
||||
When something slips through anyway, a second filter catches the handful of
|
||||
stock phrases the models fall back on, but only for clips under six seconds,
|
||||
so a genuine "thanks for watching the demo" survives.
|
||||
|
||||
The indicator reports the level it measured (`No speech detected (−56 dB)`),
|
||||
The indicator reports the level it measured (`No speech detected (-56 dB)`),
|
||||
which is what you calibrate the threshold against if your microphone is
|
||||
unusually quiet or unusually noisy.
|
||||
|
||||
@@ -87,9 +87,9 @@ unusually quiet or unusually noisy.
|
||||
Settings → **Audio file** takes any audio or video file and runs it through the
|
||||
same models. Two options, both remembered between runs:
|
||||
|
||||
- **Add timestamps** — prefixes every segment with `[mm:ss]`. This switches to
|
||||
- **Add timestamps**: prefixes every segment with `[mm:ss]`. This switches to
|
||||
`whisper-1`, the only model that returns segment times.
|
||||
- **Run the cleanup model afterwards** — same cleanup as live dictation, with an
|
||||
- **Run the cleanup model afterwards**: same cleanup as live dictation, with an
|
||||
extra rule telling the model to leave the timestamps alone.
|
||||
|
||||
Long files are converted to 16 kHz mono with ffmpeg and split into ten-minute
|
||||
@@ -102,8 +102,8 @@ KWin only reads `kglobalshortcutsrc` at startup. `install.sh` writes the
|
||||
shortcut to the right place, but **it will not fire until you log out and back
|
||||
in.** Two ways around that:
|
||||
|
||||
1. Log out and in — the clean solution. The key is swallowed by KWin, so it
|
||||
never leaks into other applications.
|
||||
1. Log out and in. This is the clean solution: the key is swallowed by KWin,
|
||||
so it never leaks into other applications.
|
||||
2. Settings → Shortcut → turn on the **built-in listener**. It reads
|
||||
`/dev/input` and catches the combination itself, working immediately. The
|
||||
difference: it does not swallow the key, so `Ctrl+Space` also reaches the
|
||||
@@ -115,17 +115,17 @@ The built-in listener needs your user to be in the `input` group:
|
||||
|
||||
## Settings
|
||||
|
||||
Stored in `~/.config/dikte/config.json`, mode 600 — the API keys live there.
|
||||
Stored in `~/.config/dikte/config.json`, mode 600, since the API keys live there.
|
||||
|
||||
| Setting | What it does |
|
||||
| --- | --- |
|
||||
| Interface language | Turkish, English, or follow the system locale |
|
||||
| Microphone | Pick a specific source or use the default |
|
||||
| Speech language | Language hint for transcription, or automatic detection |
|
||||
| Paste key | `ctrl+v` / `ctrl+shift+v` / `shift+insert` — terminals usually want the second |
|
||||
| Paste key | `ctrl+v` / `ctrl+shift+v` / `shift+insert`. Terminals usually want the second |
|
||||
| Restore clipboard | Puts your previous clipboard back after pasting |
|
||||
| Skip silent recordings | Drops recordings with no speech before any API call — see above |
|
||||
| Cleanup rules | The system prompt handed to the cleanup model — this is where you decide how much it may touch your words |
|
||||
| Skip silent recordings | Drops recordings with no speech before any API call, see above |
|
||||
| Cleanup rules | The system prompt handed to the cleanup model. This is where you decide how much it may touch your words |
|
||||
| Transcription hint | Names and terms you use often, so they get spelled correctly |
|
||||
| Keep audio files | WAVs are kept in `~/.local/share/dikte/recordings` |
|
||||
|
||||
@@ -159,4 +159,4 @@ i18n.py the string table
|
||||
|
||||
## License
|
||||
|
||||
GPL-3.0 — see [LICENSE](LICENSE).
|
||||
GPL-3.0, see [LICENSE](LICENSE).
|
||||
|
||||
Reference in New Issue
Block a user