Controlling inbuilt UE4 audio volume with FMOD mixer

We recommend using FMOD Studio exclusively for audio, however it is possible to play inbuilt UE4 audio side-by-side. The inbuilt UE4 audio doesn’t go through FMOD Studio mix bus heirarchy, so it isn’t able to be controlled from the mix.

There is a workaround for controlling just the volume of the inbuilt UE4 audio based on a bus volume in FMOD Studio. By applying snapshots to that bus, the following example code will take that volume and apply it into a UE4 SoundMix object.

Add the following code to a game side class (such as the custom AGameMode actor):

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=SoundMix)
	USoundMix* SoundMix;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=SoundMix)
	UFMODBus* SoundMixBus;
private:
	FMOD::Studio::Bus* RuntimeSoundMixBus;
	USoundMix* RuntimeSoundMix;

Then we have two functions, one that must be called at startup, and once per tick:

	/** Must be called at startup */
	UFUNCTION(BlueprintCallable, Category="Game")
	void InitSoundMix();

	/** Must be called per tick */
	UFUNCTION(BlueprintCallable, Category="Game")
	void UpdateSoundMix();

The Init function tries to look up the FMOD bus. It also applies a duplicate of the SoundMix that has been assigned into this actor:

void AExampleGameMode::InitSoundMix()
{
    RuntimeSoundMix = nullptr;
    RuntimeSoundMixBus = nullptr;

    if (!SoundMix || !SoundMixBus)
    {
        // Not set up 
        return;
    }

    // Find bus by ID
    FMOD::Studio::System* System = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
    FMOD::Studio::ID Guid = FMODUtils::ConvertGuid(SoundMixBus->AssetGuid);
    System->getBusByID(&Guid, &RuntimeSoundMixBus);
    if (RuntimeSoundMixBus)
    {
        RuntimeSoundMixBus->lockChannelGroup(); // Keep bus alive to query underlying channel group
    }

    // Init mix modifier
    if (GEngine && GEngine->UseSound())
    {
        if (FAudioDevice* AudioDevice = GetWorld()->GetAudioDevice())
        {
            RuntimeSoundMix = DuplicateObject(SoundMix, nullptr);
            AudioDevice->PushSoundMixModifier(RuntimeSoundMix);
        }
    }
}

The update function tries to get the audibility of the FMOD bus and applies it to each of the sound classes defined for the SoundMix:

void AExampleGameMode::UpdateSoundMix()
{
    float Volume = 1.0f;

    // Query effective volume of the bus
    if (RuntimeSoundMixBus)
    {
        FMOD::ChannelGroup* RuntimeGroup = nullptr;
        RuntimeSoundMixBus->getChannelGroup(&RuntimeGroup);
        if (RuntimeGroup)
        {
            RuntimeGroup->getAudibility(&Volume);
        }
    }
    // Assign into the UE4 sound mix object
    if (RuntimeSoundMix)
    {
        for(FSoundClassAdjuster& Adjust : RuntimeSoundMix->SoundClassEffects)
        {
            Adjust.VolumeAdjuster = Volume;
        }
    }
}

To use this code, the actor will need to be set up with an appropriate UE4 SoundMix and a FMOD Bus assigned into the blueprint-accessable fields.