Skip to content

Recording safety cap + runtime GPU settings + optional audio cues (fixes #25, #23, #24) - #26

Merged
benmaster82 merged 3 commits into
mainfrom
fix/recording-safety-and-runtime-settings
Sep 5, 2026
Merged

Recording safety cap + runtime GPU settings + optional audio cues (fixes #25, #23, #24)#26
benmaster82 merged 3 commits into
mainfrom
fix/recording-safety-and-runtime-settings

Conversation

@benmaster82

@benmaster82 benmaster82 commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Addresses three open issues reported by @MaxiKingXXL. Split into three self-contained, per-issue commits - reviewable one at a time.

fixes #25 - Hold-mode recording safety cap + session isolation

In hold-to-record mode a recording had no maximum duration: a missed key-release left the mic recording indefinitely, and audio could leak across modes via the shared Recorder.

  • Arm the MAX_RECORD_SECONDS safety timer in hold mode too (was toggle-only). On timeout in hold mode the mic stops and the overrun audio is discarded, never pasted into the focused window.
  • Track recorder ownership (single owner + generation counter): stale timers self-cancel, stops for a non-owning mode are ignored, and an inherited buffer is discarded when a new session starts.
  • New HotkeyListener.reset_dictation_state / reset_assistant_state so a lost key-release no longer wedges the hotkey.

fixes #23 - Compute device & precision configurable at runtime

Packaged-exe users couldn't enable CUDA or change precision without editing config.py.

  • Settings gains a Performance section: compute device (CPU / CUDA) and precision (int8 / float16 / float32), a CUDA-runtime hint, and a restart-required note.
  • main._load_settings reads and validates the persisted device / compute_type (invalid values ignored, defaults kept).

fixes #24 - Optional audio cues for dictation start/stop

Off by default; opt-in from Settings for eyes-free confirmation and pacing.

  • New audio_cues.py: renders two short WAV tones in memory (high on start, low on stop) and plays them with winsound.PlaySound(SND_MEMORY | SND_ASYNC) on a daemon thread - non-blocking, failures swallowed, no-op off Windows.
  • Wired into the dictation path only; exactly one stop cue per session across hold / toggle / timeout.

Testing

  • New: test_recording_safety.py, test_audio_cues.py, test_runtime_settings.py, plus reset-state cases in test_hotkey.py.
  • Full suite: 132 passed, 88 subtests passed.
  • New user-facing strings localised in EN / IT / DE.

benmaster82 and others added 3 commits September 5, 2026 11:20
In hold-to-record mode a recording had no maximum duration: if the global
keyboard listener observed a hotkey press but never the matching release,
the microphone stayed active indefinitely, and audio could leak from one
mode/session into another via the shared Recorder.

- Arm the MAX_RECORD_SECONDS safety timer in hold mode too, not just toggle.
  On timeout in hold mode the mic stops and the (overrun) audio is discarded
  rather than transcribed and pasted into whatever window has focus.
- Track recorder ownership with a single owner + generation counter so a
  stale timer self-cancels and a stop for a non-owning mode is ignored.
- Discard an inherited buffer when a new session starts while the recorder
  is still owned, preventing cross-mode audio contamination.
- Add HotkeyListener.reset_dictation_state/reset_assistant_state so a lost
  key-release no longer wedges the hotkey (stuck _pressed flag).
- Tests: test_recording_safety.py (ownership, hold/toggle timeout, stale
  timers) and reset-state cases in test_hotkey.py.
- Also ignore local release .zip packages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197YwE2oqsrH6JmPPRUJ66M
Packaged-exe users could not enable CUDA or change compute precision without
editing config.py, even though the transcriber already honours DEVICE and
COMPUTE_TYPE. Expose both through the existing settings mechanism, following
the same DB-persisted pattern as the other runtime settings.

- Settings window: a "Performance" section with a compute-device dropdown
  (CPU / CUDA) and a compute-precision dropdown (int8 / float16 / float32),
  a hint about the CUDA runtime requirement, and a restart-required note.
- main._load_settings reads and validates the persisted "device" and
  "compute_type" values (invalid values are ignored, keeping the defaults).
- Localised the new labels/hint in EN, IT and DE.
- Tests: test_runtime_settings.py covers the callbacks and the load path,
  including invalid-value rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197YwE2oqsrH6JmPPRUJ66M
Off by default; enable from Settings to get eyes-free confirmation and a
pacing cue so you don't clip the start of your speech.

- audio_cues.py: renders two short WAV tones in memory (high on start, low
  on stop) and plays them with winsound.PlaySound(SND_MEMORY | SND_ASYNC) on
  a daemon thread. Non-blocking, so recording and hotkey callbacks are never
  delayed; any playback failure is logged at debug and swallowed. No-op off
  Windows.
- Cues are wired into the dictation path only: start in _on_hotkey_press,
  stop in _on_hotkey_release, and the hold-mode safety-stop plays the stop
  cue too — exactly one stop cue per session across hold/toggle/timeout.
- Settings: a "Recording sound cues" toggle, persisted as the "audio_cues"
  setting and loaded in main._load_settings. Localised in EN, IT and DE.
- Tests: test_audio_cues.py (valid WAV, SND_MEMORY playback, swallowed
  backend errors, off-Windows no-op, distinct pitches) plus audio-cue cases
  in test_runtime_settings.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197YwE2oqsrH6JmPPRUJ66M
@benmaster82
benmaster82 merged commit 013994e into main Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant