Skip to content

Default --outputs to a stereo pair instead of every output channel - #2

Merged
ledogar merged 1 commit into
masterfrom
cli-output-channel-default
Jul 29, 2026
Merged

Default --outputs to a stereo pair instead of every output channel#2
ledogar merged 1 commit into
masterfrom
cli-output-channel-default

Conversation

@ledogar

@ledogar ledogar commented Jul 29, 2026

Copy link
Copy Markdown
Owner

The previous default selected every output channel of the device. On an Aggregate Device built around a loopback that is actively harmful: on a BlackHole + speakers aggregate, channels 0–1 are BlackHole's outputs, and BlackHole's outputs feed its inputs — so the circuit's output was routed back into its own input, producing runaway feedback through whatever distortion was being simulated.

Now defaults to the first two channels, and prints the full channel list (marking which are selected) whenever a device has more outputs than were taken.

What this does not do

It does not work out which pair is audible. On the aggregate above the first pair is still the loopback, not the speakers, so --outputs 2,3 is still required there. What changes is the failure mode: a howling feedback loop becomes silence plus a printed list showing exactly what to pass.

Note: this device has 4 output channels and 2 were selected. On an Aggregate Device
the first channels are not necessarily the ones you hear - use --outputs to pick. Available:
    [0] Out 1  (selected)
    [1] Out 2  (selected)
    [2] Out 3: 1
    [3] Out 4: 2

Devices with two output channels — speakers, USB interfaces, BlackHole standalone — behave exactly as before, with no warning.

Follow-up worth considering

Automatic routing would mean reading kAudioAggregateDevicePropertyFullSubDeviceList, mapping channel ranges to sub-devices, and preferring outputs on a sub-device that contributes no input — which picks the speakers and skips the loopback. Roughly 100 lines of P/Invoke plus a heuristic that could guess wrong on unusual hardware, so it's deliberately not in this change. Worth doing if aggregates become a standing setup.

Testing

Verified against the 4-channel aggregate (warning shown, 2 of 4 selected) and against a plain stereo device (no warning, unchanged behaviour). The live playback session that confirmed end-to-end audio — Apple Loops guitar through a Tube Screamer sim, out to speakers — ran on this build.

🤖 Generated with Claude Code

Writing to every output channel is actively harmful on an Aggregate Device
built around a loopback. On a BlackHole + speakers aggregate, channels 0-1
are BlackHole's outputs, which feed BlackHole's input - so the previous
default routed the circuit's output back into its own input and produced
runaway feedback through whatever distortion was being simulated.

Default to the first two channels, and when a device has more outputs than
were selected, print the full channel list marking which are in use.

This is a defensive default, not automatic routing: it does NOT work out
which pair is audible. On an aggregate the first pair is often the loopback
rather than the speakers, so --outputs is still required there - the change
turns a howling feedback loop into silence plus a printed list showing what
to pass. Devices with two output channels are unaffected.

Doing this properly would mean reading
kAudioAggregateDevicePropertyFullSubDeviceList, mapping channel ranges to
sub-devices, and preferring outputs on a sub-device that contributes no
input. That is worth doing if aggregates become a common setup, but it is a
heuristic that can guess wrong on unusual hardware, so it is deliberately
left out of this change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ledogar
ledogar merged commit 4383d48 into master Jul 29, 2026
4 checks passed
@ledogar
ledogar deleted the cli-output-channel-default branch July 29, 2026 03:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants