Complete 1.6.7 audio and microphone reliability fixes - #779
Conversation
|
The PR Policy check is blocking this PR because required template information is missing. Please update the PR description with:
Visual files detected:
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 SummaryThe PR consolidates the remaining 1.6.7 audio reliability work.
|
There was a problem hiding this comment.
💡 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".
| if let preferredUID = SettingsStore.shared.preferredInputDeviceUID, | ||
| preferredUID.isEmpty == false | ||
| { | ||
| return .preferredUID(preferredUID) |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| guard let selectedInput = self.fallbackInput( | ||
| from: availableInputs, | ||
| defaultInputUID: defaultInputUID | ||
| ) else { return } |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| self.preferredInputDeviceUID = payload.preferredInputDeviceUID | ||
| self.preferredOutputDeviceUID = payload.preferredOutputDeviceUID | ||
| if let microphoneSelectionMode = payload.microphoneSelectionMode { | ||
| self.microphoneSelectionMode = microphoneSelectionMode | ||
| } | ||
| self.enforceAppOnlyMicrophoneSelection() |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| if payload.microphoneSelectionMode == .system { | ||
| self.appMicSelectionMigrationVersion = 0 | ||
| } |
There was a problem hiding this comment.
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
8989c78 to
ce6808a
Compare
There was a problem hiding this comment.
💡 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".
| if payload.microphoneSelectionMode == .system { | ||
| self.appMicSelectionMigrationVersion = 0 | ||
| } |
There was a problem hiding this comment.
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 👍 / 👎.
| guard currentInputUIDs.isEmpty == false else { return false } | ||
| let needsInitialSelection = preferredInputUID?.isEmpty ?? true | ||
| return migrationPending || needsInitialSelection || self.didPreferredInputAvailabilityChange( |
There was a problem hiding this comment.
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 👍 / 👎.
FluidVoice PR build readyDownload 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
This build has its own app identity, so its permissions are separate from the release version of FluidVoice. |
Description
Combines the remaining FluidVoice 1.6.7 audio and microphone reliability work for main.
Type of Change
Related Issue or Discussion
Includes the changes from PR #777 and PR #778, and builds on merged PR #749.
Testing
Screenshots / Video
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.