Opened 3 years ago

Closed 2 years ago

#13080 closed defect (fixed)

AUDIO: DiMuse - Stuttering sound when manually changing audio_buffer_size

Reported by: raziel- Owned by: AndywinXp
Priority: normal Component: Audio
Version: Keywords:
Cc: Game:


ScummVM 2.6.0git (Nov 18 2021 10:36:00)
Features compiled in: Vorbis FLAC MP3 RGB zLib MPEG2 Theora AAC A/52 FreeType2 FriBiDi JPEG PNG GIF cloud (servers, local) TinyGL OpenGL

for more info on the option.

There is a "hidden" option one can use in the .ini file to override the on-the-fly calculated audio buffer.
Using this option with a value of 8192 makes the sound stutter (all ingame music, except the cutscenes).
Removing it will, of course, fix this behaviour.

Since this option is there and is causing such malfunction, i guess it would be good to either warn the user (if in use) or completely ignore the setting for those three games?

The Dig
Full Throttle (Version A/English)
The Curse of Monkey Island (Windows/English)

AmigaOS4 - PPC - SDL - BE
gcc (adtools build 11.1.0) 11.1.0

Change History (12)

comment:1 by AndywinXp, 3 years ago

Thanks for reporting this! You know, I'm currently getting what could be the same stuttering (in-game, no cutscenes) on my Android phone!

I figured it was because it wasn't fast enough to process data in time for each callback but... testing the three games on my slow-on-purpose Windows Xp VM everything was working great.

I'll test this behavior on my machine and see if I can replicate it!

comment:2 by raziel-, 3 years ago

Hmm...maybe it is as simple as a miscalculated audio buffer then, on your android? :-)

comment:3 by AndywinXp, 3 years ago

It might be, but I really don't know where this calculation is carried out in the codebase for Android. I'll try summoning an Android dev for this :-P

comment:4 by AndywinXp, 3 years ago

Yup, just tested different values on my PC, same exact behavior as Android, which appears to be using either 2048 or 4096 for the audio buffer.

comment:5 by AndywinXp, 3 years ago

Well okay, this is bigger than I thought: the audio buffer size is calculated and set up at ScummVM startup time, and it's set up at audio backend level (SDL for Windows, and some other thing for Android), so it's not toggleable for a game-to-game basis.

In other words, I'm screwed: the way audio is processed in the engine needs a low latency buffer (about 1024), otherwise if I crank the feed size in the engine to accomodate the huge audio buffer size, I get an in-game latency of about half a second, which is a lot.

The old engine handled audio quite differently at this stage of the pipeline, so it could afford having a buffer of a little more than 8192 samples with no latency whatsoever.

Last edited 3 years ago by AndywinXp (previous) (diff)

comment:6 by raziel-, 3 years ago

That doesn't sound good.
Does it mean every platform which calculates a too high buffer will suffer from this stuttering?

Can't you read the calculated buffer in on game start and fix a too high setting by overruling it?
That would be a global overrule, of course, but if it can be done on game-start and dropped again on game-closure, it wouldn't hurt other games, would it?

comment:7 by AndywinXp, 3 years ago

While this sounds ideal quality/latency-wise, it seems a bit hackish; I guess I could do the opposite: fetch the current audio_buffer_size from DiMUSE and adjust the feed size and the max number of audio blocks in queue accordingly. Even though this means that the affected devices will suffer some serious audio latency... do I read the current audio buffer size anyway at runtime? :-P

Last edited 3 years ago by AndywinXp (previous) (diff)

comment:8 by AndywinXp, 3 years ago

Well, another solution would be to allow the user to tweak audio_buffer_size from the GUI (because for the life of me, on my non-rooted Android device, I can't find scummvm.ini not even with the LAN server), and calculate the DiMUSE feed size at start-up given that value.

This is the cleanest solution I can personally think of, since it would correctly account for latency (which is one of the purposes of audio_buffer_size), or rather, raise it up accordingly.

comment:9 by raziel-, 3 years ago

Isn't the .ini location displayed in options under the "Path" tab now?
Or maybe I misunderstood?

Sorry to be of not much help here, i don't know how to code, but I'm sure whatever solution you come up with will work.
And maybe once you got a PR up other devs will chime in and have more fleshed-out ideas than me :-)

comment:10 by AndywinXp, 3 years ago

Hmm, after setting up a rather messy android environment and doing some tests, the audio stops stuttering when setting the DiMUSE feed size at 2048, which multiplied by 2 channels and 2 bytes per sample becomes 8192. This creates an embarassing amount of latency, as I predicted before.

Unfortunately this engine introduces latency by design, and changing the Android specific code to set a 1024 buffer size does absolutely nothing as I suspected, so I think I'm out of ideas here.

I'll ask for some help in the Discord server.

comment:11 by AndywinXp, 3 years ago

Hold up! Changing the line

if (_internalMixer->_stream->numQueuedStreams() < 3) {

in dimuse_tracks.cpp, to

if (_internalMixer->_stream->numQueuedStreams() < 5) {

gives an almost optimal latency outcome, with some veeery occasional audio hiccups, and definitely makes the games very playable until a better low-latency native solution comes along.

Now the problem is to understand if every Android device has the same issue and likes this workaround ;-)

comment:12 by AndywinXp, 2 years ago

Owner: set to AndywinXp
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.