Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio delay on HTML5 builds when loading big scenes #53343

Open
Tracked by #76797
HarmonyHoney opened this issue Oct 2, 2021 · 12 comments
Open
Tracked by #76797

Audio delay on HTML5 builds when loading big scenes #53343

HarmonyHoney opened this issue Oct 2, 2021 · 12 comments

Comments

@HarmonyHoney
Copy link

HarmonyHoney commented Oct 2, 2021

Godot version

3.3.3, 3.3.4

System information

Windows 10, HTML5, Firefox or Chromium, GLES2 or GLES3

Issue description

Whenever I load a heavy scene that takes more than a frame to load, the game's audio becomes desynchronized. On the title screen the menu sounds will play right when the key is pressed, after loading the level select scene, there is a noticeable delay in all sound effects after input.

Steps to reproduce

Load a big scene that takes longer than a frame, and play audio from an input key.

Minimal reproduction project

HTML5AudioDelay.zip

Run this project in HTML5

@Calinou
Copy link
Member

Calinou commented Oct 2, 2021

@HarmonyHoney Please upload a minimal reproduction project to make this easier to troubleshoot.

Also, can you reproduce this in a Chromium-based browser?

@HarmonyHoney
Copy link
Author

HarmonyHoney commented Oct 2, 2021

@HarmonyHoney Please upload a minimal reproduction project to make this easier to troubleshoot.

Also, can you reproduce this in a Chromium-based browser?

Hello! On chromium based browser this will cause audio stuttering issues while the load is happening, and audio will sound crackly shortly after. On Firefox it just halts the entire audio and then delays all audio after the load occurs.

I attached a minimal repro project! I made a "big scene" by duplicating a viewport 30 times in _ready().

there is a music loop from the start of the game, so you can hear the stuttering/halting issues in the respective browser. press X to play the audio clip. with the color of the text changing so you can see the disconnect between input and audio. press L to load the next scene.

I've seen the issue discussed here: https://itch.io/jam/stop-waiting-for-godot/topic/1630238/audio-stutter-in-html5-build on the itch.io message boards as well!

@NianoTT
Copy link

NianoTT commented Jul 3, 2022

Can confirm the issue still exists with 3.4.4 and 3.5 RC 5 and current Firefox version 102.

This is quite a major issue imo as it renders pretty much every HTML5 game unplayable on a browser that has quite significant market share. I tried different things that came to my mind to maybe find a workaround but unfortunatelly could not.

It does not happen with the threaded HTML5 export, unfortunatelly not all game websites supports the neccassary headers to make it run.

@Calinou
Copy link
Member

Calinou commented Jul 3, 2022

It does not happen with the threaded HTML5 export, unfortunatelly not all game websites supports the neccassary headers to make it run.

Unfortunately, there's nothing we can do to reduce sound latency if threads aren't supported. You can try decreasing the Output Latency.web project setting, but values that are too low will cause audible sound cracking if the CPU can't keep up with sound mixing.

You can look into not using Godot's audio subsystem at all and using Howler.js instead. This means the browser will play sounds directly, instead of going through WebAssembly.

@NianoTT
Copy link

NianoTT commented Jul 4, 2022

Unfortunately, there's nothing we can do to reduce sound latency if threads aren't supported. You can try decreasing the Output Latency.web project setting, but values that are too low will cause audible sound cracking if the CPU can't keep up with sound mixing.

The issue here is not the "normal", expected delay - the first scene in my game, basically the splashscreen, loads very fast and the sound works normally, it has the normal delay affected by the Output Latency setting which is totally fine.

However after the next, more complex scene loads (which takes a few frames), something breaks and the audio delay is over half a second. It does never recover from that, it stays like then when other scenes are loaded.

This does not happen on Chrome, only on Firefox in my testing. This is what makes the games unplayable.

@NianoTT
Copy link

NianoTT commented Jul 7, 2022

I hope it's ok to leave this here, but if someone finds this in dire need of a fix: I could get around this bug by playing all my audio throgh howler.js instead of Godots own functions. Here is a starting point: https://3p0ch.newgrounds.com/news/post/1148893

No issues or delays/crackling without Threads, so the game can go to sites that don't support them.

@idchlife
Copy link

Are Unity and Godot web export different? Some companies we worked with use Unity with more extensive scenes than our Godot projects and they have no problems with audio. Also I remember we had no Audio problems with Godot web export 1.5 years ago.

In my opinion Godot 3.5 has abnormal issues featuring audio stutters in web export, not the "normal because your computer slow" amount. Hi-end mobile devices and computers in our office experience audio stuttering even when not loading new scenes. Sometimes Godot web export plays like it is constructed from Valve games loading screens (famous audio stuttering moment).

Is nothing at all can be done in terms of web export?

@Calinou
Copy link
Member

Calinou commented Jul 19, 2023

@idchlife Are you using threads in the web export? This makes an important difference in how audio is handled, so please mention it in your comment.

If you want low audio latency, you need to use a web export with threads. (This is always the case in Godot 4.)

@idchlife
Copy link

@Calinou we are exporting without threads because platform where we upload does not support service workers. Unfortunately, it's still the case.

Actually we are investigating intensely right now what can be the root case for audio stuttering and lagging and we stumbled upon the situation where... Avoiding font and text in game can remove audio stuttering in web for good. I mean game can load and work with lots of objects, images etc without audio stutters. One rule: no text/font. We will create issue with reproduction project soon.

@Calinou
Copy link
Member

Calinou commented Jul 19, 2023

Avoiding font and text in game can remove audio stuttering in web for good.

This is expected when rendering glyphs for the first time (especially at large sizes1), as they need to be rasterized. To avoid this, display all common glyphs (e.g. the ASCII range) for 1 frame behind a ColorRect when the game starts. An alternative is to use a BitmapFont instead of a DynamicFont.

Godot 4 has a built-in font prerendering solution in DynamicFont to avoid this stuttering.

Footnotes

  1. DynamicFont rasterization performance depends on its size, with power-of-two thresholds such as 16, 32, 64, 128. This means that rendering a font at size 31 is nearly as fast as 32, but 33 is much slower than 32.

@idchlife
Copy link

Bitmap fonts fix problem completely. The more you know. Thank you @Calinou ❤️

@AnnanDistance
Copy link

Removing dynamic fonts might help with stuttering but it does not stop the half second lag.
Problem appears while running from itch.io in Firefox but not in Chrome. I am running Windows 10.

What I noticed about the half second lag in my browser game while running from itch are:
If the scene is the main scene there is no issue.
If the scene is reloaded with a get_tree().reload_current_scene() there is no issue.
If the scene is loaded from a different scene with a change_scene() or even if loaded and added as child of a master scene, the lag appears.
Once the lag appears, it will not go away even if scene is changed again.

I tested these on Godot 3.5.3.

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants