Audio Midi Setup allows a single sound source to be output from multiple devices, but is there a way to do this in CoreAudio?
Could this be done by attaching the same playerNode to two AVAudioEngine? I thought about doing this, but it threw a stack trace and gave me an error.
import Cocoa
import CoreAudio
@main
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Get the default output device
var defaultOutputDeviceID = AudioDeviceID(0)
var defaultOutputDeviceIDSize = UInt32(MemoryLayout<AudioDeviceID>.size)
var property: AudioObjectPropertyAddress = AudioObjectPropertyAddress(mSelector:kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioDevicePropertyScopeOutput, mElement: kAudioObjectPropertyElementMain)
var getDefaultOutputDeviceIDStatus = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &property, 0, nil, &defaultOutputDeviceIDSize, &defaultOutputDeviceID)
// Get the number of output devices
var outputDeviceCount = UInt32(0)
var outputDeviceCountSize = UInt32(MemoryLayout<UInt32>.size)
property.mSelector = kAudioHardwarePropertyDevices
var getOutputDeviceCountStatus = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &property, 0, nil, &outputDeviceCountSize, &outputDeviceCount)
// Get the IDs of all output devices
var outputDeviceIDs = [AudioDeviceID](repeating: 0, count: Int(outputDeviceCount))
var outputDeviceIDsSize = UInt32(MemoryLayout<AudioDeviceID>.size * Int(outputDeviceCount))
property.mSelector = kAudioHardwarePropertyDevices
var getOutputDeviceIDsStatus = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &property, 0, nil, &outputDeviceIDsSize, &outputDeviceIDs)
// Set the output device IDs to the first two devices
var outputDeviceIDsToSet = [outputDeviceIDs[0], outputDeviceIDs[1]]
var outputDeviceIDsToSetSize = UInt32(MemoryLayout<AudioDeviceID>.size * outputDeviceIDsToSet.count)
property.mSelector = kAudioAggregateDevicePropertyComposition
var setOutputDeviceIDsStatus = AudioObjectSetPropertyData(defaultOutputDeviceID, &property, 0, nil, outputDeviceIDsToSetSize, &outputDeviceIDsToSet) }
}
}
}
In preparation, struct,
and a
Dictionary<String, DeviceID>consisting of them.and code is