I'm having similar issue, solved it by creating an aggregate device using the following code,
AudioDevice is a custom struct.
Code Block | func createAggregateDevice(with devices: [AudioDevice]) { |
| guard let firstDevice = devices.first else { |
| throw MacOSAudioDevicesManagerError.unableToCreateAggregateDevice |
| } |
| |
| let subDevicesList: [[String: Any]] = devices.map { device in |
| [kAudioSubDeviceUIDKey: device.uid as CFString] |
| } |
| |
| let desc: [String: Any] = [ |
| kAudioAggregateDeviceNameKey: "YourDeviceName", |
| kAudioAggregateDeviceUIDKey: "YourDeviceUID", |
| kAudioAggregateDeviceSubDeviceListKey: subDevicesList, |
| kAudioAggregateDeviceMasterSubDeviceKey: firstDevice.uid, |
| kAudioAggregateDeviceClockDeviceKey: firstDevice.uid |
| ] |
|
| var aggregateDeviceId: AudioDeviceID = 0 |
| let status = AudioHardwareCreateAggregateDevice(desc as CFDictionary, &aggregateDeviceId) |
| guard status == 0 else { |
| throw MacOSAudioDevicesManagerError.unableToCreateAggregateDevice |
| } |
|
| // aggregateDeviceId will be the id of new aggregate device |
| } |
Then I'm trying to set default input device to this new device, and use AVAudioEngine to stream the microphone input.
Code Block | var deviceId = device.id |
| var address = AudioObjectPropertyAddress( |
| mSelector: kAudioHardwarePropertyDefaultInputDevice, |
| mScope: kAudioObjectPropertyScopeGlobal, |
| mElement: kAudioObjectPropertyElementMaster) |
| let statusCode = AudioObjectSetPropertyData( |
| AudioObjectID(kAudioObjectSystemObject), |
| &address, |
| 0, |
| nil, |
| UInt32(MemoryLayout<AudioDeviceID>.size), |
| &deviceId |
| ) |