Last active
June 6, 2023 21:02
-
-
Save larussverris/5387819a3a7337937084730a86cee073 to your computer and use it in GitHub Desktop.
Creating an aggregate device using Core Audio in Objective-C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <CoreAudio/CoreAudio.h> | |
#import "utilities.h" | |
/* | |
This example demonstrates how to create an aggregate device using Core Audio in Objective-C. | |
It creates an aggregate device with two sub-devices, which are the default input and output devices. | |
*/ | |
int main(int argc, const char * argv[]) { | |
OSStatus status = noErr; | |
// Get the default input and output device IDs | |
AudioDeviceID defaultInputDeviceID = getDefaultInputDeviceID(); | |
AudioDeviceID defaultOutputDeviceID = getDefaultOutputDeviceID(); | |
// Get the UIDs of the default input and output devices | |
NSString* defaultInputDeviceUID = getDeviceUID(defaultInputDeviceID); | |
NSString* defaultOutputDeviceUID = getDeviceUID(defaultOutputDeviceID); | |
// Create a dictionary to hold the aggregate device description | |
NSMutableDictionary *description = [NSMutableDictionary dictionary]; | |
// Set the name of the new aggregate device | |
description[@(kAudioAggregateDeviceNameKey)] = @"YourNameHere"; | |
// Set the UID of the aggregate device | |
description[@(kAudioAggregateDeviceUIDKey)] = @"YourUniqueId"; | |
// Determines if the device should be visible in the "Audio MIDI Setup" | |
description[@(kAudioAggregateDeviceIsPrivateKey)] = @(NO); | |
// Array to hold the sub devices | |
NSMutableArray *subDevices = [NSMutableArray array]; | |
// Input device | |
NSDictionary *inputSubDevice = @{ | |
@(kAudioSubDeviceUIDKey) : defaultInputDeviceUID, | |
@(kAudioSubDeviceDriftCompensationKey) : @(YES), | |
}; | |
[subDevices addObject:inputSubDevice]; | |
// Output device | |
NSDictionary *outputSubDevice = @{ | |
@(kAudioSubDeviceUIDKey) : defaultOutputDeviceUID, | |
@(kAudioSubDeviceDriftCompensationKey) : @(YES), | |
}; | |
[subDevices addObject:outputSubDevice]; | |
// Add the devices to the description | |
description[@(kAudioAggregateDeviceSubDeviceListKey)] = subDevices; | |
// This will be the ID of the newly created aggregate device | |
AudioDeviceID aggregateDeviceID = 0; | |
// Create the aggregate device | |
status = AudioHardwareCreateAggregateDevice((__bridge CFDictionaryRef)description, &aggregateDeviceID); | |
if (status != noErr) { | |
NSLog(@"An error occurred while creating the aggregate device, code: %d", status); | |
return -1; | |
} | |
NSLog(@"A new aggregate device has been created with ID: %d", aggregateDeviceID); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef helpers_h | |
#define helpers_h | |
// Get the default input device ID | |
AudioDeviceID getDefaultInputDeviceID(void) { | |
// Initialize the device ID variable | |
AudioDeviceID deviceID = kAudioDeviceUnknown; | |
UInt32 propertySize = sizeof(deviceID); | |
// Set the property address for retrieving the default input device ID | |
AudioObjectPropertyAddress propertyAddress = { | |
kAudioHardwarePropertyDefaultInputDevice, | |
kAudioObjectPropertyScopeGlobal, | |
kAudioObjectPropertyElementMain | |
}; | |
// Retrieve the default input device ID | |
OSStatus status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &deviceID); | |
if (status != noErr) { | |
// Error handling | |
// Handle the failure to retrieve the default input device ID | |
} | |
return deviceID; | |
} | |
// Get the default output device ID | |
AudioDeviceID getDefaultOutputDeviceID(void) { | |
// Initialize the device ID variable | |
AudioDeviceID deviceID = kAudioDeviceUnknown; | |
UInt32 propertySize = sizeof(deviceID); | |
// Set the property address for retrieving the default output device ID | |
AudioObjectPropertyAddress propertyAddress = { | |
kAudioHardwarePropertyDefaultOutputDevice, | |
kAudioObjectPropertyScopeGlobal, | |
kAudioObjectPropertyElementMain | |
}; | |
// Retrieve the default output device ID | |
OSStatus status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propertySize, &deviceID); | |
if (status != noErr) { | |
// Error handling | |
// Handle the failure to retrieve the default output device ID | |
} | |
return deviceID; | |
} | |
// Get the UID of an audio device | |
NSString *getDeviceUID(AudioDeviceID deviceID) { | |
// Initialize the status variable | |
OSStatus status = noErr; | |
// Initialize the UID and its size variables | |
CFStringRef uid = NULL; | |
UInt32 uidSize = sizeof(uid); | |
// Set the property address for retrieving the device UID | |
AudioObjectPropertyAddress propertyAddress = { | |
kAudioDevicePropertyDeviceUID, | |
kAudioObjectPropertyScopeGlobal, | |
kAudioObjectPropertyElementMain | |
}; | |
// Retrieve the device UID | |
status = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, NULL, &uidSize, &uid); | |
if (status != noErr) { | |
return nil; | |
} | |
return (__bridge NSString *)uid; | |
} | |
#endif /* helpers_h */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment