Skip to content

Labs: Muffle other audio while dictating (macOS) - #1391

Open
R44VC0RP wants to merge 1 commit into
devfrom
muffle-audio
Open

R44VC0RP wants to merge 1 commit into
devfrom
muffle-audio

Conversation

@R44VC0RP

@R44VC0RP R44VC0RP commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

"While dictating" gains Muffle behind Labs › Muffle other audio (labs.muffle, off by default, macOS): other apps keep playing, but low and through a wall, like a club heard from its bathroom.

How it works

  • A muted-when-tapped global Core Audio process tap (Hex's own tones excluded) silences other apps at the output; a private aggregate device holding the tap and the default output replays them through the signal path from its IOProc. Needs System Audio Recording (macOS 14.2+).
  • Signal path (src/audio/muffle.rs, pure, every OS): 400 Hz RBJ low-pass that shuts with a Q 3 → 0.707 thump over 150 ms, level ramped to 40 % over 80 ms, a small Freeverb-shaped room (4 combs, 2 allpasses, +23 samples on the right, feedback 0.72, damp 0.45, wet 0.0875), tanh soft clip above 0.9. Opening sweeps the cutoff to 20 kHz with Q 4 → 0.707 over 200 ms before the tap is torn down.
  • Effect::Muffle composes with the other held effects in recording_environment. Without the Labs feature or the permission, or if the tap fails, the session lowers the audio instead; Linux and Windows treat a saved muffle as Lower audio.
  • General shows the Screen & System Audio Recording row under Muffle (shared with Also pause the browser); the Labs toggle asks for the permission when turned on, never while dictating.
  • hex settings: recording_audio_behavior accepts muffle; labs.muffle added.
  • meeting::create_tap_aggregate takes an optional output sub-device (the muffle aggregate uses it to play; existing callers pass None).

Known gap: a default-output change mid-dictation keeps the old output until the session ends; dictations are short, so no rebuild yet (noted in docs/features/labs.md).

Verification

  • scripts/check: fmt, code-shape, clippy, 2208 tests pass.
  • audio::muffle unit tests: 4 kHz vanishes and 80 Hz passes at the muffled level once shut; opening restores the dry signal within 2 %; silence stays silent and loud input stays bounded; the sweeps start and end where they should.
  • Ignored on-hardware test muffles_the_default_output_for_a_while ran on a Mac with a test tone playing: 271 IO cycles in 3 s, tapped peak 0.60, the door opened before teardown.
  • Goldens: the Labs page gains a row, so the Linux golden tests need regenerating (check-linux.yml → golden-actual).

"While dictating" gains Muffle behind Labs › Muffle other audio
(labs.muffle, off by default, macOS): other apps keep playing, but low
and through a wall, like a club heard from its bathroom. A
muted-when-tapped global Core Audio process tap (Hex's own tones left
out) is replayed onto the default output by a private aggregate device
holding the tap and that output, through a 400 Hz RBJ low-pass that
shuts with a Q 3 -> 0.707 thump over 150 ms, the level ramped to 40 %
over 80 ms, a small Freeverb-shaped room (4 combs, 2 allpasses, +23
samples on the right, feedback 0.72, damp 0.45, wet 0.0875), and a tanh
soft clip above 0.9; opening sweeps the cutoff to 20 kHz with Q 4 ->
0.707 over 200 ms before the tap goes.

- audio/muffle: the pure signal path (every OS) with unit tests.
- recording_environment/muffle: the macOS tap adapter; Effect::Muffle
  composes with the other held effects. Without the Labs feature or
  System Audio Recording, or where the tap fails (macOS before 14.2),
  the session lowers the audio instead; Linux and Windows treat the
  saved value as Lower audio.
- meeting::create_tap_aggregate takes an optional output sub-device,
  which the muffle aggregate uses to play; existing callers pass None.
- General shows the System Audio Recording row under Muffle, as it does
  for Also pause the browser (shared system_audio_row); the Labs toggle
  asks for the permission when turned on, never while dictating.
- hex settings: recording_audio_behavior accepts muffle; labs.muffle.
- The Labs state packs Muffle at bit 32 and moves the unload-idle
  minutes to bit 40.
- Translations for the new strings; feature maps and AGENTS updated.

Verified: scripts/check (fmt, code-shape, clippy, 2208 tests) passes;
the ignored on-hardware test muffles_the_default_output_for_a_while
ran on a Mac with a test tone playing: 271 IO cycles in 3 s, tapped
peak 0.60, the door opened before teardown.

This branch has not been deployed

No deployments
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