feat: implement host-audio-orchestrator#3
Merged
Conversation
Integrate SimplyCoreAudio 4.1.0 for Core Audio device enumeration and add AppFadersTests test target with placeholder test verifying import.
Updated tasks.md for host-audio-orchestrator to reflect completion of AppFadersProperty enum and VolumeStore implementation.
…ting Add missing isPropertySettable handler for AppFadersProperty.setVolume so CoreAudio clients can properly query settability before IPC calls. Also fix extraneous blank lines in getPlugInPropertyDataSize.
Introduces the TrackedApp struct to represent and identify running applications within the host orchestrator. Includes a convenience initializer from NSRunningApplication and implements custom value semantics for Hashable and Equatable to handle NSImage correctly.
Implements LocalizedError for device discovery, property I/O, and volume validation cases. Completes task 6 of the orchestrator spec.
Implements a thread-safe wrapper around SimplyCoreAudio to discover the virtual device and observe system-wide device list changes. Includes automatic observer cleanup and identification of the AppFaders driver by UID.
87fcc37 to
584c9d8
Compare
Refactoring required for DeviceManager
…ions Refactors DeviceManager to use a modern AsyncStream for audio device list changes instead of closures and manual lock management. - Replaces onDeviceListChanged callback with deviceListUpdates AsyncStream. - Removes NSLock and ThreadSafeArray as state is now managed via structured concurrency. - Uses NotificationCenter.notifications(named:) for Swift 6.2 compliance. - Implements [weak self] and proper task cancellation.
Uses NSWorkspace notifications to track application lifecycle and emits events via a modern AsyncStream. - Tracks app launch and termination using structured concurrency. - Manages thread-safe state for currently running applications. - Filters processes by bundle identifier to ensure trackability. - Integrates with the updated orchestrator design using Swift 6.2 patterns.
…esign Updates the technical stack and architectural design to use CAAudioHardware by sbooth as the primary HAL wrapper. - Swaps SimplyCoreAudio dependency for CAAudioHardware in tech.md. - Refactors design.md architecture and component interfaces to use CAAudioHardware types. - Adds migration tasks 9 and 10 to tasks.md for dependency replacement and DeviceManager refactoring. - Renumbers subsequent tasks 11-17 to maintain spec consistency.
Updates Package.swift and Package.resolved to use sbooth/CAAudioHardware version 0.7.1.
Migrates the DeviceManager component from SimplyCoreAudio to CAAudioHardware, which is actually maintained.
Creates DriverBridge.swift for low-level IPC with the virtual driver. - Handles serialization of VolumeCommand for setAppVolume. - Uses AudioObject properties for setAppVolume and getAppVolume. - Incorporates NSLock for thread safety of deviceID access. - Adds null terminator to bundleID when retrieving volume to ensure C-string compatibility with the driver.
AudioOrchestrator for coordinating app state, device connection, and IPC. Updates DeviceManager to be Sendable and refreshes spec documentation (tasks.md, design.md, requirements.md) for accuracy.
Sets up AudioOrchestrator startup, SIGINT handling, and the main execution loop via dispatchMain.
Implement unit tests for VolumeStore covering volume operations, clamping, and thread-safety using the Swift Testing framework.
Add unit tests for AppAudioMonitor and TrackedApp. Refactor AppAudioMonitor to prevent duplicate launch events and add an internal initializer to TrackedApp for testing.
Added unit tests for DriverBridge and made DriverError Equatable.
Exposes driver's getAppVolume via public method for reading current volume levels back from the driver, complementing existing setVolume.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Phase 2 of AppFaders: building the host-side orchestration layer that connects the virtual audio driver to running applications. This branch implements device discovery via CAAudioHardware, app lifecycle monitoring via NSWorkspace, and an IPC bridge using custom AudioObject properties.
big problem: Integration testing shows coreaudiod blocks custom property writes with
kAudioHardwareUnknownPropertyError. The'afvc'/'afvq'property approach is NOT viable for host-driver communication. An architectural pivot to XPC or Mach ports will be required.Changes Made
Host Components:
AudioOrchestrator- central @observable coordinator with tracked apps, volumes, driver connection stateDeviceManager- CAAudioHardware wrapper with AsyncStream for device list updatesAppAudioMonitor- NSWorkspace app tracking with AsyncStream eventsDriverBridge- IPC via custom AudioObject properties (blocked by coreaudiod)TrackedApp- Sendable model for running applicationsDriverError- typed errors for driver communicationDriver-side:
VolumeStore- thread-safe per-app volume storageVirtualDevicefor'afvc'(setVolume) and'afvq'(getVolume)AppFadersPropertyenum with custom selectorsTests:
Testing Notes
swift test- all unit tests passScripts/install-driver.sh- driver installs and registers successfullyswift run AppFaders- host connects to driver, but setVolume fails withkAudioHardwareUnknownPropertyErrorNext step: Evaluate XPC service or Mach ports for IPC.