Commit Graph
7 Commits
Author SHA1 Message Date
felixmandClaude Opus 5 6ad8526920 Add Voxtral Small 24B as a transcription option
Whisper large-v3 mis-segments unfamiliar proper nouns: "Whisper Large"
came back as "Wisp Alarge", and it leaves doubled words and sentence
breaks in the wrong places. Voxtral decodes with a 24B language model,
so ambiguous acoustics get resolved against what a sentence can mean.
Checked both against saved captures: Voxtral fixed the proper noun and
the punctuation, at 1.7 s round-trip for 15 s of audio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrC2xo3RUExhVPzWGnGfRK
2026-08-22 09:22:13 -04:00
felixmandClaude Opus 5 9d04427816 Trim only the real click, and surface mid-clip dropouts
Transcripts came back short, but the log showed the whole clip going up:
captured samples matched wall clock and upload duration matched the
recording minus exactly the fixed 150 ms head trim. So nothing was being
cut in transit — the losses had to be at the edges or inside the audio,
and neither was visible.

Trim the stream-open click by measurement instead of by the clock: cut
only the leading frames that are genuinely louder than the rest of the
clip, up to the old cap. Mics that do not click now keep their first
syllable.

Measure each frame against its own mean so a steady DC bias — or a
stream frozen on one value — reads as the silence it is, and report the
longest run of digital silence as dead=. A live mic never goes below
DEAD_AIR_DBFS, so anything there is input that never arrived, which is
what following the system default source invites. Warn on startup when
no device is pinned, log the noise floor next to the speech level, and
log how much of the clip the output limiter had to clamp.

BLURT_SAVE_CAPTURES keeps the raw and uploaded WAVs per clip, so the
next short transcript can be checked against what the API actually got.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 20:45:14 -04:00
felixmandClaude Opus 5 e3faf32f55 Fix Linux capture: negotiate rate, condition audio, pin the device
Transcripts were far worse on Linux than on Windows for the same model, because
of what reached the API rather than the model itself.

Picking any mic from the tray menu never worked: PortAudio exposes the friendly
names through PipeWire's JACK host API, which only accepts 48 kHz, so opening at
16 kHz failed outright and recording always fell back to the system default —
whichever source PipeWire happened to prefer at that moment. That source is
often the raw AMD digital mic, which ships a +0.14 FS DC bias, a full-scale
clipped click in the first 15 ms of every stream, and speech around -50 dBFS.
Windows' vendor driver hides all of this; PipeWire hands over the raw stream.

- Negotiate rate and channels per device, then downmix and resample with
  resample_poly, so every listed device can actually be recorded from.
- Hide devices that cannot work: playback endpoints JACK re-exposes as inputs,
  and raw ALSA hw: devices a sound server already owns (acp: hw:2,0 blocks
  forever on open).
- Persist the chosen device by name in device.txt; PortAudio indices shift as
  USB gear comes and goes. Add a "System default" menu entry.
- Condition every clip before upload: trim the warm-up click, high-pass out DC,
  normalise towards -20 dBFS under a -1 dBFS ceiling.
- Refuse near-silent clips instead of paying for a hallucination, and log
  capture levels (speech, rms, peak, DC, clipping) plus PortAudio status
  warnings, which previously went to a discarded stderr.
- Import scipy.signal as dsp: it was shadowing the stdlib signal module that
  the SIGUSR1 hotkey toggle depends on.

mic_check.py records from Blurt's configured input, reports levels before and
after conditioning, saves the WAV, and transcribes it with the current model.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 18:58:39 -04:00
felixm 0ccada8522 Only allow keyring for credentials retrieval 2026-08-15 13:29:22 -04:00
felixm 0b94bcd1c0 Identify Blurt in OpenRouter requests 2026-08-08 15:19:59 -04:00
felixmandClaude Opus 4.8 777d4bef33 Speed up transcription with a pluggable provider backend
Transcription:
- Provider-pluggable backend: each model routes to OpenAI (multipart
  upload) or OpenRouter (JSON + base64 body). Add OpenRouter's
  whisper-large-v3-turbo (Groq-served, ~216x real-time) to the tray
  menu for far lower latency than whisper-1.
- Load API keys env -> keyring -> file for both providers via a shared
  helper.
- Encode the WAV in memory and reuse a warm requests.Session (no temp file).

Other improvements:
- blurt-toggle signals the running app directly via SIGUSR1 instead of
  paying ~0.5s to import the full stack through "uv run blurt toggle".
- Remove the redundant dead blurt shell script.
- Suppress the benign Gdk-CRITICAL warning from pystray's GtkStatusIcon.
- gitignore openrouter_key.txt.

Transcription code is platform-agnostic; the Windows/Linux platform layer
is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 08:38:05 -04:00
felixmandClaude Opus 4.8 4d10653790 Initial commit
Toggle voice-to-text tool with Linux and Windows support.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 23:30:37 -04:00