MacOS Raw SpeakerMode Device?

How do I configure an output device in RAW speaker mode? I have output devices which have 24+ channels, but seem to be limited to the speaker configuration definitions in the “Audio MIDI Setup” tool (“Configure Speakers” - Stereo, 5.1, 7.1, etc.) How do I connect directly to the raw output channels?

The docs for fmod_speakermode_raw contain some relevant information.

This mode is for output devices that are not specifically mono/stereo/quad/surround/5.1 or 7.1, but are multichannel.

  • Use System::setSoftwareFormat to specify the number of speakers you want to address, otherwise it will default to 2 (stereo).
  • Sound channels map to speakers sequentially, so a mono sound maps to output speaker 0, stereo sound maps to output speaker 0 & 1.
  • The user assumes knowledge of the speaker order. FMOD_SPEAKER enumerations may not apply, so raw channel indices should be used.
  • Multichannel sounds map input channels to output channels 1:1.
  • Speaker levels must be manually set with Channel::setMixMatrix.
  • Channel::setPan and Channel::setMixLevelsOutput do not work.

Thanks, that clarifies it a bit. My follow up question is: how do I remove the mono/stereo/quad/surround configuration to make it a “multichannel” device? This is probably a MacOS issue and not fmod, but it seems like fmod adheres to whatever speaker configuration is set. My 24 channel output is reported by fmod as mono/stereo/quad/surround, rather than the full 24 channels.

To clarify: I have called System::setSoftwareFormat(FMOD_SPEAKERMODE_RAW), but a follow up System::getSoftwareFormat returns a speakermode that is consistent with what has been configured in the Audio MIDI Setup tool. Is there a way to override this and get access to all of the outputs a device has to offer?

Are you checking the FMOD_RESULT of the setSoftwareFormat? It will tell you if it failed and why.
make sure it is being called before System::Init.

The call order was indeed the issue for setSoftwareFormat, but the overall behavior hasn’t improved. I am still only seeing output to the number of configured speakers in Audio MIDI Setup. What is more interesting is that the actual speaker numbers don’t seem to matter – the output always goes to the first X outputs, even if I remap one of the speaker numbers to some higher output.

For reference, here is the script I am testing (using pyfmodex for prototyping):

import pyfmodex as fmod

s = fmod.System()
format = s.software_format
format.raw_speakers = 24
format.speaker_mode = 1
s.software_format = format
s.driver = 1

channel_group = s.create_channel_group("test")
matrix = [1] * (24 * 24)
channel_group.set_mix_matrix(matrix, 24, 24)

sound = s.create_sound("./media/jaguar.wav")
sound.mode = fmod.flags.MODE.LOOP_NORMAL

And the net result is that the audio is output to the first X outputs. If I configured Stereo speakers, then the first two outputs are active. If I configure 5.1, then the first 6 outputs are active. Based on the mix_matrix, I would expect all 24 channels to be active.

At the channel level a mono sound is automatically panned to front left/right by default, so the other 22 channels are most likely going to be silence. You could try a 1x24 matrix on the channel, instead of the channelgroup.

That doesn’t seem to have any effect. But the channelgroup matrix is definitely working, to a degree. If I only set one output in the mix matrix, then only one channel will be active. Likewise, if I set three outputs in the mix matrix, then three outputs channels will be active.

The problem is that the number of output channels is always constrained by the Audio MIDI Setup speaker count. I have validated this by enabling all 24 outputs in the mix matrix and then changing the surround sound configuration and then restarting the script. Despite the same script and all 24 channels enabled, only the number of speakers enabled are active.

You seem to be saying you’re not setting up your mac os speaker configuration properly, and that is the problem?

What is wrong with setting the audio midi setup speaker count to 24, if thats what coreaudio wants? You can’t output to speakers in the OS that are disabled.

Audio MIDI Setup only supports common speaker arrangements; I can’t specify an arbitrary number of speakers. However, high-end DAW applications (Pro Tools, Logic, etc.) are able to drive 24 outputs, which leads me to think that there is some way for software to bypass the speaker configuration. I assumed that fmod supported this based on the language around the System::setSoftwareFormat function, such as “numrawspeakers”.

Hi Matt,
We do have a ticket open about this actually, apparently yes, some DAWs on mac can basically overwrite the settings in the mac setup screen.
Can’t promise an immediate fix but we’re aware of that and will patch it for a future version.

Thanks for the clarification. I’m glad to hear it’s possible and on the roadmap.

I can add to this. In FMOD Ex, the “setHardwareChannels” call effecively overrode the Audio Midi setup (like other DAW applications) , but, in FMod 5 this call is no longer available. Older versions of my app work on multichannels as expected, but newer versions using FMOD 5 cannot address more channels than setup in Audio MIDI settings.

I have begun to try setting this myself by getting the Audio Unit handle from FMod and borrowing code from the Chromium project to set properties directly, but no luck yet.

If I knew how this worked before in setHardwareChannels, I could probably solve it!

setHardwareChannels was meant for platforms that had hardware voice support (ie ‘channels’. As far as I remember this was Xbox and Playstation type platforms.
There is no evidence that the mac platform used setHardwareChannels at all in FMOD Ex, it is just not referenced.

Maybe that call wasn’t the difference it seems. I haven’t been able to discover an init sequence that makes the current version behave the same as FMod Ex though. My testers report they cannot address more than 2 channels on some interfaces, but on others I’ve addressed 4 successfully. They are running the old and new side by side with the same audio midi setup to test, one after the other. Strange. I never had any prior code to manipulate the audio unit directly.

i will double check as fmod ex probably went through a few iterations with different output modes leading up to coreaudio.

Here is what I am trying:

    SoundSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_RAW, ap->settings->numMultichannels);

    SoundSystem->setDriver(ap->settings->selectedAudioDeviceNum );

    result = SoundSystem->init(60, FMOD_INIT_NORMAL, 0);

    static const AudioChannelLabel kCoreAudioChannelMapping[] = {
    AudioUnit audioUnit;
    SoundSystem->getOutputHandle((void **)&audioUnit);
    const size_t layout_size =
    offsetof(AudioChannelLayout, mChannelDescriptions[ap->settings->numMultichannels]);
    std::unique_ptr<uint8_t[]> layout_storage(new uint8_t[layout_size]);
    memset(layout_storage.get(), 0, layout_size);
    AudioChannelLayout* coreaudio_layout =
    coreaudio_layout->mNumberChannelDescriptions = numMultichannels;
    coreaudio_layout->mChannelLayoutTag =
    AudioChannelDescription* descriptions =
    for (int ch = 0; ch < numMultichannels; ++ch)
        descriptions[ch].mChannelLabel = ch > 16
        ? kAudioChannelLabel_Unknown
        : kCoreAudioChannelMapping[ch];
        descriptions[ch].mChannelFlags = kAudioChannelFlags_AllOff;
    OSStatus ret = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input,
                         0, coreaudio_layout, layout_size);

and I use SetMixMatrix to assign the levels, of course