Dissonance Bugs

Sure. The bug itself seems to appear after some time - but seems to be variable. I wonder if it has something to do with a player getting out of range then in range again? (As I believe the voice is virtualised when out of range…)

Simply:

  1. Load into scene (in my project, go to the WorldMap and use Unity’s Multiplayer Play Mode to create an additional instance)
  2. Then, wait for some time (or potentially go out of range and back in)
  3. Bug should appear within a couple minutes.
  4. Repeat if bug does not appear; it doesn’t always seem to happen.
1 Like

Thank you, I was able to get it running. I spent some time running in and out of range, seeing the DSP becoming virtual:


However, I was not able to reproduce the issue.

We have a second option to set the priority directly on the channel the voice is played on: FMOD Engine | Core Api Channel - Channel::Setpriority.

Could you try calling Channel.setPriority(0); after line 90 in FMODVoicePlayback.cs. I found this would keep the DSP real. Let me know if that helps at all!

Thank you again for assisting investigating this issue.

Just checking back in on this issue, since another Dissonance user seems to have encountered the problem.

There seems to be two theories that have been discussed: sample rates and virtualisation.

Has the default sample rate been changed in the FMOD Settings

Dissonance gets the rate with RuntimeManager.CoreSystem.getSoftwareFormat(out _sampleRate, out _, out _);. Give that, shouldn’t it work correctly no matter what rate has been set?

Virtualisation

There was some talk about virtualisation, and ensuring Dissonance playback never gets virtualised. This shouldn’t be necessary because Dissonance handles virtual channels.

We subscribe to channel event callbacks to monitor for the channel becoming virtual with code like this;

private static RESULT ChannelEventCallback(IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype, CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2)
{
    // Check this is a virtualisation event
    if (controltype != CHANNELCONTROL_TYPE.CHANNEL)
        return RESULT.OK;
    if (callbacktype != CHANNELCONTROL_CALLBACK_TYPE.VIRTUALVOICE)
        return RESULT.OK;

    /* snipped some error handling and sanity checking here */

    var isVirtual = commanddata1.ToInt32() != 0;
    SetChannelVirtual(isVirtual);

Then this other method is called in FixedUpdate on the “audio generator” - this is the object the channel pulls from in ReadDSP:

public void PumpVirtualised(float deltaTime, int sampleRate)
{
    if (!_isVirtual)
        return;

    lock (_pumpLock)
    {
        if (!_isVirtual)
            return;

        // Accumulate time elapsed since this audio generator was made virtual
        _virtualisedTimeAccumulator += deltaTime;

        // Take as many complete integer samples as possible
        var samples = (uint)Math.Floor(_virtualisedTimeAccumulator * sampleRate);

        // Decrease the timer by however much time that many samples is
        _virtualisedTimeAccumulator -= (float)samples / sampleRate;

        // Pump for that much audio, passing a null pointer because we don't
        // actually care about the result
        GetAudio(IntPtr.Zero, samples, 1);
    }
}

The idea here is when FMOD virtualises the channel we take over pumping audio out of the generator at the correct rate.

I think that addresses both of the working theories. Does this code all look like the correct way to handle things from an FMOD perspective?

2 Likes

Hi,

That makes sense. Thank you for investigating the issue!

To be clear there’s still some kind of issue here I think - people are still intermittently reporting this issue! I was just trying to narrow it down.

1 Like

I see, have you been able to reproduce the issue reliably yet?