Selecting specific device/channel in sound interface

I have an application written about 10 years ago using FMOD. The original program was written for a specific MOTU sound interface device and its ASIO drivers, and the outputs appeared on the optical output channels (ADAT A, channels 1-6). I think it was almost pure accident that the outputs appeared in the correct location (for us), in that I don’t see any logic for finding the ADAT A channels and using those for the output.

Now I need to use a different MOTU device and without making any software changes, my outputs (six of them) show up on “Main Out 1-2”, “Analog 1-2”, and “Analog 3-4”, but I need to get them on “ADAT A 1-2”, “ADAT A 3-4”, and “ADAT A 5-6”.

Can anyone give me some hints?

I can “see” the channels I want (from within the debugger) when I make a call to:

result = system->getAdvancedSettings(fmodSettings);

After that call, I can see the fmodSettings structure and from there can get into the ASIOChannelList element. That’s where I see all the possible output devices of the MOTU, like Main Out 1-2, S/PDIF 1-2, ADAT Optical A 1-2, etc.

I found some hints about using the ASIOSpeakerList element of fmodSettings, but the only example I’ve see sets that speaker list to fmod constants like FMOD_SPEAKER_MAX, and it seems like the speaker list values want to be between 0 and 15, which wouldn’t work with hardware that has upwards of 30 possible channels.

And just to be clear, all output channels are listed twice, presumably because they are stereo pairs. So above where I mentioned “Main Out 1-2”, that actually appears twice.

I’ve tried creating a ASIOSpeakerList filled in with 6 constants (since I’m using 5.1) and calling setAdvancedSettings(), but the code craps out once it goes into its main loop. Sort of like this:

        FMOD_SPEAKER rcwSpeakerList [] = { (FMOD_SPEAKER)14, (FMOD_SPEAKER)15, (FMOD_SPEAKER)16, (FMOD_SPEAKER)17, (FMOD_SPEAKER)18, (FMOD_SPEAKER)19 }; 

where the constants (14, 15, …) are the index of the desired ADAT lines found with the debugger.

I’m sure the “right” answer is to update to the latest version of fmod, but that introduces all sorts of other potential issues. I’m hoping to make a simple change to keep this old code running on newer hardware. BTW, the fmod.h files lists the version as an int value of 0x00043602.

The speaker list should not be force cast to asio speaker numbers. the speaker list is referring to fmod’s standard internal speaker layout (ie if you are using 5.1 in setSpeakerSettings)

Here’s a studio example that might be relevant

    /*
        First call get, to get the ASIO channel list
    */
    advancedsettings.cbSize = sizeof(advancedsettings);
    result = system->getAdvancedSettings(&advancedsettings);
    ERRCHECK(result);
    
    /*
        Now call set, to set our speaker mapping.  
    */
    FMOD_SPEAKER speakerlist[1024] = { };
    for (count = 0; count < sizeof(speakerlist) / sizeof(speakerlist[0]); count++) speakerlist[count] = (FMOD_SPEAKER)-1;

    /* 
        Set up the 'bed' which is the default speaker layout that FMOD mixes to, according to the set speaker mode (ie 5.1). 
        You can set this 'bed' to any ASIO channels you like, and more than once!
    */
    speakerlist[0] = FMOD_SPEAKER_FRONT_LEFT;
    speakerlist[1] = FMOD_SPEAKER_FRONT_RIGHT;
    speakerlist[2] = FMOD_SPEAKER_FRONT_CENTER;
    speakerlist[3] = FMOD_SPEAKER_LOW_FREQUENCY;
    speakerlist[4] = FMOD_SPEAKER_SURROUND_LEFT;
    speakerlist[5] = FMOD_SPEAKER_SURROUND_RIGHT;

    /*
        This is an example of also using ASIO channels 10 to 15 to have another copy of the FMOD mix audible.
    */
    if (advancedsettings.ASIONumChannels > 15)  /* First check if this device actually has 16 channels or not */
    {
        speakerlist[10] = FMOD_SPEAKER_FRONT_LEFT;
        speakerlist[11] = FMOD_SPEAKER_FRONT_RIGHT;
        speakerlist[12] = FMOD_SPEAKER_FRONT_CENTER;
        speakerlist[13] = FMOD_SPEAKER_LOW_FREQUENCY;
        speakerlist[14] = FMOD_SPEAKER_SURROUND_LEFT;
        speakerlist[15] = FMOD_SPEAKER_SURROUND_RIGHT;
    }

    advancedsettings.ASIOSpeakerList = speakerlist;
    advancedsettings.ASIONumSpeakers = advancedsettings.ASIONumChannels;    // 1:1 fmod speakers to asio channels
    result = system->setAdvancedSettings(&advancedsettings);
    ERRCHECK(result);

The second part might be more relevant to you, where it sets the fmod speaker list to asio speakers 10 to 15

Thank you very much for the hints @brett

I was able to implement this and see I was having some effect. However, I suspect the version of fmod we’re using is too old/buggy. Regardless of how I assigned the speakerlist, I could not get outputs on the ADAT channels. In fact, analog signals always seemed to just start at device 0 (Main Out 1-2), unless the Motu was configed to use Main Out for something else, and in that case analog signals would start at device 1 (Analog 1-2).

We’ll have to evaluate if we want to update the fmod lib, but that’s probably not as high on the priority queue. That will be a separate conversation.

But again, thanks for the hints. I was thinking of speakerlist the other way around!

BTW, I’m sending in a rfq through sales.