alsa-project / alsa-lib

The Advanced Linux Sound Architecture (ALSA) - library
GNU Lesser General Public License v2.1
368 stars 177 forks source link

alsa-lib 1.2.2 breaks Shovel Knight, 1.2.1.2 is still working. #27

Closed DarkWav closed 4 years ago

DarkWav commented 4 years ago

So, today after upgrading to alsa-lib 1.2.2 I noticed the game "Shovel Knight" does no longer launch. Any Ideas why this could be happening? Sadly steam or the game executable won't provide any usable debug info when looking at terminal output :( . Can I maybe use GDB to gather more info or is that useless in this case?

perexg commented 4 years ago

There are no many changes in the code except topology and UCM which probably the game does not use. If you can compile the alsa-lib code from sources, try to bisect the change which causes this regression.

DarkWav commented 4 years ago

So after some testing I found out commit 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c is the faulty one here. When doing git reset --hard ebdd2b6cdb8119cf75f0dd0a3b283d271b3a547e before compilation shovel knight works fine. When doing git reset --hard 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c shovel knight breaks. I cannot revert the commit on its own with git revert --no-edit 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c because of merge conflicts but the changes are really small so It shouldn't be too hard.

perexg commented 4 years ago

What's difference between 'aplay -L' and 'aplay -L' output with and without this change on your system?

perexg commented 4 years ago

You should revert 6055f8a584296abfc0cec0439ceb708f0eddcc9d and 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c (in this order).

DarkWav commented 4 years ago

My system locale unfortunately is german, some quick translations: "Gerät" == "Device", "Karte" == "Card" aplay -L (without change):

Liste der Hardware-Geräte (PLAYBACK) Karte 0: PCH [HDA Intel PCH], Gerät 0: ALC1220 Analog [ALC1220 Analog] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 0: PCH [HDA Intel PCH], Gerät 1: ALC1220 Digital [ALC1220 Digital] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 3: HDMI 0 [HDMI 0] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 7: HDMI 1 [HDMI 1] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 8: HDMI 2 [HDMI 2] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 9: HDMI 3 [HDMI 3] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 10: HDMI 4 [HDMI 4] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 11: HDMI 5 [HDMI 5] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 12: HDMI 6 [HDMI 6] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0

aplay -L (with change):

Liste der Hardware-Geräte (PLAYBACK) Karte 0: PCH [HDA Intel PCH], Gerät 0: ALC1220 Analog [ALC1220 Analog] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 0: PCH [HDA Intel PCH], Gerät 1: ALC1220 Digital [ALC1220 Digital] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 3: HDMI 0 [HDMI 0] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 7: HDMI 1 [HDMI 1] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 8: HDMI 2 [HDMI 2] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 9: HDMI 3 [HDMI 3] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 10: HDMI 4 [HDMI 4] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 11: HDMI 5 [HDMI 5] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0 Karte 1: NVidia [HDA NVidia], Gerät 12: HDMI 6 [HDMI 6] Sub-Geräte: 1/1 Sub-Gerät #0: subdevice #0

Seems pretty Identical if you ask me. And reverting 6055f8a584296abfc0cec0439ceb708f0eddcc9d and 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c does work nicely, thanks!

perexg commented 4 years ago

Please use upper letter -L not -l as the aplay argument.

DarkWav commented 4 years ago

aplay -L (without change, shovel knight is working):

null Discard all samples (playback) or generate zero samples (capture) jack JACK Audio Connection Kit default Default ALSA Output (currently PulseAudio Sound Server) sysdefault:CARD=PCH HDA Intel PCH, ALC1220 Analog Default Audio Device front:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog Front speakers surround21:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 2.1 Surround output to Front and Subwoofer speakers surround40:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.0 Surround output to Front and Rear speakers surround41:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.1 Surround output to Front, Rear and Subwoofer speakers surround50:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.0 Surround output to Front, Center and Rear speakers surround51:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers iec958:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Digital IEC958 (S/PDIF) Digital Audio Output usbstream:CARD=PCH HDA Intel PCH USB Stream Output hdmi:CARD=NVidia,DEV=0 HDA NVidia, HDMI 0 HDMI Audio Output hdmi:CARD=NVidia,DEV=1 HDA NVidia, HDMI 1 HDMI Audio Output hdmi:CARD=NVidia,DEV=2 HDA NVidia, HDMI 2 HDMI Audio Output hdmi:CARD=NVidia,DEV=3 HDA NVidia, HDMI 3 HDMI Audio Output hdmi:CARD=NVidia,DEV=4 HDA NVidia, HDMI 4 HDMI Audio Output hdmi:CARD=NVidia,DEV=5 HDA NVidia, HDMI 5 HDMI Audio Output hdmi:CARD=NVidia,DEV=6 HDA NVidia, HDMI 6 HDMI Audio Output usbstream:CARD=NVidia HDA NVidia USB Stream Output

aplay -L (with change, shovel knight is broken):

surround21 2.1 Surround output to Front and Subwoofer speakers surround40 4.0 Surround output to Front and Rear speakers surround41 4.1 Surround output to Front, Rear and Subwoofer speakers surround50 5.0 Surround output to Front, Center and Rear speakers surround51 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers null Discard all samples (playback) or generate zero samples (capture) samplerate Rate Converter Plugin Using Samplerate Library speexrate Rate Converter Plugin Using Speex Resampler jack JACK Audio Connection Kit oss Open Sound System pulse PulseAudio Sound Server speex Plugin using Speex DSP (resample, agc, denoise, echo, dereverb) upmix Plugin for channel upmix (4,6,8) vdownmix Plugin for channel downmix (stereo) with a simple spacialization default Default ALSA Output (currently PulseAudio Sound Server) sysdefault:CARD=PCH HDA Intel PCH, ALC1220 Analog Default Audio Device front:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog Front speakers surround21:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 2.1 Surround output to Front and Subwoofer speakers surround40:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.0 Surround output to Front and Rear speakers surround41:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.1 Surround output to Front, Rear and Subwoofer speakers surround50:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.0 Surround output to Front, Center and Rear speakers surround51:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers iec958:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Digital IEC958 (S/PDIF) Digital Audio Output usbstream:CARD=PCH HDA Intel PCH USB Stream Output hdmi:CARD=NVidia,DEV=0 HDA NVidia, HDMI 0 HDMI Audio Output hdmi:CARD=NVidia,DEV=1 HDA NVidia, HDMI 1 HDMI Audio Output hdmi:CARD=NVidia,DEV=2 HDA NVidia, HDMI 2 HDMI Audio Output hdmi:CARD=NVidia,DEV=3 HDA NVidia, HDMI 3 HDMI Audio Output hdmi:CARD=NVidia,DEV=4 HDA NVidia, HDMI 4 HDMI Audio Output hdmi:CARD=NVidia,DEV=5 HDA NVidia, HDMI 5 HDMI Audio Output hdmi:CARD=NVidia,DEV=6 HDA NVidia, HDMI 6 HDMI Audio Output usbstream:CARD=NVidia HDA NVidia USB Stream Output

Now there seem to be some intersting changes...

perexg commented 4 years ago

All is correct, so the question is what the game (or steam code) does. It seems that a wrong device is picked or so. You may use ALSA_CONFIG_DIR environment variable to override the ALSA configuration directory, but I don't know what the application expects.

DarkWav commented 4 years ago

So is it best to contact Yacht Club Games (the game's developers) about the regression? Or would reverting the change make more sense? Should I check or change my sound/ALSA configuration maybe? May it be helpful to delete/factory reset the global asound.state file?

DarkWav commented 4 years ago

After some testing I found out resetting asound.state or running alsactl --init does not help. I facory resetted all config files in existance, and no luck. It really seems like shovel knight somehow selects a wrong device, maybe one of these "surround" things. I will do further testing with unplugging my speakers, ect.

perexg commented 4 years ago

Try to comment (add # as the first character on the line) those lines in /usr/share/alsa/alsa.conf :

pcm.surround21 cards.pcm.surround21
pcm.surround40 cards.pcm.surround40
pcm.surround41 cards.pcm.surround41
pcm.surround50 cards.pcm.surround50
pcm.surround51 cards.pcm.surround51
pcm.surround71 cards.pcm.surround71
DarkWav commented 4 years ago

That worked flawlessly, now shovel knight is working fine again. Welp that's basically the proof that shovel knight is incorrectly selecting the souround stuff. Should I contact Yacht Club with that info, or is it possible to change the default config to make it work? I'll check if moving the entries down is also working.

perexg commented 4 years ago

Yes, it appears that it works if the null PCM device is first on the list. I would contact the game developer to fix that.

DarkWav commented 4 years ago

After some experimentation, I found out its not just the null device, it generally seems that those "extra surround" entries must not be before anything important or they'll get selected because with this aplay -L output shovel knight still crashes:

null Discard all samples (playback) or generate zero samples (capture) surround21 2.1 Surround output to Front and Subwoofer speakers surround40 4.0 Surround output to Front and Rear speakers surround41 4.1 Surround output to Front, Rear and Subwoofer speakers surround50 5.0 Surround output to Front, Center and Rear speakers surround51 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers samplerate Rate Converter Plugin Using Samplerate Library speexrate Rate Converter Plugin Using Speex Resampler jack JACK Audio Connection Kit oss Open Sound System pulse PulseAudio Sound Server speex Plugin using Speex DSP (resample, agc, denoise, echo, dereverb) upmix Plugin for channel upmix (4,6,8) vdownmix Plugin for channel downmix (stereo) with a simple spacialization default Default ALSA Output (currently PulseAudio Sound Server) sysdefault:CARD=PCH HDA Intel PCH, ALC1220 Analog Default Audio Device front:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog Front speakers iec958:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Digital IEC958 (S/PDIF) Digital Audio Output surround21:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 2.1 Surround output to Front and Subwoofer speakers surround40:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.0 Surround output to Front and Rear speakers surround41:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 4.1 Surround output to Front, Rear and Subwoofer speakers surround50:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.0 Surround output to Front, Center and Rear speakers surround51:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71:CARD=PCH,DEV=0 HDA Intel PCH, ALC1220 Analog 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers usbstream:CARD=PCH HDA Intel PCH USB Stream Output hdmi:CARD=NVidia,DEV=0 HDA NVidia, HDMI 0 HDMI Audio Output hdmi:CARD=NVidia,DEV=1 HDA NVidia, HDMI 1 HDMI Audio Output hdmi:CARD=NVidia,DEV=2 HDA NVidia, HDMI 2 HDMI Audio Output hdmi:CARD=NVidia,DEV=3 HDA NVidia, HDMI 3 HDMI Audio Output hdmi:CARD=NVidia,DEV=4 HDA NVidia, HDMI 4 HDMI Audio Output hdmi:CARD=NVidia,DEV=5 HDA NVidia, HDMI 5 HDMI Audio Output hdmi:CARD=NVidia,DEV=6 HDA NVidia, HDMI 6 HDMI Audio Output usbstream:CARD=NVidia HDA NVidia USB Stream Output

I belive the "surround" entries are some kind of "dead entries", before 1.2.2 aplay wouldn't even show them, now it does when not explicitly disabled in alsa.conf.

perexg commented 4 years ago

Those are shortcuts for the surround channel configuration. Those devices may not be available on all hw platforms (the open may return an error). Anyway, the application should not crash or so.. Report this.

perexg commented 4 years ago

And the 1.2.2 just fixed the listing of those devices (there were available, but just not listed because there was an bug in the enumeration routines - 5ee5ef31b5ff3fb7c904054cb9cac7478a727f7c).

DarkWav commented 4 years ago

Okay, thanks for your efforts, I really appreciate it. I will now contact Yacht Club Games via Support and tell them the issue. For now I will use the modified asound.conf to play the game, seems fine for a temporary solution. Since this obviously isn't really a bug in alsa-lib, I will close this issue now.

DarkWav commented 4 years ago

This change seems to have more drastic impact than I thought. Now many unity games like Pillars of Eternity, RaceTheSun, Ravenfield and Vaporum are affected for some people apparently: https://bbs.archlinux.org/viewtopic.php?pid=1889747#p1889747. Although being perfectly correct from a scientistic point of view, It might be more practical to move the newly detected devices to the bottom of the list to prevent crashes like this. Do you think there is a way to do so? I'll change the code a bit myself, and check if I can achieve something. By the way, Yacht Club Games reported they will take a look at the issue.

perexg commented 4 years ago

I basically don't know what those games trying to do.. If you have sources, I can look into. You may also trace the snd_pcm_open() calls.

DarkWav commented 4 years ago

The only good news is that I finally got some half-decent console output from shovel knight:

SaveManager::Init() Run Thread Save Thread Audio Drivers [ALSA]: 0 : default 1 : cards 2 : 3 : POF 4 : P�E 5 : �_G 6 : �lE 7 : null 8 : samplerate 9 : speexrate 10 : jack 11 : oss 12 : pulse 13 : speex 14 : upmix 15 : vdownmix 16 : sysdefault:CARD=PCH 17 : surround71:CARD=PCH,DEV=0 18 : iec958:CARD=PCH,DEV=0 19 : usbstream:CARD=PCH 20 : hdmi:CARD=NVidia,DEV=0 21 : hdmi:CARD=NVidia,DEV=1 22 : hdmi:CARD=NVidia,DEV=2 23 : hdmi:CARD=NVidia,DEV=3 24 : hdmi:CARD=NVidia,DEV=4 25 : hdmi:CARD=NVidia,DEV=5 26 : hdmi:CARD=NVidia,DEV=6 27 : usbstream:CARD=NVidia 28 : cards 29 : front 30 : rear 31 : center_lfe 32 : side 33 : surround21 34 : surround40 35 : surround41 36 : surround50 37 : surround51 38 : spdif 39 : dmix 40 : dsnoop 41 : modem 42 : phoneline 43 : hw 44 : plughw 45 : plug 46 : shm 47 : tee 48 : file 49 : !default selected driver: 0 double free or corruption (!prev) Aborted (core image dumped)

DarkWav commented 4 years ago

And numbers 2-6 always change their hieroglyphic letters every time I try to run the game, that's ultra sketchy. When I do the proper config file modifications, they just disappear! What is going on here?????

perexg commented 4 years ago

I changed the order of the devices in https://github.com/alsa-project/alsa-lib/commit/27c7927842a691ef13724cd16fb26264680c6aa2 . It makes sense to have the null device as first in the listing. But I am almost sure, that they have a problem in their audio device detection code - it looks like an access to the freed memory object or so...

DarkWav commented 4 years ago

Just tested, doesn't really help, but thanks anyways. I belive It's rather a problem of the sound devices with hieroglyphic letters appearing in the list generated by shovel knight. Any Idea why that could be happening?

perexg commented 4 years ago

.... it looks like an access to the freed memory object or so...

DarkWav commented 4 years ago

After further testing I found mainly the if-then-continue statement in lines 335 and 336 causes this problem. Lines 352 thru 354 work just fine. It almost seems like some none-audio devices are picked up. Like are samplerate and speexrate legit audio devices or is something unintended being detected here?

perexg commented 4 years ago

The problem is most probably in the application not in alsa-lib (malloc/free issue).

"speex" is valid device with "plug:hw" default backend - see /usr/share/alsa/alsa.conf.d/60-speex.conf .

DarkWav commented 4 years ago

The big issue we're facing at the moment is that the problem currently also affects almost every single game created with Unity3D as long as that game doesn't use PulseAudio but actually ALSA (you have to kill pulseaudio maunually) Even if Unity3D fixes the issue on their side, ALL games ever created with Unity3D for Linux would have to be re-compiled and the ones that don't will stay broken forever.

Therefore as dumb as it is its quite problematic to leave it as it is.

In some cases some functions (those returning the available alsa devices) seem to return abnormal characters as the name, resulting in those games to crash (by the way, I have once seen surround50 being returned correctly in fields 2-6). Maybe some character modifications are broken?

Like can we, when sound device lists are requested, prevent that devices with abnormal characters in their name are returned? I have to go for today, but a huge thanks for your efforts. DarkWav

perexg commented 4 years ago

I think that we are both talking about different things. I agree that there's an issue, but I cannot do much when I don't know, how the device list in the used library is composed. The changes which cause this application behaviour are in the snd_device_name_get_hint() alsa-lib function. This function can be debugged using 'aplay -L' and 'arecord -L', but I don't see those invalid strings with this type of test. The alsa-lib probably does not return (and should not return) them.

The debug output from the application suggests that the application does really weird things, because there are no devices like 'cards', '!default' etc. It seems that there's a mix of the strings returned from snd_device_name_get_hint() and the direct configuration file parsing. I am confused as you.

For now, there is at least workaround (modify alsa.conf), or alternatively, you may do this in the local ~/.asoundrc file:

cat >> ~/.asoundrc <<EOF
# hack for Unity3D games (wrong sound device probe)
pcm.!surround21 0
pcm.!surround40 0
pcm.!surround41 0
pcm.!surround50 0
pcm.!surround51 0
pcm.!surround71 0
EOF
DarkWav commented 4 years ago

OK, I'll investigate further tomorrow. It won't be an issue for the causal user since most games use PulseAudio when available so the games work, but fixing the problems is nevertheless a good idea IMO. Thanks

darktjm commented 4 years ago

I just posted this issue again to the mailing list. This change breaks almost all of my unity3d games. Sorry. I didn't think to check the open bugs (wasn't even sure where to look).

perexg commented 4 years ago

@darktjm : Thank you for cross posting. All bugs are mirrored to the alsa-devel mailing list automatically.

DarkWav commented 4 years ago

Maybe the games don't like that the surround devices are listed twice? Is there a way to prevent double listing in the code?

DarkWav commented 4 years ago

I think I finally found an acceptable solution. It allows all the devices newly detected in 1.2.2 to stay, just removes duplicate "surround" entries. What you need to do: Edit alsa default config revoke the "defaults" surround entries one they are linked to cards.pcm I created a pull request: https://github.com/alsa-project/alsa-lib/pull/30

perexg commented 4 years ago

It's not feasible solution in my eyes. You may add this to configuration to ~/.asoundrc as workaround, but we should not fix a bug with removing something what worked before. For example, the 'surround40' is valid device name. It tries to open the first sound card (card 0 device 0) in the default config with the 4.0 channel configuration.

But I see the duplicate (default arguments, explicit arguments). We may improve the code to not list the duplicated entries in the namehint function. Could you test this? https://github.com/alsa-project/alsa-lib/pull/31

DarkWav commented 4 years ago

Sadly #31 doesn't work, duplicate entries still exist. Are there any other ways we can hide the entries?

perexg commented 4 years ago

Ok, the condition was inverted (sorry). Could you try again?

perexg commented 4 years ago

Another problem found. This third version should work. I finally got a litle time to test it...

DarkWav commented 4 years ago

Yes, this works perfectly, thanks! Do you think its possible to merge that patch into the main repo?