Playing different audios simultaneously through different output devices

Hello,

I’ve been trying to play different audios at the same time but on different speakers (soundcard) using the same application, but I can’t really find a way to make it work.

After looking around a bit, I did see a similar topic here, suggesting to add multiple FMOD.System in order to be able to play sounds on different outputs simultaneously, but I’m not really sure on how to properly do it, as I’m fairly new to FMOD.

I did manage to switch outputs, but all playing sounds also switch to it.

Is there another way to play audios through multiple outputs at once? If not, how can I properly link a new FMOD.System to play event instances?

It really depends what you mean by wanting to play “different audios at the same time on different speakers”.

You can use the Channel Mix effect to force only certain channels to output audio, essentially muting one side of speakers, or you can use the ChannelControl::setMixMatrix() if you are using the Core API.

If you are referring to outputting to multiple audio devices then you will need to run multiple FMOD systems. This is basically just running every single FMOD command twice to two separate instances of the FMOD system, but it will double the resources required to do so.

Guess it wasn’t very clear, but what I really meant is having multiple outputs, each one playing a different sound.

I’ve managed to do it by modifying RuntimeManager.cs and adding 3 extra systems along with the coreSystem

        FMOD.Studio.System studioSystem, studioSystem2, studioSystem3, studioSystem4;
        FMOD.System coreSystem, system2, system3, system4;

And then creating them itself during RuntimeManager’s intialization

            result = FMOD.Studio.System.create(out studioSystem2);
            CheckInitResult(result, "Creating System Object");
            studioSystem2.getCoreSystem(out system2);
            result = FMOD.Studio.System.create(out studioSystem3);
            CheckInitResult(result, "Creating System Object");
            studioSystem3.getCoreSystem(out system3);
            result = FMOD.Studio.System.create(out studioSystem4);
            CheckInitResult(result, "Creating System Object");
            studioSystem4.getCoreSystem(out system4);

And initializing them in my own script (I’m not sure if getting the number of drivers for the other systems other than the core is a required step, but I did it out of precaution)

var resGetDrivers_core = FMODUnity.RuntimeManager.CoreSystem.getNumDrivers(out int totalDrivers);
var resGetDrivers_system2 = FMODUnity.RuntimeManager.System2.getNumDrivers(out int totalDriversSys2);
var resGetDrivers_system3 = FMODUnity.RuntimeManager.System3.getNumDrivers(out int totalDriversSys3);
var resGetDrivers_system4 = FMODUnity.RuntimeManager.System4.getNumDrivers(out int totalDriversSys4);
var resSysInit_system2 = FMODUnity.RuntimeManager.System2.init(4, FMOD.INITFLAGS.NORMAL, (System.IntPtr)0);
var resSysInit_system3 = FMODUnity.RuntimeManager.System3.init(4, FMOD.INITFLAGS.NORMAL, (System.IntPtr)0);
var resSysInit_system4 = FMODUnity.RuntimeManager.System4.init(4, FMOD.INITFLAGS.NORMAL, (System.IntPtr)0);    

I also created the sounds using System::createSound , but I’ve associate them with the CoreSystem instead of the new systems, I still can play and access them with the others:

var soundResult_test = FMODUnity.RuntimeManager.CoreSystem.createSound(Application.dataPath + "/StreamingAssets/" + "test.mp3",FMOD.MODE.DEFAULT, out var sound_test);

And then finally, playing the sound itself.

//One for each system
FMOD.ChannelGroup cgSys1;
FMOD.Channel chaSys1;

FMOD.Result playResult;

//Change "CoreSystem" to whichever system you want (System2, System3, etc.)
playResult = FMODUnity.RuntimeManager.CoreSystem.playSound(sound_test, cgSys1, false,out chaSys1);

Yes, that is the way to do it if you wish to output to multiple devices.

1 Like