Skip to content

Delay dictation overlay until audio capture is ready - #701

Closed
supfeer wants to merge 1 commit into
altic-dev:mainfrom
supfeer:agent/delay-dictation-overlay-after-audio-ready
Closed

Delay dictation overlay until audio capture is ready#701
supfeer wants to merge 1 commit into
altic-dev:mainfrom
supfeer:agent/delay-dictation-overlay-after-audio-ready

Conversation

@supfeer

@supfeer supfeer commented Jul 23, 2026

Copy link
Copy Markdown

Description

Starts audio capture before presenting the dictation UI so the beginning of a spoken phrase is retained.

This PR:

  • marks capture ready only after the first PCM buffer is accepted
  • waits 500 ms of active recording before showing the recording overlay
  • plays the configured dictation start sound when the overlay appears
  • cancels delayed presentation when capture stops or fails
  • keeps app-context capture and AI prewarming on the first-audio boundary

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

Related to #477, #236, and #592.

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version: 26.5.2
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources
  • Ran formatter locally: swiftformat --config .swiftformat Sources
  • Ran tests locally:

Additional validation:

  • Signed Debug build completed successfully.
  • Installed and launched locally with com.FluidApp.local.

Screenshots / Video

  • No UI/visual changes; screenshots/video are not applicable.

The existing overlay appearance and layout are unchanged. This PR only changes when the existing overlay and start sound are presented relative to active audio capture.

Notes

  • Audio acquisition begins before the 500 ms presentation delay.
  • The delay is measured from the first accepted PCM buffer, not from the hotkey event.

@github-actions github-actions Bot added needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 23, 2026
@github-actions

Copy link
Copy Markdown

The PR Policy check is blocking this PR because required template information is missing.

Please update the PR description with:

  • Related Issue or Discussion
  • Screenshots / Video

Visual files detected:

  • Sources/Fluid/ContentView.swift
  • Sources/Fluid/Services/MenuBarManager.swift

Screenshots or video are required for UI, UX, settings, onboarding, overlay, menu bar, or visual behavior changes. If this PR has no visual changes, check the no-visual-change box in the template.

If this remains incomplete for 48 hours after opening, the PR may be closed.

@github-actions github-actions Bot removed needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 23, 2026
@altic-dev

Copy link
Copy Markdown
Owner

This unfortunately goes against the UX I am planning toward - I am still A/B Testing to see which one makes sense and how to animate etc but adding 500ms will ruin the experience. Even the audio only takes ~150ms to start listening.

Thanks for this but I won't be able to merge this as it would break the UX in a v bad way!

For next time, please discuss about this before raising a PR to make sure we can align beforehand.

@altic-dev altic-dev closed this Jul 28, 2026
@aliashov-fnddev

Copy link
Copy Markdown

The original problem was that audio capture and the UI were not synchronized. This description may sound simplistic, but the fix corrects the entire startup flow rather than merely adding a static delay.
The issue is especially frustrating with Bluetooth devices: the overlay indicates that FluidVoice is listening even though the microphone is not yet ready to deliver audio. The UI is now synchronized with the first actual PCM buffer.
The additional 500 ms delay is only a UX refinement. It lets the audio engine run briefly before prompting the user to speak, reducing the chance that speech onset overlaps with recognition startup or audio-channel switching artifacts and clicks.

Previous flow

Hotkey → start sound → audio backend starts → isRunning = true → overlay appears → first PCM buffer arrives

Problems:

  • AVAudioEngine.start() or AudioDeviceStart() could return when the device was formally started but no real audio data had arrived yet.
  • isRunning was set immediately after the backend start method returned.
  • MenuBarManager showed the overlay based on isRunning.
  • ContentView could also independently request the overlay to appear immediately.
  • The start sound played before audio capture was actually ready.
  • With Bluetooth devices, profile switching and first-packet delivery introduced additional delay.

As a result, the overlay and start sound told the user it was safe to speak before AudioCapturePipeline had received a single PCM buffer. If the user started speaking immediately, the beginning of the phrase could be lost.

Correct flow

Hotkey → backend starts → first PCM buffer arrives → 500 ms of active recording → start sound + overlay

@altic-dev

Copy link
Copy Markdown
Owner

Thanks for explanation. I understand the PR and the purpose ofc.

This is more like a patch instead of solving the root problem which is time to capture first audio.

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.

3 participants