Repository navigation
feat: opt-in local control API for external controllers - #476
Open
davidprokopec wants to merge 5 commits into
Open
davidprokopec wants to merge 5 commits into
davidprokopec wants to merge 5 commits into
Conversation
davidprokopec
marked this pull request as ready for review
October 20, 2026 18:08
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.
Motivation
I use FineTune for its per-app volume, output routing, and microphone/device switching, and I want to build richer integrations around those existing capabilities—not implement a competing audio engine. For example, a hardware controller should be able to adjust FineTune-managed volume, mute, and routing while its faders and lights stay synchronized with changes made in FineTune itself.
Keeping FineTune responsible for audio processing lets external tools focus on control and automation without maintaining another capture/routing pipeline. FineTune’s troubleshooting guide notes that some audio-processing and routing applications can interfere with its process taps. Multiple audio tools are not universally incompatible, but overlapping pipelines can create configuration-dependent problems; this API avoids adding a second pipeline. This is not a claim of a confirmed FineTune/Wave Link incompatibility.
Hardware controllers such as a Stream Deck or a Novation Launchpad can already drive FineTune through
finetune://URLs, but only one way: they can't read the current volume, mute or routing, so faders and button lights drift as soon as something changes in FineTune's own UI. This PR adds a small, opt-in local API so a controller can read FineTune's state, follow changes live, and send absolute commands.What it adds
~/Library/Application Support/FineTune/Control/control.sock, using newline-delimited JSON (protocolfinetune-control, version 1).setAppVolume,setAppMute,setAppRouting(follow default or a single output; multi-output stays read-only in v1),setDefaultOutput, andsetPreferredInput. Preferred input goes through FineTune's existing input-lock/priority path.pending/applied/failedseparately from what was requested.guide/control-api.md(linked from the README).Security model
Controldirectory is created with mode0700and the socket with0600. The peer UID is checked withgetpeereidbefore any bytes are read.Engine changes
DeviceVolumeMonitorcaches readability and backend metadata during its normal refreshes, so snapshots never probe the HAL on the main thread.setLockedInputDevicereturns the existing result of thesetDefaultInputDevicecall.AudioRecordingPermission(status:),AutoEQProfileManager(loadAutomatically:)) default to the current production behaviour.Verification
xctestand without launching the app. They use fakes and temporary sockets only.0700/0600permissions, andhello/getStatereport the devices, defaults, input policy and permission correctly. A Novation Launchpad client (Lunchpad) subscribed and changed a real app's volume and mute, the client's faders and lights followed changes made in FineTune's own UI, and output routing changes worked.Non-goals
Controller plugins and mappings, network or remote access, audio streaming or meters, EQ/boost editing, Bluetooth control, a generic RPC layer, and changes to the URL actions.
This is independent of #222.