-
Notifications
You must be signed in to change notification settings - Fork 0
Platform Notes
AudioHub runs on macOS and on Windows 10 version 2004 (build 19041) or later. Nothing below that build is considered.
This page covers only the things the two operating systems do differently. Modes, pairing, transport, quality and volume behave the same on both and are described on Operating Modes, Discovery and Pairing and the pages beside them.
On Windows the rules are different and much shorter — see Windows permissions.
macOS grants these per application, and its rule is unforgiving: once a permission is denied, the application can never prompt again — it has to be switched on by hand in System Settings. AudioHub therefore asks for what it needs up front, and every row you see is a live probe. Nothing is remembered on disk: what an attempt learned is held in memory and dies with the service, so a permission you revoke in System Settings does not leave a stale green row behind.
| Row | What it is for | Marked required |
|---|---|---|
| Microphone | Sharing this Mac's microphone with a paired host | Yes |
| Local Network | Finding peers on the LAN and connecting to them | Yes |
| System Audio | Sending what this Mac is playing to the peer's speaker | No |
"Required" is AudioHub's own judgement, not the system's. The first two are load-bearing in every mode; System Audio backs one capture source only, so the first-run gate lets you past without it.
Two rows behave in ways that look like defects and are not:
- Local Network can never read as Denied. macOS publishes no query API for it. The row reads Granted only once an mDNS answer has actually arrived during this run of the service; otherwise it reads Unknown. Its button says Check Settings rather than Grant, because the app cannot raise that dialog on demand — macOS asks the first time AudioHub touches the LAN.
- System Audio cannot be checked in advance either. The call that would answer the question is the same call that raises the prompt, so the row stays Unknown until you first enable system-audio capture.
Screen Recording is not one of the three rows. The ScreenCaptureKit capture backend below needs it, and macOS defines no usage-description key for that consent, so its dialog is worded entirely by the system and can only be managed from System Settings afterwards.
Without this grant AudioHub cannot browse for peers and cannot dial one — including pairing by a typed IP address. That is the part users get backwards, because macOS never reports it as a permission problem. It reports it as a network problem, in two different disguises:
| What AudioHub does | What macOS does when the grant is missing |
|---|---|
| Sends the mDNS query | Accepts the send, then silently discards the packet. A LAN with nothing to answer looks identical. |
| Opens a TCP connection to a peer | Fails with No route to host (errno 65) — a fabricated EHOSTUNREACH, not a permission error. |
The diagnostic rule, from a real incident: if AudioHub logs
No route to host for a peer while another program on the same Mac reaches the
same host and port (nc -z <ip> 47810 succeeds, ping is clean), stop suspecting
the network. It is the Local Network grant. In the recorded case the daemon
failed 26 consecutive reconnects this way, with the peer online and listening
the whole time.
The grant is attached to a program's code identity, so anything that changes that identity — rebuilding or re-signing the app the service is running from — revokes it silently and produces exactly the symptom above. This is the reason the background service is installed and re-signed rather than run from inside the app bundle; see below.
There are two backends. Both are side taps: they read what is already playing, and your output device is never touched or switched.
| Backend (as the picker labels it) | Needs | Permission it asks for |
|---|---|---|
Audio Process Tap (mac-catap) |
macOS 14.2+ | System Audio Recording |
Screen capture audio (mac-sck) |
macOS 13.0+ | Screen Recording |
Both exclude AudioHub's own playback from the capture, so neither can feed the peer's audio back to the peer.
What Auto picks. The list is walked in order and the first available entry
wins, so Auto resolves to the process tap wherever the process tap exists.
Screen capture audio is selected automatically only on macOS 13.0 through
14.1, where the process tap does not exist at all. That band is the entire
reason the second backend was built.
The ordering is the whole mechanism, and it is deliberate: the process tap asks for the narrower grant, so putting it first is what keeps a 14.2+ Mac from ever being asked for screen access. You can still select screen capture audio by hand on a 14.2+ machine; it will then ask for Screen Recording, and macOS re-asks for that grant periodically.
Below macOS 13 there is no backend at all. System audio is then disabled in the Source picker, with the note System capture unavailable · Microphone only.
The picker sits on each peer's card, under Source → Backend, and offers Auto plus every backend it knows about. An entry the current Mac cannot run is shown as (unavailable). There is a second marking, (unsupported), for a backend this project has ruled out permanently — nothing carries that marking in this release, so every greyed-out backend row you can see is one an OS upgrade would fix.
Not yet measured: the screen capture audio path has never been run end to end. Its first capture raises the Screen Recording prompt, which needs a human to click it. Prompt behaviour, device-switch handling, CPU cost and long-run stability are unmeasured for both macOS backends.
On macOS the app does not run the copy of the audio service sealed inside its own bundle. There is a one-time install step instead, and you will see a standard administrator authorization prompt for it.
What that step does:
- Copies the service out of the app bundle into
/Library/Application Support/AudioHub/service/versions/, under a directory named for the copy's own SHA-256. A root-ownedcurrentsymlink selects the active version. -
Generates a signing certificate on this machine — a self-signed identity
called
AudioHub Local Code Signing, held in a root-only keychain — and signs the installed copy with it. That certificate exists only on your machine; it is never part of a build.
The reason for the local re-sign is permissions, and it is the same code-identity rule described under Local Network: macOS remembers microphone, screen-recording and Local Network consent against a program's code identity. A copy signed once on this machine keeps a stable identity across app updates, so the consent you granted stays granted.
Three things this is not:
- Not a root service. Only the install step is privileged. The audio service itself runs as you, the logged-in user — it has to, because Core Audio and the Local Network permission are properties of the interactive session.
- Not a launch daemon. Startup at login registers a per-user LaunchAgent that launches the app; see Settings Reference.
- Not a privileged helper. The elevation is an in-process administrator authorization, so the prompt is attributed to AudioHub itself rather than to a generic scripting process.
AudioHub has to be at /Applications/AudioHub.app. The install refuses
otherwise, with "Install and open AudioHub using AudioHub.pkg before installing
its service". Dragging the app somewhere else out of the disk image produces
that message.
Older versions are not cleaned up: each installed version keeps its own
hash-named directory, and there is no prune step. Uninstall AudioHub.app in
the disk image removes them all.
If no verified installed service is present, a release build reports that and asks you to run the install action rather than quietly falling back to the copy in the bundle. That is deliberate — the fallback would work, and would then break your permissions the next time the app was rebuilt.
On Windows none of this applies: the service sits beside the app under Program Files and is launched directly, with no separate install step and no re-signing.
macOS uses a Core Audio Server Plugin — user space, ordinary code signing is
sufficient, no kernel extension and no reduced security mode. It installs to
/Library/Audio/Plug-Ins/HAL/ and talks to the service over a shared-memory
ring.
Installing it is a separate, explicit action from installing the service above: the button is in Settings › Mode, beside the mode picker, and it relabels itself Install Driver / Update Driver / Repair Driver according to what it finds. Confirming it raises a system authorization prompt and pauses system audio briefly while the driver loads. Neither the app's installer nor the pkg ever creates system audio devices on its own.
Driver and service must agree exactly on a protocol version. The check is
equality, not a minimum, and both platforms work this way. A driver left over
from an older AudioHub does not run in a degraded mode — it publishes nothing,
so the symptom is no AudioHub devices in the system list at all while
everything else looks healthy. Settings › Mode names the mismatch and shows both
numbers, as (service v3 / driver v2), and the install button becomes Update
Driver. Press it.
This is intentional: a tolerant version check would have produced subtly wrong audio instead of an obvious refusal. Concretely, the version that shipped before this one published both a speaker and a microphone for every peer; the current one publishes only the directions the peer actually has. An old driver would ignore that instruction and silently publish both.
The two platforms carry separate, independent version numbers — macOS is at 3 and Windows at 6. They are not meant to match, and a macOS 3 next to a Windows 6 is not a sign that either is out of date. Compare a driver only against the service on the same machine.
Both numbers were last raised in the 2026-08-14 build, so a driver installed before then needs reinstalling.
AudioHub carries a single mono channel today, in every mode. Multichannel PCM, Dolby, DTS and object audio do not survive the link, whatever the source was. The virtual devices declare two channels to the operating system on both platforms, but what crosses the network between the two machines is one channel.
Two consequences worth stating plainly:
- Apple Spatial Audio is closed to third-party HAL devices. Only Apple's own and certified output devices can take part; no virtual device can declare it, and there is nothing you can install to change that. macOS also has no equivalent of Windows' Dolby Access.
- AudioHub offers no passthrough route. Handing an encoded bitstream through untouched, to be decoded by hardware at the far end, is a design direction with a reserved codec id and no implementation. Do not plan around it.
What does work is what already arrives as PCM: apps that render Atmos or E-AC3 internally — Apple Music with Dolby Atmos set to Always On, IINA, VLC — hand macOS ordinary PCM, and the virtual device accepts that like any other audio. It is still downmixed to mono before it leaves the machine.
Windows does not gate audio access per application the way macOS does, so nothing here needs granting before AudioHub works. The permission rows still appear in Settings, and they all report Granted.
What can still block AudioHub on Windows is the firewall, which is a different mechanism entirely — the installer's inbound rule covers the Domain and Private network profiles only, so on a network Windows has classified as Public, peers cannot reach this machine. See Discovery and Pairing for the ports involved.
Two backends, selected at runtime:
| Backend (as the picker labels it) | Needs | Excludes AudioHub's own playback |
|---|---|---|
Process loopback (win-proc-exclude) |
Windows 10 2004, build 19041 | yes |
Device loopback (win-device-loopback) |
always available | no |
Process loopback is first in the list, so Auto picks it wherever it is
available. Excluding AudioHub's own output is what prevents the feedback loop
you would otherwise get when both machines send audio to each other.
Device loopback is the fallback and captures everything, including the peer audio AudioHub is playing. It is the only backend on either platform that cannot exclude itself. When it is capturing while this machine is also playing a peer's audio, the service writes one warning line to its log — once per run of the service, and nowhere in the interface. There is no on-screen warning, so if you have selected this backend by hand, that risk is yours to track.
Device loopback also reads the mix after the output volume stage, so muting this machine would silence the mirror along with the speakers. AudioHub knows this and refuses: with device loopback selected, the Mode A Mute locally option does not fire when a stream opens, and the service logs why. The macOS backends read the other side of the mixer and are unaffected.
Acoustic echo cancellation — speakers bleeding into a microphone — is out of scope.
Status: it builds and it works on a test-signing machine, and it is not signed for release. On an ordinary Windows machine it will not load.
Windows offers no user-mode audio driver framework, so a virtual audio device requires a kernel-mode driver (PortCls/KMDF). That is a platform fact, not a choice, and shipping one requires an EV certificate and attestation signing that this project does not have.
What that means in front of you:
- The 1.0.0 installer stages the driver package under Program Files. It does not install it, does not import a certificate, and does not touch test signing or your boot policy.
- Settings › Mode still shows an Install Driver button, and it will ask for administrator rights. Then, with Secure Boot on and test signing off, Windows refuses the unsigned package and the install reports failure. That refusal is deliberate fail-closed behaviour, not a bug: the installer will not force an untrusted driver, and will not weaken your machine's boot policy to make one load.
- With no driver installed, Mode B is greyed out and Mode A is the supported path. See Operating Modes for pairing Mode A with a third-party signed audio bridge.
One known limitation that is not about signing: renaming a peer cannot take effect in place on Windows. Endpoint names are cached per endpoint id by the property store, and the only mechanism that forces a refresh marks the endpoint absent and takes the user's default-device selection with it — which is precisely what in-place renaming exists to avoid. This is accepted, not pending.
If a Windows audio driver does not declare volume support, the audio engine silently inserts its own software volume stage in front of the driver. The driver then never sees full-scale samples, the peer attenuates again on its own side, and you get double attenuation that is invisible from the application's point of view — nothing errors, no device looks wrong, the audio is just quieter than it should be.
So "not implementing volume" on Windows does not mean "no volume control" — it means volume gets applied somewhere you cannot see. AudioHub's driver declares a volume node for exactly this reason. macOS does not have this problem, because the HAL plugin sits before the volume stage. What the two ends then do with that number is on Volume.
This section applies to both platforms. It describes the names AudioHub's own virtual devices carry in the system device list, in Mode B.
A device name is assembled from four parts:
| Part | Value | Notes |
|---|---|---|
| Prefix | AudioHub – |
Frozen. That is an en dash, not a hyphen. |
| Peer label | The alias you set, or the peer's own computer name | Falls back to the fingerprint if both are empty |
| Duplicate marker |
(2), (3) … |
Only when two peers share a label |
| Offline marker |
(Offline) or (离线)
|
Only when Mark names offline is on and the peer is offline |
On Windows the system then appends the adapter's own description, which is shared by every peer and cannot carry per-peer content:
AudioHub – <peer label> (AudioHub Virtual Audio)
Four things about this that are easy to get wrong:
- There is no direction word. The speaker and the microphone for one peer carry the same label, on both platforms, on purpose — the operating system's device class, list and icon already say which is which. The driver is handed a direction word and explicitly ignores it.
- It is the peer's label, not its hostname. Set an alias on the peer's detail page and the device is renamed to it.
-
Duplicates never rename the incumbent. If you pair a second machine that
calls itself the same thing, the newcomer becomes
… (2). Renaming the one an application had already selected would change a device's label for reasons the person looking at it cannot connect to anything they did. - The offline marker's language follows a machine-level setting, not the interface language of whoever is looking — it is the language the operating system sees. Both markers, and Mark names offline itself, are in Settings Reference.
The whole name is capped at 127 bytes and is truncated on a character boundary if a peer label is long enough to exceed it.
Renaming in place works on macOS and not on Windows. macOS devices are identified by a UID and the display name is decorative, so a rename keeps the same UID and no application sees a device change or loses a remembered selection. Windows caches endpoint names and cannot be refreshed without disturbing the default-device choice; see The AudioHub driver (Windows).
| macOS | Windows | |
|---|---|---|
| Share mode | Yes | Yes |
| Mode A (driverless) | Yes; system audio needs 14.2+, or 13.0+ via screen capture audio | Yes; process loopback needs build 19041 |
| Mode B (virtual devices) | Yes — user-space HAL plugin | No for end users — the kernel driver is unsigned and Windows refuses it |
| Driver protocol version | 3 | 6 |
| Per-application permissions | Microphone, Local Network, System Audio | None |
| Per-peer device rename in place | Yes | No — platform limitation |
| Channels carried over the network | 1 (mono) | 1 (mono) |
Start here
Using AudioHub
- Window and tray
- Operating Modes
- Virtual Driver
- Discovery and Pairing
- Peer detail page
- Share Protocols (Sharing tab)
- Web Access
How it behaves
Reference
- Settings Reference
- Platform Notes
- Firewall and network
- CLI Reference
- Versions and Compatibility
- Glossary
- Licenses and Attribution
Troubleshooting and removal
This wiki describes AudioHub 1.0.0.