ValveSoftware / csgo-osx-linux

Counter-Strike: Global Offensive
http://counter-strike.net
786 stars 69 forks source link

CS2 Delayed Audio - Pipewire #3283

Closed kodatarule closed 9 months ago

kodatarule commented 1 year ago

Your system information

Operating System: EndeavourOS KDE Plasma Version: 5.27.8 KDE Frameworks Version: 5.110.0 Qt Version: 5.15.10 Kernel Version: 6.5.3-273-tkg-bmq (64-bit) Graphics Platform: Wayland Processors: 16 × AMD Ryzen 7 5800X3D 8-Core Processor Memory: 31,3 GiB of RAM Graphics Processor: NVIDIA GeForce RTX 3090/PCIe/SSE2

Please describe your issue in as much detail as possible:

Firstly the game requires a launch command in order to get audio to work under pipewire and second it has a good between 2-5 seconds delay, you see the action on screen and after that you hear the audio. For CS GO neither of those issues were present.

Steps for reproducing this issue:

  1. Just try to play the game using pipewire( launch command -sdlaudiodriver pipewire required otherwise game would be without audio)
jnvsor commented 1 year ago

I had this occur but only after playing for a few hours. It went away after a game restart but it does happen

Edit: Yeah it seems to slowly desync and get later and later from what I've seen

ZeroYamaoka commented 1 year ago

I had same isuee i changed default sound device in game option to my Soundcard that i use and it fixed the problem for me (Well maybe it will help)

stealingudc commented 1 year ago

This hack reduced the audio delay to up to a second for me on Debian 12 with pipewire-pulse. Even so, it's still barely playable.

valve, pls fix

JacKeTUs commented 1 year ago

Guys, can you retest please if latency will still build up on latest update without any workarounds?

JacKeTUs commented 1 year ago

I tried retest it with latest update - latency is still building up.

My method of testing:

Launch Audacity, set Recording Device - cs2 app. Press record in stereo. In Carla reroute your mic capture to PortAudio device - that's our Audacity. So left channel in Audacity records cs2 and right channel is my mic. I click the mouse and then hear cs2 gunshots. I measure latency between start of a click and start of sound from CS2.

Initially right after map was loaded, before mouse click and sound of a gun i had ~90-100ms (of course my system latency / recording software latency/etcetc will affect it, but i didn't change it through tests, nor restart the game / sound system / audacity, etc) After 10-15 minutes - about 110-120ms latency Another 10 minutes - about 140ms latency Another 10 minutes - about 170ms, already noticeable with eyes Another 10 - about 200ms, already unplayable Another 15 - about 230-240ms, unplayable indeed

So latency did build up for me.

image

image

image

image

JacKeTUs commented 1 year ago

cs2latency.zip I exported project to .ogg file, you can try to import it in audacity. Original aup3 is 145Mb, quite big for github Timestamps: 0s - 48s - right after loading the game 48s - 1m21s - after ~10minutes 1m22s - 2m04s - after another ~10 minutes 2m05s - 2m55s - after another ~10 minutes 2m55s - 3m33s - after another ~10 minutes

My system information: https://gist.github.com/JacKeTUs/d36b8e75a78f96160fd9c12eeccab18b Pipewire 0.3.80, config: https://gist.github.com/JacKeTUs/abc72942af8e96a47a7eba4430fc5643

JacKeTUs commented 1 year ago

May be it's the Pipewire issue, but i definitely didn't have that desync problem with csgo and other games (osu!lazer for example, rhythm game where sound latency even +-20ms is critical)

szmarczak commented 1 year ago

I can confirm that the latency builds up (flatpak steam, pipewire).

szmarczak commented 1 year ago

Changing the audio device also fixes the latency issue (you have to actually change the device by selecting it from the menu, and change it back to the old one). The changes takes a few hundred ms to take effect, so binding this to a key like W or MOUSE1 won't be ok :(

NiSchie commented 1 year ago

Can confirm latency buildup.

Operating System: Arch XFCE Version 4.18 GTK Version: 3.24.38 Qt Version: 5.15.10 Kernel Version: 6.5.5-arch1-1 Graphics Platform: X11 Processors: AMD Ryzen 5 3600 Memory: 16 GiB of RAM Graphics Processor: NVIDIA GeForce GTX 1660 Ti Sound server: pipewire

jpgay commented 1 year ago

Latency buildup also occurs with PulseAudio. System info: https://gist.github.com/jpgay/a6f3f51e590652eef96c91216b1e7e96

itouchdennis commented 1 year ago

Having the same problem on pipewire.

Did someone test it with alsa ?

Yesterday I tried the workaround with the .asoundrc, timings where on point for the time I tested it, but unfortunately my sound got stuttering and cracking after a short while so I did not test it one or two matchmaking games, just for some short deathmatches.

My console got also following output while using the .asoundrc file:

[SoundSystemLowLevel] Audio device starved 512 samples

Which could indicate a too huge bitrate and a too small buffersize - might take a look this evening to check if I could lower the sample rate and maybe increase a bit the buffer size (I assume the buffer size should not be that huge, as it could also cause delay).

JacKeTUs commented 1 year ago

Some tinkering: Game tries to use pulseaudio by default, and on my system it defaults to pipewire-pulse bridge. On pw-top i can see that game asks for 256 quantum and 48000 rate by default

Forced pipewire does not help. PULSE_LATENCY_MSEC=60 and PIPEWIRE_LATENCY=128/48000 added to launch command did not help. My thoughts was "if i set constant latency, issue will be fixed".

Also - latency increases even if game is staying in background

edit: forced pipewire tested

JacKeTUs commented 1 year ago

@icculus, i believe that you could help us here, maybe? Tell us please, how can we test this more throughfully?

Jerroder commented 1 year ago

I have the exact problem jnvsor described... but I'm on windows 10

I tried reinstalling windows and it didn't fix it. One idea I have is that I can change my USB sound card's buffer size, but even when trying with lower or higher values it doesn't fix it.

itouchdennis commented 1 year ago

I tested a quick deathmatch with the update today, sound works but seems a bit delayed.

I added the start option -dxvk And retested a quick deathmatch, sound was crisp on point, I will play later some games and see if a delay builds up or this would work, might be related to the vulkan build(?)

Might be placebo, need to test more

Spacefish commented 1 year ago

Pipewire on ubuntu 23.10 here, i have up to a second delay. Latest public CS2 version. If i shoot i see the 3-4th shot and then the sound starts playing..

xstaticxgpx commented 1 year ago

I think I was able to make a noticeable improvement by doing this - so it might be worth trying different values to see what works best for your setup? I use a S24LE/96khz USB DAC so this may not work for everyone...

Launch options:

env PULSE_LATENCY_MSEC=30 %command% -vulkan -novid -nojoy +exec autoexec.cfg

Seems like you can confirm the change with pw-mon looking for application.name = cs2

Before

        properties:
                client.api = "pipewire-pulse"
                pulse.server.type = "unix"
..
                application.process.binary = "cs2"
                application.name = "cs2"
..
                node.rate = "1/96000"
                node.latency = "512/96000"

After

node.rate = "1/96000"
node.latency = "720/96000"

(or look at the QUANT column in pw-top - it seems like usual applications show 1024 or 2048 :man_shrugging:)

This still seems hacky because the application should probably be coordinating better with the pipewire/whatever daemon... this is a random selection of chromium/firefox/mpv/cs2 all playing audio:

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME                                                                
S   28      0      0    ---     ---   ---   ---     0                  Dummy-Driver                                                        
S   29      0      0    ---     ---   ---   ---     0                  Freewheel-Driver
S   36      0      0    ---     ---   ---   ---     0                  Midi-Bridge     
R   42    512  96000  82.4us  17.7us  0.02  0.00    0    S24LE 2 96000 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   52   1024  96000  18.0us  11.1us  0.00  0.00    0    F32LE 2 96000  + Chromium                                                   
R   65   2646  44100  30.2us  26.7us  0.01  0.00    0    S16LE 2 44100  + mpv                                                              
R   58   3600  48000  58.2us  11.8us  0.01  0.00    0    F32LE 2 48000  + Firefox Developer Edition
R   71    720  96000  70.8us   4.3us  0.01  0.00    0    F32LE 2 96000  + cs2                                                              

PULSE_LATENCY_MSEC=60 and PIPEWIRE_LATENCY=128/48000 added to launch command did not help. My thoughts was "if i set constant latency, issue will be fixed".

@JacKeTUs I think the 128 seen in your second envvar there might have prevented the first from working properly.

PULSE_LATENCY_MSEC=60 works even better for me, very crisp - most noticeable with pistols for whatever reason.

JacKeTUs commented 1 year ago

@xstaticxgpx, i tried first with pulse-pipewire bridge, without any arguments and only PULSE_LATENCY_MSEC, and later with forced pipewire with only PIPEWIRE_LATENCY added. With both methods i still had build-up latency issue How long you've been testing the game? Because at first yeah, sound is on point, but later, like 30-40 minutes - it's becoming more and more delayed

xstaticxgpx commented 1 year ago

I previously had the same behavior where after ~30min it was unplayable because of the sound delay - now with PULSE_LATENCY_MSEC=60 I can play for at least ~2 hours with zero noticeable delay. FWIW, as described here: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#pipewire-buffering-explained

Note that PIPEWIRE_LATENCY= does nothing for PulseAudio clients.

So that probably does nothing here for cs2, so maybe you guys just need to try different values?

@JacKeTUs Did you mean "forced pipewire" with this? SDL_AUDIODRIVER=pipewire ?

JacKeTUs commented 1 year ago

Yes, but with -sdlaudiodriver pipewire. Without any other args game defaults to Pulseaudio, and on my system there is pulse-pipewire bridge, which imitates Pulseaudio api. Without any args i tried PULSE_LATENCY_MSEC, and got similar results with increasing latency over time. For tests i also tried to set comically high latency like 2 seconds - it worked, and latency still would build itself up lol

Later i tried with forced pipewire with -sdlaudiodriver=pipewire - PULSE_LATENCY_MSEC stopped working, and i needed to set PIPEWIRE_LATENCY instead. Sadly it didn't help at all

xstaticxgpx commented 1 year ago

Yea something is still messed up here, there is less delay and it doesn't seem to get much worse as quickly, I'm thinking it's related to the number of sounds played and so testing in a bot match vs public deathmatch it manifests differently :thinking:

Starting a bot match after extended pub deathmatch play with the sound delay and checking console:

> sv_cheats true
> snd_report_verbose_error true
[AI BT]: Unable to buy after multiple attempts.
[Developer] Failed to find ui preference 'spec_autodirector_cameraman'
[ResourceSystem] Failed loading resource "panorama/images/_small_png.vtex_c" (ERROR_FILEOPEN: File not found)
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.
[AI BT]: Unable to buy after multiple attempts.
[AI BT]: Unable to buy after multiple attempts.
[AI BT]: Unable to buy after multiple attempts.
[AI BT]: Unable to buy after multiple attempts.
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.
Achievements disabled: cheats turned on in this app session.
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.
[Shooting] sv: Lag comp - full interp info doesn't match target time, using target time instead.

Maybe that's helpful to Valve?

Also trying:

Remove all envvars, use -sdlaudiodriver alsa - see pw-top:

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME                                                                
I   28      0      0   0.0us   0.0us  0.00  0.00    0                  Dummy-Driver
S   29      0      0    ---     ---   ---   ---     0                  Freewheel-Driver
S   36      0      0    ---     ---   ---   ---     0                  Midi-Bridge
R   46   2048  96000  71.1us  48.4us  0.00  0.00    0    S24LE 2 96000 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   84   1024  44100   9.3us  47.2us  0.00  0.00    0    F32LE 2 44100  + ALSA plug-in [cs2]

EDIT: Well.. using alsa fixes the audio delay for me but now causes crackling/popping audio and this seen in console:

[SoundSystemLowLevel] Increased audio mix latency to 8 buffers
[SoundSystemLowLevel] Audio device starved 512 samples
...

Which is a similar issue in DOTA2 apparently: https://github.com/ValveSoftware/Dota-2/issues/2425

No amount of SDL_AUDIO_ALSA_SET_PERIOD_SIZE and/or SDL_AUDIO_ALSA_SET_BUFFER_SIZE seems to help there.

candreacchio commented 1 year ago

Unsure if this is related, but if i play a few games, or leave cs open for a while, it starts to become more and more out of sync

icculus commented 1 year ago

Did you mean "forced pipewire" with this? SDL_AUDIODRIVER=pipewire ?

(It's SDL_AUDIO_DRIVER, extra underscore, in SDL3. SDL_AUDIODRIVER is ignored.)

szmarczak commented 1 year ago

Tested the latest update, the issue is still present.

Cutaneus commented 1 year ago

I have the same problem on Kubuntu 22.04 (Ryzen 5600x, AMD Radeon 6700XT, flatpak steam) If the sound has started to lag, then switching sound devices in the game settings helps (choose another sound card, then back)

af7567 commented 1 year ago

I am also getting delayed sound after about 20 rounds played in the latest update with pipewire. Also ALSA is very broken too now which is why I had to quickly swap to pipewire.

With -sdlaudiodriver alsa I am now getting these messages in the console like others had previously.

[SoundSystemLowLevel] Audio device starved 512 samples 
[SoundSystemLowLevel] Increased audio mix latency to 8 buffers
[SoundSystemLowLevel] Audio device starved 512 samples 

CS2 now seems to be ignoring my system alsa settings and forcing alsa to use the pulseaudio output plugin. Not sure if that is the reason for the bad audio now, or if some other SDL ALSA changes are causing it. Technically it should be fine using the pulseaudio alsa plugin :)

edit: I can use AUDIODEV="hw:0" which tells CS2 to use the soundcard instead of alsa-pulse but that now doesn't work since the device is busy - which makes sense becuase pipewire is running and steam has been using that for the mic. So now it seems like I only had it working before with alsa output by fluke :) But I was able to test CS with proper alsa output and that didn't have the audio device starved problem, so that is caused by using alsa-pulse.

ipaqmaster commented 1 year ago

A quick-fix without having to leave the match and waste a timeout is to go to sound options and change the sound device to anything else then back to what it was to trigger a restart of the game's audio system.

There doesn't seem to be a snd_restart command exposed in cs2 right now.


I'm on Linux with pipewire and the game uses pipewire-pulse.

-sdlaudiodriver pipewire made cs2 show "Audio Disabled" in the sound options for another problem but using pulse fixed things up for the time being and is currently a launch argument I use.

My usb dac also defaults to 96khz as configured. I wonder if this is some form of mismatched rate issue as some of the above testing comments are trying to eliminate.

I will some testing tonight. It's a fun problem to troubleshoot because the game has to run for the desync to slowly make itself apparent as time goes on and the delay increases.

nadanke commented 1 year ago

My usb dac also defaults to 96khz as configured. I wonder if this is some form of mismatched rate issue as some of the above testing comments are trying to eliminate.

I have mine set to 192 kHz and am affected by this issue - is there anyone who has this issue with a 44.1/48 kHz DAC?

candreacchio commented 1 year ago

I have mine set to 44.1 kHz... still issues with delayed audio

kiwec commented 1 year ago

Using PULSE_LATENCY_MSEC=60 (or any other value) makes the game crash on the Valve logo for me. Still no workaround for this issue.

JacKeTUs commented 1 year ago

With latest update (2023/10/04) increasing delay issue is still present. Tried leave cs2 overnight (no alt-tabs, without pc hibernating, monitor is on): after 7 hours of "playing" delay became whole 5 seconds

Spacefish commented 1 year ago

Yep no fix yet.. wonder why this happens anyway.. as it hints at the game generating more audio frames than can be consumed / played back by pulse.. So the game must be using another clock source / a internally generated synthetic clock source which is different from the Pulse audio ones..

Guess pulse will use the clock / synchronize to the clock of the hardware playback device if there is only one..

ipaqmaster commented 1 year ago

I run wireplumber with pipewire-pulse also present. Using -sdlaudiodriver with "pipewire" or "jack" causes CS2 to claim Audio Disabled

Played again tonight [Build: Oct 4 14:36:50] with -sdlaudiodriver pulse set and the delays started happening quickly by the end of the first round.

Glancing to my left, I notice my DAC is currently lit up yellow which is 96khz+ mode tonight. Usually Spotify causes this to pull down at some point but not this time.

Here is my DAC's sink information from pactl list sinks and underneath, CS2's presence under sink-inputs

pactl list sinks shows my FiiO K3 DAC with the below state (trimmed):

Show DAC sink ``` Sink #60 State: RUNNING Name: alsa_output.usb-FiiO_K3-00.pro-output-0 Description: K3 Pro Driver: PipeWire Sample Specification: s32le 2ch 96000Hz Channel Map: aux0,aux1 Mute: no Volume: aux0: 32759 / 50% / -18.07 dB, aux1: 32759 / 50% / -18.07 dB balance 0.00 Base Volume: 65536 / 100% / 0.00 dB Monitor Source: alsa_output.usb-FiiO_K3-00.pro-output-0.monitor Latency: 0 usec, configured 0 usec Flags: HARDWARE DECIBEL_VOLUME LATENCY Properties: alsa.card_name = "K3" alsa.driver_name = "snd_usb_audio" alsa.name = "USB Audio" alsa.resolution_bits = "32" api.alsa.card.longname = "FiiO K3 at usb-0000:0b:00.3-4.2.4, high speed" api.alsa.card.name = "K3" api.alsa.pcm.stream = "playback" audio.position = "AUX0,AUX1" device.api = "alsa" device.profile.name = "pro-output-0" device.profile.pro = "true" factory.name = "api.alsa.pcm.sink" node.pause-on-idle = "false" session.suspend-timeout-seconds = "0" clock.quantum-limit = "8192" node.max-latency = "16384/96000" device.bus-id = "usb-FiiO_K3-00" device.name = "alsa_card.usb-FiiO_K3-00" device.vendor.name = "FiiO Electronics Technology" Formats: pcm ```

pactl list sink-inputs has CS2 in it with this below state (trimmed):

Show CS2 sink-input ``` Sink Input #3606 Driver: PipeWire Owner Module: n/a Client: 2904 Sink: 60 Sample Specification: s32le 2ch 96000Hz Channel Map: front-left,front-right Format: pcm, format.sample_format = "\"s32le\"" format.rate = "96000" format.channels = "2" format.channel_map = "\"front-left,front-right\"" Corked: no Mute: no Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB balance 0.00 Buffer Latency: 0 usec Sink Latency: 0 usec Resample method: PipeWire Properties: client.api = "pipewire-pulse" pulse.server.type = "unix" application.process.id = "592824" application.process.binary = "cs2" application.name = "cs2" node.rate = "1/96000" node.latency = "960/96000" target.object = "alsa_output.usb-FiiO_K3-00.pro-output-0" stream.is-live = "true" node.want-driver = "true" resample.quality = "10" node.autoconnect = "true" node.dont-reconnect = "true" media.class = "Stream/Output/Audio" clock.quantum-limit = "8192" factory.mode = "split" library.name = "audioconvert/libspa-audioconvert" object.serial = "3606" pulse.attr.maxlength = "4194304" pulse.attr.tlength = "23040" pulse.attr.prebuf = "15368" pulse.attr.minreq = "7680" module-stream-restore.id = "sink-input-by-application-name:cs2" ```

Their rate's match so I can only imagine this is a lower level inconsistency or problem the game is experiencing in the sound department. For the time being the Default Device > DAC > Default Device trick is resetting this for me. I just have to remember to do it each round.

nadanke commented 1 year ago

I just tested with my DAC set to 48kHz using the following in pipewire.conf:

context.properties = {
  ...
  default.clock.rate = 48000
}

and it seems to have fixed the problem. I played a round of deathmatch with it with no noticeable delay. Afterwards I set the DAC back to 192kHz, started another round, and had a little bit of delay immediately, which became very noticeable after a few minutes. Can anyone else try?

livkx commented 1 year ago

I just tested with my DAC set to 48kHz using the following in pipewire.conf:

context.properties = {
  ...
  default.clock.rate = 48000
}

and it seems to have fixed the problem. I played a round of deathmatch with it with no noticeable delay. Afterwards I set the DAC back to 192kHz, started another round, and had a little bit of delay immediately, which became very noticeable after a few minutes. Can anyone else try?

I was already running at 48K and I have the issue still. Only workaround for me is to change audio device in-game and then back again when I start to notice issues (after about 15-20 mins maybe)

ipaqmaster commented 1 year ago

I'll have a go later too. Last night was noticeably much worse and sooner (a single round for half a seconds delay) than a few days ago - and the dac was in 96khz mode. Will test forcing 48000 just to check if the problem arises slower.

af7567 commented 1 year ago

I just played a couple of games now using the default pulse output and after about 20 rounds the delay was still too much to be able to play (no idea how many ms that is though :) ). My sample rate has always been at 48000

icculus commented 1 year ago

Okay, we need to figure out if this is a CS2 problem, an SDL problem, or a PipeWire problem.

So, to sanity check:

Someone load a video in something that definitely uses PipeWire and see if it desyncs after some time (if it does, it's either PipeWire or the hardware in use, if it doesn't, it's either SDL or CS2).

Someone get their system to play CS2 through PulseAudio (AND NOT THE PULSE-PIPEWIRE BRIDGE) and make sure it's not still happening (if it still is, it's either CS2 or SDL generally, if not, it's SDL's PipeWire code).

At this moment, I believe our Pulse code is most likely to be the most battle-tested.

What the problem actually sounds like from here: something (possibly SDL) is resampling slightly incorrectly, so a few frames here and there adds up quickly--especially at 192KHz--so the game is feeding the right amount of audio but over time it is drifting as we convert to have a few more samples than expected, accumulating. It probably doesn't even sound wrong!

xstaticxgpx commented 1 year ago

I think it's worth noting that this issue is infuriating to iterate on because, normally, you may not notice it until it's really bad after 20 minutes. @JacKeTUs made a solid effort trying to quantify this previously by measuring the actual mouse click and sound from the game.

Practically though, what I found to work the best was to just spam rifles and watch the ammo in HUD and listen for the low ammo clicks. The AK clicks at 5, m4a1 at 4, etc - if you just watch the ammo and listen for the click-click-click it becomes pretty apparent only 3-4 minutes into any game, in my experience.

I've had some seemingly great success by doing this, I'm not noticing the same extreme delay creeping up after some extended play now:

PIPEWIRE_DEBUG=T PIPEWIRE_LOG=/tmp/pipewire-cs2.log PIPEWIRE_RATE=1/44100 PIPEWIRE_LATENCY=256/96000 %command% -sdlaudiodriver pipewire -vulkan -novid -nojoy +exec autoexec.cfg

Those are all described here: https://github.com/PipeWire/pipewire#usage

The trace logs enabled there didn't really report much of interest AFAICT - and it doesn't generate a huge amount FWIW: https://gist.github.com/xstaticxgpx/631663179bf9c5626bd303297f315660

The PIPEWIRE_RATE is certainly taking affect as seen by pw-top:

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
I   28      0      0   0.0us   0.0us  0.00  0.00    0                  Dummy-Driver
S   29      0      0    ---     ---   ---   ---     0                  Freewheel-Driver
S   37      0      0    ---     ---   ---   ---     0                  Midi-Bridge
R   47    256  96000  25.5us   4.6us  0.01  0.00    0    S24LE 2 96000 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   52    256  44100  12.5us   2.2us  0.00  0.00    1    F32LE 2 96000  + Audio Stream

(note the rate column - it will always be resampled to the sink ultimately AFAIK)

I didn't need to change any of my existing pipewire/wireplumber/blah/blah/blah configs for this and so far I'm not seeing the same almost-immediately-noticeable audio delay.

Personally wouldn't be surprised if just the trace logs enabled had some effect :laughing:

Also under pipewire cs2 shows up as generic "Audio Stream" or "SDL Application" as seen above - that could also be partly fixed by adding this envvar too (the app should definitely be doing this somehow, both alsa/pulse seem to show up as "cs2")

SDL_AUDIO_DEVICE_STREAM_NAME="cs2"

It probably doesn't even sound wrong!

Indeed for me it never sounded garbled or malformed or crackly/underruns (only on alsa as noted above), just delayed.

EDIT: The delay still seems to come back after some time :( There's a noticeable hitch during end-of-round that creates audible stuttering FWIW.

JacKeTUs commented 1 year ago

Someone load a video in something that definitely uses PipeWire and see if it desyncs after some time

For first - is pipewire-alsa okay? Or we strictly need to check native Pipewire applications, which are not using SDL? As i just uncovered, osu!lazer uses BASS libraries, which does not support native Pipewire, but only through ALSA, so pw-mon looks like that:

pw-mon of osu! ``` added: id: 125 permissions: rwxm- type: PipeWire:Interface:Client (version 3) properties: pipewire.protocol = "protocol-native" pipewire.sec.pid = "67197" pipewire.sec.uid = "1000" pipewire.sec.gid = "1000" module.id = "2" object.id = "125" object.serial = "1146" remote.name = "pipewire-0" application.name = "PipeWire ALSA [osu!]" node.name = "alsa_playback.osu!" node.description = "ALSA Playback [osu!]" media.name = "ALSA Playback" media.type = "Audio" media.category = "Playback" config.name = "client-rt.conf" client.api = "alsa" log.level = "0" cpu.max-align = "32" default.clock.rate = "48000" default.clock.quantum = "1024" default.clock.min-quantum = "32" default.clock.max-quantum = "2048" default.clock.quantum-limit = "8192" default.video.width = "640" default.video.height = "480" default.video.rate.num = "25" default.video.rate.denom = "1" clock.power-of-two-quantum = "true" link.max-buffers = "64" mem.warn-mlock = "false" mem.allow-mlock = "true" settings.check-quantum = "false" settings.check-rate = "false" application.process.binary = "osu!" application.language = "en_US.UTF-8" application.process.id = "67197" application.process.user = "oleg" application.process.host = "home-pc" application.process.session-id = "3" window.x11.display = ":1" core.version = "0.3.80" core.name = "pipewire-oleg-67197" pipewire.access = "unrestricted" ```

But latency didn't increase, i have an hour of gameplay with no issues. Also there is no increasing latency if i use the game over Pulseaudio or JACK (both being rerouted to Pipewire through compatibility layers)

Also, fun thing - someone tried to implement SDL2 audio backend in osu and there was no increasing latency with native Pipewire with SDL2 as dev reports

IMO - it's not Pipewire issue, and not SDL2. May be SDL3 is responsible? :thinking:

I'll try to find proper native Pipewire application to test it again :smile:

af7567 commented 1 year ago

I just tested CS2 with no launch options and using real pulseaudio and after 90 minutes didn't have any delay at all BUT I wasn't playing normally. I just started up deathmatch and occasionally went in game to shoot some bots and change maps. Another thing is I had my monitor set to 60Hz but when I actually play I have it at 144Hz, don't know if that could have any effect. I will have to try tonight properly with pulseaudio to see how it goes.

So far I have:

edit: pipewire has seemed to be fine with everything else on my system, but the only long running things I used recently were Kodi and Mafia 3 where the delay wouldn't be as noticeable as in CS.

kiwec commented 1 year ago

Jank workaround for Pipewire:

Change the audio device to whatever you're using (you can see it by typing sound_device_override into the console).

fortunefox commented 1 year ago

Can confirm the issue as well. After maybe 40 minutes of gameplay, the delay becomes unbearable, and I have to restart the game. Using PulseAudio makes it worse, so I've stuck to Pipewire for now. The issue still occurs, of course.

OS: Linux Mint 21.2
Kernel: 6.5.5-2-liquorix-amd64
Graphics Platform: X11
CPU: AMD Ryzen 7 3700X (16)
Memory: 31,3 GiB of RAM
GPU: NVIDIA GeForce RTX 2080 SUPER 
Driver Version: 535.113.01 
icculus commented 1 year ago

Using PulseAudio makes it worse

But are you using PulseAudio through PipeWire's compatibility layer, or actual PulseAudio?

icculus commented 1 year ago

Further testing on my side: converted a 25-minute WAV file from 44100Hz to 192000Hz using SDL3's resampler, both as one giant block and streamed as 4 kilobyte chunks; the resampled audio matched to the millisecond, so it doesn't appear to be SDL3's new resampler adding extra samples over time, which was the most obvious culprit.

This does seem to be PipeWire-specific (or at least, PipeWire adjacent, like Pulse->Pipe compatibility layers), but I'm having trouble sifting through all the bug reports to confirm if that's actually true.

If so, it might still be SDL's pipewire backend (likely), or PipeWire itself (unlikely?), or CS2 itself (...unlikely...?).

af7567 commented 1 year ago

CS2 uses pipewire 0.3.65 but I (and others) have pipewire 0.3.80 on our systems, I wondered if that could be causing a problem even though they are ABI/API compatible. 0.3.65 is from January and it looks like there has been a lot of pipewire changes since then.

edit: I tried getting CS2 to use my pipewire 0.3.80 libs but it didn't like that, so what I have now from testing different audio drivers is

BAD

GOOD

In all cases the mic input is done by steam client using pulseaudio/pipewire-pulse.

I'm not sure the problem is SDL's pipewire backend though, since pulse output through pipewire-pulse will be using the SDL pulseaudio backend. It seems to be more a problem of CS2 pipewire stuff sending data to the system pipewire.

targotargo commented 1 year ago

I'm not sure if this is diagnostically relevant to any of you guys, but a number of us Windows folks are having the exact same problem with delayed audio that happens sooner with a higher sample rate and the workarounds for it are identical to yours. Buffer size doesn't seem to be relevant in my testing. The thing we all have in common is that we all use MOTU M Series audio interfaces. Could just be a coincidence, but I'm just mentioning it on the off chance that you may find it helpful to know.

xstaticxgpx commented 1 year ago

GOOD

* sdlaudiodriver alsa AUDIODEV=hw:0

I couldn't get that to work on my end (with the envvar) - no sound at all, even with trying hw:1 which is what my DAC maps to under aplay -l (card 1, device 0)

Trying to get cs2 to actually output 44100 rate in the "format" seems to require additional steps on my end:

I believe this is what we want to see in pw-top:

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
R   47    128  44100  18.7us   4.3us  0.01  0.00    0    S24LE 2 44100 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   52    128  44100   8.2us   6.5us  0.00  0.00    0    F32LE 2 44100  + cs2

The rate and output formats all match in frequency.

In order to get there I had to take several steps:

  1. add pulse.rules config for cs2:

    cat <<_EOF >~/.config/pipewire/pipewire-pulse.conf.d/01-cs2.conf
    pulse.rules = [
    {
        matches = [
            {
                application.process.binary = "cs2"
            }
        ]
        actions = {
            update-props = {
                node.latency       = 128/44100
                node.rate          = 1/44100
                node.quantum       = 128/44100
                node.lock-quantum  = true
                node.force-quantum = 128
            }
        }
    }
    ]
    _EOF
  2. Restart services

    systemctl --user restart pipewire.socket pipewire-pulse.socket wireplumber.service

But... the rate is never applied, and ultimately it looks like this (note quantum settings are applied):

# 52 is the cs2 id under "Streams"
$ wpctl inspect 52 | grep -E 'cs2|quantum|rate|latency'
  * application.name = "cs2"
    application.process.binary = "cs2"
    clock.quantum-limit = "8192"
    node.force-quantum = "128"
    node.latency = "512/96000"
    node.lock-quantum = "true"
  * node.name = "cs2"
    node.quantum = "128/44100"
    node.rate = "1/96000"

# Including firefox for comparison
S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
R   47    128  44100  34.6us   4.7us  0.01  0.00    0    S24LE 2 44100 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   52    128  96000   6.1us  13.9us  0.00  0.00    0    F32LE 2 96000  + cs2
R   58   3600  48000  20.6us   9.3us  0.01  0.00    0    F32LE 2 48000  + Firefox Developer Edition
  1. Now - before running the game - force pipewire frequency across the board, including for the sinks:
    pw-metadata -n settings 0 clock.allowed-rates '[ 44100 ]'
    pw-metadata -n settings 0 clock.rate 44100
    pw-metadata -n settings 0 clock.force-rate 44100
    # To verify
    pw-metadata -n settings

these settings apply immediately and last until you restart the services - so do the config stuff above first ^ the sink may not update immediately in pw-top :confused: Ah, after it gets a stream it'll update...

However it's still output FORMAT 96KHz from the client - which makes no sense, where is it even getting that now?

S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
R   47    128  44100  33.8us   9.3us  0.01  0.00    0    S24LE 2 44100 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
R   52    512  96000  10.3us  14.1us  0.00  0.00    0    F32LE 2 96000  + cs2

(I tried reverting the 01-cs2.conf here hence the higher quantum - I'm still not sure that does anything)

  1. Ok...now, let's try re-adding the PULSEAUDIO_LATENCY envvar...
    # PULSEAUDIO_LATENCY=128/44100 %command% -vulkan -novid -nojoy +exec autoexec.cfg
    S   ID  QUANT   RATE    WAIT    BUSY   W/Q   B/Q  ERR FORMAT           NAME
    R   47    128  44100  18.7us   4.3us  0.01  0.00    0    S24LE 2 44100 alsa_output.usb-NuForce__Inc._NuForce___DAC_2-01.analog-stereo
    R   52    128  44100   8.2us   6.5us  0.00  0.00    0    F32LE 2 44100  + cs2

FINALLY this looks like what we want here. Matching rates across all columns.

There must be something I'm missing with the pulse.rules and/or some reason the game is still negotiating 96000 even when it's forced 44100.

FWIW, the sound does seem really good when I finally got it matching 44.1KHz like that. This issue is pretty deceptive though.

semyon2105 commented 1 year ago

I ended up forcing 44.1KHz sample rate in Pipewire (system-wide) and that appears to have solved the problem.

cat /etc/pipewire/pipewire.conf.d/10-default.conf

context.properties = {
    default.clock.allowed-rates = [ 44100 ]
    default.clock.rate = 44100
    default.clock.quantum = 256
    default.clock.max-quantum = 1024
}

No additional CS2 command-line args are needed in this case.

I do wish Valve fixed the latency issue with 48KHz as it's the de-facto standard sample rate for video playback and etc.

EDIT: -sdlaudiodriver pulse CS2 launch option might still be needed for this.