Stuttering In Unity WebGL

We’re building a WebGL project using Unity, but during some operations that perform some switching of interfaces, the music playing makes a noticeable lagging sound. I noticed that the documentation mentions something about this and gives some sample code.

CPU Overhead
By default FMOD mixes at 48000hz. If the browser is not running at that rate, it will introduce a resampler to convert the rate, which consumes CPU time and adds a DSP block worth of latency.
This can be solved by querying the hardware’s rate before System::init, and calling System::setSoftwareFormat to the same rate as the output. Here is an example (from the PlaySound example)

var outval = {};
result = gSystem.getDriverInfo(0, null, null, outval, null, null);
CHECK_RESULT(result);
result = gSystem.setSoftwareFormat(outval.val, FMOD.SPEAKERMODE_DEFAULT, 0)
CHECK_RESULT(result);

Audio Stability (Stuttering)
Some devices cannot handle the default buffer size of 4 blocks of 1024 samples (4096 samples) without stuttering, so to avoid this set the buffer size in your application to 2 blocks of 2048.
Here is an example

result = gSystem.setDSPBufferSize(2048, 2); 
CHECK_RESULT(result);

But how do I use this code? They look like JS code rather than C# code.

If I want to do these operations in C#, where should I perform them?

For example, according to the description I should execute this code before the System.init method call, but I have not searched for a reference to the System.init method in the entire C# project for Unity.

The equivalent calls to a Core API system in C# are:

FMOD.RESULT result;
result = system.getDriverInfo(0, out System.Guid guid, out int systemrate, out FMOD.SPEAKERMODE speakermode, out int speakermodechannels);
result = system.setSoftwareFormat(systemrate, speakermode, 0);
result = system.setDSPBufferSize(2048, 2);

If you were accessing the core system from RuntimeManager, it would be the following instead:

FMOD.RESULT result;
result = FMODUnity.RuntimeManager.CoreSystem.getDriverInfo(0, out System.Guid guid, out int systemrate, out FMOD.SPEAKERMODE speakermode, out int speakermodechannels);
result = FMODUnity.RuntimeManager.CoreSystem.setSoftwareFormat(systemrate, speakermode, 0);
result = FMODUnity.RuntimeManager.CoreSystem.setDSPBufferSize(2048, 2);

You may not need all of the out arguments, so remove as needed.

These functions all need to be called before system initialization; the recommended way to do so with the Unity integration would be to use a custom handler that receives a callback before system initialization occurs. For more information on how to do this, see the Callback Handler scripting example in our Unity documentation.

1 Like