This is basically @Andrei B.'s answer, with the linked [now dead] blog post code
updated to use AudioHardwareCreateAggregateDevice()
and the kAudioAggregateDeviceIsStackedKey
symbol (and it's in swift, sorry, I didn't read the question):
func createMultiOutputAudioDevice(masterDeviceUID: CFString, secondDeviceUID: CFString, multiOutUID: String) -> (OSStatus, AudioDeviceID) {
let desc: [String : Any] = [
kAudioAggregateDeviceNameKey: "My Multi-Output Device",
kAudioAggregateDeviceUIDKey: multiOutUID,
kAudioAggregateDeviceSubDeviceListKey: [[kAudioSubDeviceUIDKey: masterDeviceUID], [kAudioSubDeviceUIDKey: secondDeviceUID]],
kAudioAggregateDeviceMasterSubDeviceKey: masterDeviceUID,
kAudioAggregateDeviceIsStackedKey: 1,
]
var aggregateDevice: AudioDeviceID = 0
return (AudioHardwareCreateAggregateDevice(desc as CFDictionary, &aggregateDevice), aggregateDevice)
}
Too bad multi output devices don't have volume control, this makes them not so useful when they become the default output device.