Author Topic: BASS_ASYNCFILE causing weird stream behavior on Windows  (Read 256 times)

Wieku

  • Posts: 3
Related topics:
https://github.com/ppy/osu/issues/18652
https://github.com/Wieku/danser-go/commit/b5a6ce356ce4b9efe151f47a85b1e045cb32da2c

Hi,

It seems that since like 2 weeks, when audio stream is initialized with BASS_ASYNCFILE flag and its position is being modified by ChannelSetPosition, it causes ChannelGetPosition to report delayed values and music seems to start playing earlier than target position.

From initial investigation it seems:
  • It's happening only on Windows (at least builds 19043 and 19044)
  • It's not deterministic, sometimes it works correctly, sometimes not
  • Setting position to 0 works correctly
  • Reproducible on BASS 2.4.16.1 and 2.4.16.7
  • Not enough data, but seems happening only on AMD machines as I'm not able to reproduce it on a machine with Intel Coffee Lake CPU (comparable setup uses the same audio device (Scarlett Solo) and has the same Windows 10 build (19043))
  • It's also happening when BASS is initialized with device_id 0 and data is being pulled from main mixer with ChannelGetData, in this case though it hints that seek is not working correctly because ChannelGetPosition is not used

Comparison recorded from affected system:

It's hard to tell if it's an undefined behavior in Windows' file handling in BASS or it's a Windows/AMD bug so assistance with that issue would be very helpful.

Thanks!

Ian @ un4seen

  • Administrator
  • Posts: 24494
That sounds strange, as BASS_ASYNCFILE shouldn't affect the accuracy of setting or getting the position. But it might cause a BASS_ChannelSetPosition call to take a bit longer, eg. if that has to wait for an asynchronous read to finish before seeking in the file. Perhaps that's making a difference? You could try logging and comparing the time taken by the BASS_ChannelSetPosition calls to see if there is indeed a difference.

Looking at the code in your GitHub link, it appears that all playback is through a mixer? Is the issue that 2 sources that should start at the same time in the mix are not? If so, please try locking the mixer to add the sources, which will ensure that they start together in the mix. For example:

Code: [Select]
BASS_ChannelLock(mixer, true); // lock mixer
BASS_Mixer_StreamAddChannel(mixer, source1, flags); // add 1st source
BASS_Mixer_StreamAddChannel(mixer, source2, flags); // add 2nd source
BASS_ChannelLock(mixer, false); // unlock mixer

Wieku

  • Posts: 3
Quote
it appears that all playback is through a mixer?

Yes, all audio goes through a mixer. Same in osu!.

Quote
Is the issue that 2 sources that should start at the same time in the mix are not?

The issue is with sudden breakage of audio seeking. The breakage seems to happen only when ChannelSetPosition is called with non-zero position.

It started appearing like 2 weeks ago. It was working correctly before. And yes, when it happens, people reported a sligtly bigger delay before music starts playing after seek. It doesn't happen every time though (like 20% chance to get that issue). After that music starts playing at earlier point than anticipated, but position is getting reported as if it resumed playing at correct position.

Squashed flow of playing an audio file:

Code: [Select]
BASS_SetConfig(BASS_CONFIG_DEV_NONSTOP, 1)
BASS_SetConfig(BASS_CONFIG_VISTA_TRUEPOS, 0)
BASS_SetConfig(BASS_CONFIG_BUFFER, 100)
BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 5)
BASS_SetConfig(BASS_CONFIG_DEV_BUFFER, 10)
BASS_SetConfig(BASS_CONFIG_DEV_PERIOD, 10)
BASS_SetConfig(68, 1) // BASS_CONFIG_MP3_OLDGAPS

BASS_Init(-1, 44100, 0, NULL, NULL)

masterMixer := BASS_Mixer_StreamCreate(44100, 2, BASS_MIXER_NONSTOP)
BASS_ChannelSetAttribute(masterMixer,BASS_ATTRIB_BUFFER, 0)
BASS_ChannelSetDevice(masterMixer, BASS_GetDevice())

BASS_ChannelPlay(masterMixer, 0)

channel := BASS_StreamCreateFile(0, filePath, 0, 0, BASS_STREAM_DECODE | BASS_STREAM_PRESCAN | BASS_ASYNCFILE)

fxChannel := BASS_FX_TempoCreate(channel, BASS_FX_FREESOURCE | BASS_STREAM_DECODE)

BASS_Mixer_StreamAddChannel(masterMixer, fxChannel, BASS_MIXER_CHAN_NORAMPIN|BASS_MIXER_CHAN_BUFFER)

BASS_Mixer_ChannelSetPosition(fxChannel, BASS_ChannelSeconds2Bytes(fxChannel, pos), BASS_POS_BYTE)

currentPos := BASS_ChannelBytes2Seconds(fxChannel, BASS_Mixer_ChannelGetPosition(fxChannel, BASS_POS_BYTE)) //if we call previous function with pos > 0 and BASS_ASYNCFILE is used in StreamCreateFile, subsequent calls to this function will start returning wrong values compared to music being heard


Turning off ASYNCFILE fixes the problem completely.

I will try to make some diagnostics about seek delay with affected people.

Ian @ un4seen

  • Administrator
  • Posts: 24494
The issue is with sudden breakage of audio seeking. The breakage seems to happen only when ChannelSetPosition is called with non-zero position.

It started appearing like 2 weeks ago. It was working correctly before. And yes, when it happens, people reported a sligtly bigger delay before music starts playing after seek. It doesn't happen every time though (like 20% chance to get that issue). After that music starts playing at earlier point than anticipated, but position is getting reported as if it resumed playing at correct position.

Strange that it should suddenly start happening. Did you make any changes (eg. code or DLLs) just before that? Is it happening with a particular file format or all? If you haven't already done so, please try with WAV files. If you can, please also try without the BASS_FX_TempoCreate call (ie. plug the decoder directly into the mixer), to check if the problem is in any way related to that stuff.

Also confirm what BASSmix version you're using, ie. what BASS_Mixer_GetVersion returns.

Wieku

  • Posts: 3
Code: [Select]
BASS Version:     2.4.16.1
BASS FX Version:  2.4.12.1
BASS Mix Version: 2.4.10.0

Although it also happens with osu!lazer which uses:
Code: [Select]
BASS Version:     2.4.16.7
BASS FX Version:  2.4.12.6
BASS MIX Version: 2.4.11.1

Quote
Is it happening with a particular file format or all?
IIRC all files were mp3.

Quote
Did you make any changes (eg. code or DLLs) just before that?
No, BASS related code/dlls haven't been touched in at least 8 months. I just found that I got a first notice about this on 18th of May this year. AMD CPU as well.

ppy

  • Posts: 4
To add to the weirdness, even without the async flag, at least one user is reporting discrepancies to a lesser degree (https://github.com/ppy/osu/issues/18909). Hard to say if this is the same issue (maybe Wieku can confirm or deny whether they can reproduce the lesser differences?)

Ian @ un4seen

  • Administrator
  • Posts: 24494
After reading the GitHub issue links, it unfortunately still isn't entirely clear to me what the problem actually is, as I'm not familiar with the game/terms being discussed. Can you say the problem is definitely happening in a BASS_Mixer_ChannelSetPosition call, or might it be in BASS_Mixer_ChannelGetPosition or even elsewhere? And what is the reference that's being compared with, ie. how do you know it's off target? Once it goes off, does it stay that way and by the same amount?

Wieku mentioned all files being MP3. Would it be possible to try with WAV files instead to see if that makes any difference? If it only happens with MP3 files then perhaps it's a pre-scanning (BASS_STREAM_PRESCAN) issue.