How Vorssaint Implements Per-Process Audio Routing on macOS

Vorssaint creates per-process audio routing by using CoreAudio's AudioHardwareCreateProcessTap API to intercept audio streams from individual applications, then processes them through AppVolumeMixer and MixerRoutingSupport to determine output devices, volume levels, and exclusions for specific bundles.

Vorssaint-utils is an open-source macOS utility that provides granular control over system audio. The repository implements sophisticated per-process audio routing that allows users to capture, manipulate, and redirect sound from individual applications independently of the system mixer.

Core Architecture and Process Taps

The foundation of Vorssaint's per-process audio routing relies on CoreAudio process taps. When a user enables system audio capture, the RecorderSystemAudioTap component creates a dedicated tap for the target process using the AudioHardwareCreateProcessTap function.

This tap returns an AudioObjectID that uniquely identifies the intercepted stream. The system then maps this ID back to the originating application's bundle identifier and PID, allowing the utility to distinguish between audio sources from different processes.

The workflow follows this sequence:

  1. RecorderSystemAudioTap requests a tap for the target process
  2. AudioHardwareCreateProcessTap creates the interception point
  3. Audio frames flow to AppVolumeMixer for processing
  4. MixerRoutingSupport determines the final output destination

Routing Logic with MixerRoutingSupport

The MixerRoutingSupport class encapsulates all routing heuristics. It evaluates three critical questions for every audio stream: Is the app eligible for routing? Which output device should receive the audio? What volume level should be applied?

Excluding Special-Case Applications

Certain professional audio applications manage their own internal routing and must bypass the process tap to prevent interference. The bypassesProcessTap(bundleIdentifier:name:) method maintains a exclusion list:

  • us.zoom.xos
  • com.apple.logic10
  • com.ableton.live
  • com.steinberg.cubase13
  • com.presonus.studioone6

When an application's bundle identifier matches this list, Vorssaint excludes it from process-tap routing and allows it to communicate directly with the system audio hardware.

Device Selection and Persistence

The nextSelectedOutputDeviceUID(currentUID:) method determines the appropriate output destination. It prefers user-selected devices but falls back to the system default when the preferred device becomes unavailable. When macOS wakes from sleep or the audio device configuration changes, MixerRoutingSupport recomputes the appropriate output UID and restores previously saved volume and gain settings.

The Audio Pipeline Implementation

The AppVolumeMixer serves as the core mixing engine. It receives raw audio buffers from the process tap, applies per-application volume adjustments using volumeFraction(fromPercentageText:), and renders the final output to the selected hardware device.

The UI layer in MixerSection.swift exposes controls for per-app volume sliders and output device selection, reflecting the underlying routing decisions in real time.

Code Implementation Examples

Creating a process tap requires proper error handling and lifecycle management. The implementation in RecorderSystemAudioTap.swift follows this pattern:

var tapID: AudioObjectID = 0
let description = AudioObjectPropertyAddress(
    mSelector: kAudioHardwarePropertyProcessTap,
    mScope: kAudioObjectPropertyScopeGlobal,
    mElement: kAudioObjectPropertyElementMaster)

// Request a tap that intercepts the target process audio
guard AudioHardwareCreateProcessTap(description, &tapID) == noErr,
      tapID != 0 else {
    // Fallback to system-default audio path on failure
    return
}

The routing exclusion logic implemented in MixerRoutingSupport validates application eligibility:

static func bypassesProcessTap(bundleIdentifier: String?, name: String) -> Bool {
    let excluded = [
        "us.zoom.xos", 
        "com.apple.logic10", 
        "com.ableton.live",
        "com.steinberg.cubase13", 
        "com.presonus.studioone6"
    ]
    return bundleIdentifier.map { excluded.contains($0) } ?? false
}

Applying per-process volume adjustments within the audio pipeline:

let fraction = MixerRoutingSupport.volumeFraction(fromPercentageText: "75%")
let scaledGain = fraction * maximumGain
audioBuffer.applyGain(scaledGain)

Device selection logic ensures continuity across hardware changes:

static func nextSelectedOutputDeviceUID(currentUID: String?) -> String {
    // Prefer user-chosen device; fall back to system default if unavailable
    return currentUID ?? systemDefaultSelectionID
}

Key Source Files

Summary

  • Vorssaint implements per-process audio routing using CoreAudio's AudioHardwareCreateProcessTap to intercept streams from individual applications.
  • The MixerRoutingSupport class manages routing decisions, excluding professional audio apps like Logic Pro and Ableton Live from tap interception.
  • AppVolumeMixer processes intercepted audio frames, applying per-application volume scaling before output to the selected device.
  • Routing decisions persist across system sleep/wake cycles and device changes through UID-based device tracking.
  • The architecture allows fine-grained control over application audio without modifying the system mixer or affecting other processes.

Frequently Asked Questions

How does Vorssaint handle applications that manage their own audio routing?

Vorssaint explicitly excludes applications known to implement internal audio routing through the MixerRoutingSupport.bypassesProcessTap() method. When an app's bundle identifier matches the exclusion list—including Zoom, Logic Pro, Ableton Live, Cubase, and Studio One—the utility bypasses the process tap for that application, allowing it to communicate directly with CoreAudio without interference.

What happens when the selected audio output device becomes unavailable?

The MixerRoutingSupport.nextSelectedOutputDeviceUID(currentUID:) method handles device changes by checking the current user preference against available hardware. If the preferred device disconnects or becomes unavailable, the system automatically falls back to the systemDefaultSelectionID, ensuring audio continues playing through the default output rather than failing silently.

Does creating per-process taps impact system performance?

According to the Vorssaint-utils source code, process taps operate at the CoreAudio driver level with minimal overhead. The AppVolumeMixer processes audio buffers in real-time using efficient gain scaling algorithms. However, users running multiple simultaneous process taps alongside professional audio software may experience increased CPU utilization, which is why certain DAWs and video conferencing tools are excluded from the routing system.

Can users adjust volume for applications independently of the system volume?

Yes. The MixerRoutingSupport class converts user-friendly percentage strings (e.g., "75%") into gain fractions via volumeFraction(fromPercentageText:). The AppVolumeMixer then applies these scaled values to individual process streams before they reach the hardware output, allowing each application to maintain independent volume levels regardless of the macOS system volume setting.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →