Skip to content

Complete 1.6.7 audio and microphone reliability fixes - #779

Merged
altic-dev merged 7 commits into
mainfrom
B/app-only-microphone-selection
Aug 5, 2026
Merged

Complete 1.6.7 audio and microphone reliability fixes#779
altic-dev merged 7 commits into
mainfrom
B/app-only-microphone-selection

Conversation

@altic-dev

@altic-dev altic-dev commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Description

Combines the remaining FluidVoice 1.6.7 audio and microphone reliability work for main.

  • Keeps Direct Core Audio capture required and reduces first-audio startup delays.
  • Prevents media playback from remaining paused when Now Playing is slow or settings change during recording.
  • Keeps FluidVoice microphone selection app-only, with a safe built-in fallback and external-microphone preservation.
  • Builds on merged PR Fix Bluetooth headset mode churn while idle #749 by @AshwanthramKL for Bluetooth and audio-device lifecycle reliability.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Chore
  • Documentation update

Related Issue or Discussion

Includes the changes from PR #777 and PR #778, and builds on merged PR #749.

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS 27.0
  • SwiftFormat completed with no changes
  • Strict SwiftLint passed with zero violations
  • Private Fluid Intelligence build installed and launched successfully
  • Focused microphone tests previously passed 40/40; PR Harden media pause and resume lifecycle #778 checks passed

Screenshots / Video

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

Notes

The development build used the supported FluidVoice bridge override because the private bridge manifest is still pinned to the 1.6.6 FluidVoice commit. Rebind and verify that manifest before producing the final private 1.6.7 release.

@github-actions github-actions Bot added the needs screenshots Pull request needs screenshot or video evidence. label Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

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

Please update the PR description with:

  • Screenshots / Video

Visual files detected:

  • Sources/Fluid/ContentView.swift
  • Sources/Fluid/Persistence/SettingsStore.swift
  • Sources/Fluid/Services/MenuBarManager.swift
  • Sources/Fluid/UI/SettingsView.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.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

The PR consolidates the remaining 1.6.7 audio reliability work.

  • Makes Direct Core Audio the required recording backend and revises capture readiness and engine-retirement synchronization.
  • Changes microphone selection to an app-only preference with migration and fallback handling.
  • Preserves media-pause ownership across recording-time settings changes and slow Now Playing responses.
  • Updates menu, settings, and focused integration tests for the revised behavior.

Confidence Score: 5/5

The PR appears safe to merge within the scope of this follow-up review.

No eligible new comments or supplied outstanding prior findings leave a blocking failure.

Reviews (7): Last reviewed commit: "fix(ci): shorten microphone test identif..." | Re-trigger Greptile

@github-actions github-actions Bot removed the needs screenshots Pull request needs screenshot or video evidence. label Aug 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e11bb3109b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +911 to 914
if let preferredUID = SettingsStore.shared.preferredInputDeviceUID,
preferredUID.isEmpty == false
{
return .preferredUID(preferredUID)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve direct capture through the mic fallback

With direct Core Audio enabled by default, this path bypasses MicrophonePreferenceCoordinator.inputDeviceForCapture(). If the stored app mic UID is stale—for example the selected USB/Bluetooth mic was unplugged while FluidVoice was quit, or a system-mode backup restored an old preferred UID—resolveDevice(.preferredUID) throws on every start attempt even though the coordinator would pick the built-in/current-default fallback. Use the coordinator (and persist the fallback when appropriate) before returning .preferredUID so recording can still start.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5119281e75

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +56 to +59
guard let selectedInput = self.fallbackInput(
from: availableInputs,
defaultInputUID: defaultInputUID
) else { return }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve available preferences on mic migration

When upgrading an existing install on Macs with no built-in input device, this migration ignores an already-available saved FluidVoice mic and then overwrites preferredInputDeviceUID with the macOS default or first input. For example, a Mac mini user who had FluidVoice set to a USB studio mic while the system default is a monitor/webcam mic will be moved back to the system default on first launch, which breaks the app-only selection this change is trying to preserve. Prefer the built-in mic when present, but otherwise keep the stored preferred UID if it is still in availableInputs before falling back.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a40737a3d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 3124 to +3126
self.preferredInputDeviceUID = payload.preferredInputDeviceUID
self.preferredOutputDeviceUID = payload.preferredOutputDeviceUID
if let microphoneSelectionMode = payload.microphoneSelectionMode {
self.microphoneSelectionMode = microphoneSelectionMode
}
self.enforceAppOnlyMicrophoneSelection()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Re-run microphone migration for restored system-mode backups

When a user restores an older backup after this install has already completed the app-only migration, this restores the backup’s preferredInputDeviceUID and then forces manual mode without resetting appMicSelectionMigrationVersion. If that backup was in macOS-default/system mode but still carried an old available manual UID, the backup-restore recovery skips migration and keeps using that old mic instead of mapping the restored system-mode state through the built-in/default fallback. Reset the migration version or explicitly migrate payload.microphoneSelectionMode == .system payloads before enforcing app-only selection.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8989c78bab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3126 to 3128
if payload.microphoneSelectionMode == .system {
self.appMicSelectionMigrationVersion = 0
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark app-only backups as already migrated

When a backup created by this app-only version is restored onto a fresh install or any profile where AppOnlyMicrophoneSelectionMigrationVersion is still 0, this branch leaves the migration pending because the payload mode is .manual. The next ASR initialization then treats the restored preferredInputDeviceUID as a legacy/system-mode value and migrateToAppOnlySelectionIfNeeded will prefer the built-in mic over the backed-up app mic, even when that saved mic is available. For non-system payloads, restore should mark the app-only migration complete (or persist/restore the migration version) so manual backups keep their selected microphone.

Useful? React with 👍 / 👎.

* fix(audio): require direct Core Audio capture

* perf(audio): skip idle engine retirement barriers

* perf(audio): remove cold readiness actor hop

* fix(audio): close readiness cancellation race

* fix(audio): preserve pre-registration cancellation
@altic-dev
altic-dev force-pushed the B/app-only-microphone-selection branch from 8989c78 to ce6808a Compare August 5, 2026 03:48
@altic-dev
altic-dev changed the base branch from B/audio-fix-1.6.7-base to main August 5, 2026 03:49
@altic-dev altic-dev changed the title Make microphone selection app-only with safe fallback Complete 1.6.7 audio and microphone reliability fixes Aug 5, 2026
@github-actions github-actions Bot added needs screenshots Pull request needs screenshot or video evidence. and removed needs screenshots Pull request needs screenshot or video evidence. labels Aug 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b9339546e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3126 to 3128
if payload.microphoneSelectionMode == .system {
self.appMicSelectionMigrationVersion = 0
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat missing mic mode as legacy system mode

When restoring backups created before microphoneSelectionMode existed, the decoded payload value is nil because the field is optional, and older builds treated an absent stored mode as .system. This check only resets appMicSelectionMigrationVersion for an explicit .system, so restoring one of those legacy system-mode backups onto an install that already has migration version 1 leaves the backup's old preferredInputDeviceUID marked as a completed app-only selection; if that UID is still available, reconciliation keeps using it instead of remapping the restored system-mode state through the built-in/default fallback. Treat nil like .system here.

Useful? React with 👍 / 👎.

Comment on lines +21 to +23
guard currentInputUIDs.isEmpty == false else { return false }
let needsInitialSelection = preferredInputUID?.isEmpty ?? true
return migrationPending || needsInitialSelection || self.didPreferredInputAvailabilityChange(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile stale mics after empty topology

If the selected mic is removed while Core Audio temporarily reports no inputs, this returns false; handleDeviceListChanged then caches the empty UID set. When a fallback mic later appears, the preferred UID is absent from both the previous and current sets and migrationPending is false, so no reconciliation or prewarm is scheduled; the next direct capture still resolves the stale stored preferred UID and fails instead of persisting the fallback. Reconcile when devices reappear and the saved preferred UID is still absent.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

FluidVoice PR build ready

Download FluidVoice-PR-779-7b9339546ea8

The artifact contains the ad-hoc-signed app ZIP, Xcode archive, build manifest, and installation instructions. It expires 5 days after the build.

Install the app

  1. Extract the downloaded artifact, then extract FluidVoice-PR-779.app.zip.

  2. Move FluidVoice Complete 1.6.7 audio and microphone reliability fixes #779.app into the /Applications folder.

  3. Open Terminal and remove the download quarantine marker:

    xattr -dr com.apple.quarantine "/Applications/FluidVoice #779.app"
    
  4. In Applications, Control-click FluidVoice Complete 1.6.7 audio and microphone reliability fixes #779.app and choose Open.

  5. If macOS still blocks it, open System Settings → Privacy & Security, click Open Anyway, and confirm.

This build has its own app identity, so its permissions are separate from the release version of FluidVoice.

View workflow run

@altic-dev
altic-dev merged commit d2df033 into main Aug 5, 2026
6 checks passed
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