Dev build/Linux: modded SoundClips not preloaded [RESOLVED]

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Dev build/Linux: modded SoundClips not preloaded [RESOLVED]

Post by pango »

When overloading SoundClips, sounds are not played on first use after game start, only on second and later uses.
I assume the only fix would be to preload them?
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Dev build/Linux: modded SoundClips not preloaded

Post by TheLacus »

I can't replicate this issue. Can you suggest a way to do it, with a save if needed?

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Dev build/Linux: modded SoundClips not preloaded

Post by pango »

Hi TheLocus,
We're both talking of wav files soundclips overrides right?
The original mixdown solution, using patched DAGGER.SND, indeed does not have that issue.
But with wav files overrides, like the ones I provided halfway thru the thread above, I always have to wait for the second use to ear a sound effect; With the first door you open it''s a bit unsettling, but in a dungeon it can even be deadly.
I don't see what gamesave I could provide, it's purely a runtime effect and won't show up in the data...
If you can't reproduce the issue with the wav files, maybe it's dependent on platform (Linux here), or hardware?
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Dev build/Linux: modded SoundClips not preloaded

Post by pango »

I saw barely anything audio related in Player.log, is there a way I could produce more logs on my setup?
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Dev build/Linux: modded SoundClips not preloaded

Post by Interkarma »

If you add a Debug.Log() with the information you want to DaggerfallAudioSource.PlayOneShot(), it should eject information for most effects.

And sounds are read by SoundReader.GetAudioClip(). Replacement injection runs here also, not sure why this would behave differently to standard effects. In concept both types of effects are loaded and cached at the same point in execution.

I experienced a problem similar to what you're describing very early on. For example, a door sound would only play on fresh load the second time you opened a door. I remember I had to restructure things to fix this, but it's a been some time (almost 4 years) and it wasn't a bug worth remembering much about at the time. Maybe just need to step through the process of injection to see where effect is skipped on first play.

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Dev build/Linux: modded SoundClips not preloaded

Post by TheLacus »

pango wrote: Mon Oct 29, 2018 10:28 pm But with wav files overrides, like the ones I provided halfway thru the thread above, I always have to wait for the second use to ear a sound effect; With the first door you open it''s a bit unsettling, but in a dungeon it can even be deadly.
Sorry i wasn't clear, I was asking with what sound effects you've encountered this problem, maybe is easier to replicate for some specific enemies with a big sound file. I'll try again with door sounds.

I believe the issue is that sound clips are requested synchronously but the actual data loading is asynchronous. AudioSource waits for AudioClips with Loading state, but maybe it happens that they can be received when the state is still Unloaded. This shouldn't be an issue with AudioClips loaded from asset bundles.

Loose files import is done via WWW requests, which are inherently async and for a good reason. At the same time, GetAudioClip() is called from many different places and is expected to return an immediately playable soud effect, so this is a tricky situation.

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Dev build/Linux: modded SoundClips not preloaded

Post by pango »

TheLacus wrote: Tue Oct 30, 2018 2:12 pm Sorry i wasn't clear, I was asking with what sound effects you've encountered this problem, maybe is easier to replicate for some specific enemies with a big sound file. I'll try again with door sounds.
Ah ok, it seems to happen with all sound effects as far as I can tell. But it's easier to tell for sounds triggered by your own actions (for others you may not be aware you missed a sound...)
TheLacus wrote: Tue Oct 30, 2018 2:12 pm Loose files import is done via WWW requests, which are inherently async and for a good reason. At the same time, GetAudioClip() is called from many different places and is expected to return an immediately playable soud effect, so this is a tricky situation.
Thanks both of you for technical details,
Yes, I suspected this "load sound asynchronously but start playing it immediately" was not comfortable, and requires either:
1) to accept a delay before some effects start;
2) to be able to play sounds being streamed from storage (if it can start streaming fast enough);
3) to preload all effects.
I thought DFU strategy was 3) but it seems to be 1), assuming that the effects would load fast enough for the initial delay to be unnoticeable (and maybe skip the sound if loading took too long?)
Anyway, I'll see what I can debug with all those infos...
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Dev build/Linux: modded SoundClips not preloaded

Post by pango »

Okay, it seems the problem is exactly as expected; If I instrument PlayOneShot, I get

Code: Select all

Clip 94 status Unloaded
And adding even a small delay for sound loading works around the issue

Code: Select all

diff --git a/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs b/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
index f7504d90..d6ccffc1 100644
--- a/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
+++ b/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
@@ -89,6 +89,7 @@ namespace DaggerfallWorkshop.Utility.AssetInjection
                     WWW www = new WWW("file://" + path);
                     audioClip = www.GetAudioClip();
                     DaggerfallUnity.Instance.StartCoroutine(LoadAudioData(www, audioClip));
+                    System.Threading.Thread.Sleep(1);
                     return true;
                 }
 
(Of course that's not the right way to fix this, I assume PlayOneShot should be run from within some callback instead, unless Unity has other tricks to handle that case).

And I'm not sure whether loading from mods will be synchronous or asynchronous?

Code: Select all

                // Seek from mods
                if (ModManager.Instance != null && ModManager.Instance.TryGetAsset(name, false, out audioClip))
                {
                    if (audioClip.preloadAudioData || audioClip.LoadAudioData())
                        return true;

                    Debug.LogErrorFormat("Failed to load audiodata for audioclip {0}", name);
                }
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Dev build/Linux: modded SoundClips not preloaded

Post by TheLacus »

pango wrote: Thu Nov 01, 2018 12:27 am And I'm not sure whether loading from mods will be synchronous or asynchronous?

Code: Select all

                // Seek from mods
                if (ModManager.Instance != null && ModManager.Instance.TryGetAsset(name, false, out audioClip))
                {
                    if (audioClip.preloadAudioData || audioClip.LoadAudioData())
                        return true;

                    Debug.LogErrorFormat("Failed to load audiodata for audioclip {0}", name);
                }
AFAIK this behavior is affected by loadInBackground property on the AudioClip. If set, LoadAudioData() should return immediately but start an async loading process. The audiosource will wait for the loading process to complete and then play when possible.

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: Dev build/Linux: modded SoundClips not preloaded

Post by pango »

GetAudioClip(true, true) does the job without the need for an explicit coroutine:

Code: Select all

diff --git a/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs b/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
index f7504d90..a418965a 100644
--- a/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
+++ b/Assets/Scripts/Utility/AssetInjection/SoundReplacement.cs
@@ -87,8 +87,7 @@ namespace DaggerfallWorkshop.Utility.AssetInjection
                 if (File.Exists(path))
                 {
                     WWW www = new WWW("file://" + path);
-                    audioClip = www.GetAudioClip();
-                    DaggerfallUnity.Instance.StartCoroutine(LoadAudioData(www, audioClip));
+                    audioClip = www.GetAudioClip(true, true);
                     return true;
                 }
 
However I'm not sure you get any nice log if something wrong happens, the documentation I've seen is very shallow...
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

Locked