Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set speaker configuration programatically using Core Audio API on Mac OS X?

I have a 7.1 channel audio output device and a custom kext to drive that. My custom application needs to send 7.1 rear channel audio data to the device but the device receives only 2 channel audio data. I checked "Configure Speaker" option in "Audio MIDI setup" application and it's set to stereo. When I set it to "7.1 Rear Surround" everything works fine. In my final product, I don't want the user to have to do all of this manually. So, the question is - Is there any Core Audio API or any other means of doing this programatically?

enter image description here

like image 650
Raunak Avatar asked May 15 '13 05:05

Raunak


People also ask

How do I enable core audio on my Mac?

Locate the search bar in the top right and type in “coreaudiod,” then click on it with your mouse or trackpad. As soon as it's highlighted, click on the “X” icon at the top left of the Activity Monitor window, and it will automatically restart your Mac's Core Audio process.

How do you change the default speaker on a Mac?

On your Mac, choose Apple menu > System Preferences, click Sound , then click Output. Select the device you want to use in the list of sound output devices. ), USB speakers, and AirPlay devices.

How do you add a device to sound input on a Mac?

From the Finder, choose Go > Utilities. Open the Audio MIDI Setup application. Click the Add (+) button on the bottom-left corner in the Audio Devices window and chose Create Aggregate Device. A new Aggregate Device appears in the list on the left side of the window.


1 Answers

Ok, after playing around with some Core Audio APIs, finally I could get this done.

  1. Get the AudioDeviceID:

    AudioDeviceID audioDevice = getMyAwesomeDeviceID();
    
  2. Create an AudioObjectPropertyAddress:

    AudioObjectPropertyAddress propertyAddress;
    propertyAddress.mSelector = kAudioDevicePropertyPreferredChannelLayout;
    propertyAddress.mScope = kAudioDevicePropertyScopeOutput;
    propertyAddress.mElement = kAudioObjectPropertyElementMaster;
    
  3. Query if the audio object has this property:

    AudioObjectHasProperty(audioDevice, &propertyAddress)
    
  4. Get the data size of this property and create AudioChannelLayout:

    UInt32 propSize(0);
    AudioObjectGetPropertyDataSize(audioDevice, &propertyAddress, 0, NULL, &propSize);
    AudioChannelLayout* layout = (AudioChannelLayout*)malloc(propSize);
    
  5. Configure your AudioChannelLayout structure (eg: stereo layout):

    AudioChannelLabel labels[2] = {kAudioChannelLabel_Right, kAudioChannelLabel_Left};
    
    layout->mNumberChannelDescriptions = 2;
    for (UInt32 i = 2; i < layout->mNumberChannelDescriptions; i++) {
        layout->mChannelDescriptions[i].mChannelLabel = labels[i];
        layout->mChannelDescriptions[i].mChannelFlags = kAudioChannelFlags_AllOff;
    }
    
  6. Set the AudioObject property data:

    AudioObjectSetPropertyData(audioDevice, &propertyAddress, 0, NULL, propSize, layout);
    
like image 198
Raunak Avatar answered Oct 05 '22 11:10

Raunak