ppy / osu

rhythm is just a *click* away!
https://osu.ppy.sh
MIT License
15.33k stars 2.28k forks source link

"System audio playback is not working as expected" notification can show unexpectedly #26404

Open bdach opened 10 months ago

bdach commented 10 months ago

Type

Game behaviour

Bug description

Reproduction steps:

This shouldn't be possible in the first place, but may also warrant investigation why this is happening anyway as it may indicate the logic being broken. I haven't managed to break this in actual gameplay yet, though.

Screenshots or videos

osu_2024-01-05_19-31-17

Version

current master

Logs

n/a

abi19911 commented 9 months ago

I too am getting this error while playing every 1 or 2 maps, although sometimes I can play for hours without this error. If it helps I'm on a linux system with pipewire installed.

bdach commented 9 months ago

@abi19911 pipewire configurations are out of scope of this issue, it's more likely that your config is broken. this was originally reproduced on windows

BashhScriptKid commented 9 months ago

I just noticed deleting the last object that was placed near the end of the song doesn't end up as prescribed Scrubbing it back to the beginning then back to near end kinda resolves that as well, probably because the audio catches up on scrubbing faster than the beatmap, then object gets left behind, game expecting theres still gonna be some music left for the object while the song is already finished.

https://github.com/ppy/osu/assets/63024549/08ca6854-47d3-4a3a-940d-4c9075b0d44a

bdach commented 9 months ago

As far as I can tell this is some bass weirdness...

Using the audio track from the aforementioned beatmap, the following reproducer does weird things:

using ManagedBass;

namespace Reproducer;

public static class Program
{
    public static void Main(string[] args)
    {
        if (!Bass.Init())
            throw new InvalidOperationException("could not init");

        var hStream = Bass.CreateStream("audio.mp3");

        Console.WriteLine($"channel length is {Bass.ChannelGetLength(hStream)}");

        Bass.ChannelPlay(hStream);
        Bass.ChannelSetPosition(hStream, 2053312);

        while (Bass.ChannelIsActive(hStream) == PlaybackState.Playing)
        {
            Console.WriteLine(Bass.ChannelGetPosition(hStream));
        }
    }
}

This program first prints

channel length is 2057472

but then spins for a while, printing 2053312 for a good few seconds and then terminates. Which basically amounts to "BASS is lying that it is playing the track, while simultaneously seemingly staying in a single playback position". Which explains the issue - the gameplay clock is basically stalled (doesn't transition to decoupled because the source is lying to it that it's playing), and so it only takes the realtime difference to grow large enough to report a discrepancy.

For now I think we'll just want to silence the notification in replays to not look ridiculous, but ultimately it'll need reporting to bass. We have previously had problems with seeking in VBR files, but the audio for this beatmap doesn't appear to be VBR as per a random online utility (mediainfo) - it's reporting 128kbps constant.

frenzibyte commented 9 months ago

@bdach should the priority of this one be dropped now that it's silenced?

developomp commented 3 months ago

I didn't have this issue while using the built-in 3.5mm headphone port on my laptop but as soon as I started using an external DAC (ifi zen air to be specific) I got this issue. This happens on the latest lazer client (2024.31.0).

peppy commented 2 months ago

If it only started with a new audio device, there's a high likelihood that your new device is not reporting current time values with high enough fidelity. For most use cases this is fine, but as osu! (currently) uses this as the primary method of timekeeping it can cause issues.

We may be able to improve his in the future, but for now my recommendation would be to use a different audio device for osu!.

You may also be able to find updated drivers or firmware for your DAC (or change windows settings such as sample rate) to improve things, as that does sound like a device performing below acceptable thresholds.

developomp commented 2 months ago

I'll play around with sample rate and audio buffer settings and see what works.

developomp commented 2 months ago

I still don't fully understand why the issue occurs or how it's affected by my hardware, but I have narrowed down the issue to the PIPEWIRE_LATENCY environment variable I have set for the game.

from https://github.com/PipeWire/pipewire?tab=readme-ov-file#usage:

PIPEWIRE_LATENCY=<num/denom> to configure latency as a fraction. 10/1000 configures a 10ms latency. Usually this is expressed as a fraction of the samplerate, like 256/48000, which uses 256 samples at a samplerate of 48KHz for a latency of 5.33ms. This function does not attempt to configure the samplerate.

I'm not seeing any error message after making the following alteration. Even on longer maps (~20min).

-PIPEWIRE_LATENCY=8/44100
+PIPEWIRE_LATENCY=16/44100

The clock validation logic can still fail under extreme scenarios, but it should be fine for now.

The logic in question: https://github.com/ppy/osu/blob/62f737d8de0944d5b278d4ab72844af6dbc67ace/osu.Game/Screens/Play/MasterGameplayClockContainer.cs#L178

bdach commented 2 months ago

@developomp pipewire weirdness is out of scope of this issue, please move it to a discussion