[BUG] createCapabilities fails despite alcOpenDevice((ByteBuffer)null) != NULL

Started by jakethesnake, September 10, 2021, 06:22:11

Previous topic - Next topic

jakethesnake

I have an issue on linux, where I get:

!java.lang.IllegalStateException: There is no OpenAL context current in the current thread or process.!

from this code:

device = ALC10.alcOpenDevice((ByteBuffer)null);
		if (device == MemoryUtil.NULL){
			throw new Errors.GameError("No OpenAL device could be found. Try enabling sound and or / plug in/out speakers/earphones or restart your computer.");
		}
		ALCCapabilities caps;
		try {
			caps = ALC.createCapabilities(device); // <- error!!!
			Source.posTransX = 1f/settings.getNativeWidth();
			Source.posTransY = 1f/settings.getNativeHeight();
			
			if (!caps.OpenALC10){
				throw new Errors.GameError("No OpenALC 10 support found. Make sure your computer has got this support. Try enabling sound and or / plug in/out speakers/earphones or restart your computer.");
			}
			context = ALC10.alcCreateContext(device, (IntBuffer)null);

			ALC10.alcMakeContextCurrent(context);
			AL.createCapabilities(caps);
			
		}catch(Throwable e) {
			e.printStackTrace();
			throw new Errors.GameError("No OpenALC 10 support found. Make sure your computer has got this support. Try enabling sound and or / plug in/out speakers/earphones or restart your computer.");
		}


It works on 99% of all platform configurations, but crashes on a linux user's setup. Any ideas?

jakethesnake

We did some bug hunting and managed to fix it by changing stuff in pulse audio.

https://wiki.archlinux.org/title/PulseAudio#OpenAL

What's weird is that he had apps running on lwjgl 2.0 working as expected.

Before applying the fix, we could do a lot of weird stuff. Listing devices through the openAL API only ever gave us a device called "JACK default", no matter how many there were. There was no such device on his PC. And by plugging in different amount of devices, we could get sound to play in different devices.

I looked into lwjgl 2.0 and it also has a OpenAL_64.so in addition to OpenAL.so. My app only extracts 1 OpenAL.so file. I'm guessing and hoping that this is 64 bits, or some kind of combination. Or maybe lwjgl 2.0 uses a different non-openal library if it can. Or maybe the lwjgl 2.0 app uses a different sound library all together.


spasi

LWJGL 3 doesn't support x86 Linux, that's why there's only one binary. The OpenAL Soft build that comes with LWJGL 2 is like a decade older, the implementation has changed a lot since then.

OpenAL Soft supports multiple backends on each operating system. When troubleshooting OpenAL issues, you can use environment variables to enable debugging messages, force a specific backend, etc. Reference here.

Btw, the code listing above notes that the error was happening on ALC.createCapabilities, which is wrong. That error message can only come from AL.createCapabilities. That probably means that alcCreateContext was failing for some reason, did you check alcGetError?

jakethesnake

Hey Spasi, thanks for having a look!

Here's the stacktrace:

java.lang.IllegalStateException: There is no OpenAL context current in the current thread or process.
	at org.lwjgl.openal.AL.createCapabilities(AL.java:159)
	at snake2d.SoundCore.<init>(SoundCore.java:55)
	at snake2d.CORE.create(CORE.java:97)
	at menu.Menu.start(Menu.java:53)
	at init.Main.main(Main.java:75)


So it is happening on createCapabilities unless I'm missing something. And that means that:

device = ALC10.alcOpenDevice((ByteBuffer)null);
		if (device == MemoryUtil.NULL){
			throw new Errors.GameError("No OpenAL device could be found. Try enabling sound and or / plug in/out speakers/earphones or restart your computer.");
		}


Passed, and  ALC10.alcOpenDevice((ByteBuffer)null) returned not NULL, and a device that apparently can't create a context? You mean I should do a alcGetError after alcOpenDevice, just to make sure?

I'm aware lwjgl wraps things and that it's probably an openal thing, but perhaps error handling could be wrong here??

spasi

Note that there are two createCapabilities calls; one on ALC and a second one on AL. It is the second one that fails. Which probably means that ALC10.alcCreateContext returns null and raises an error that can be checked with alcGetError. There is no error handling for this case.

Btw, I've never encountered a failing alcCreateContext before. That particular user's machine has broken audio configuration somehow and alcGetError might not be able to help. You'll probably have more luck identifying the issue with ALSOFT_LOGLEVEL=3.

jakethesnake

Oh, I didn't see it was the AL one, you're right, thanks again. I used your openal test over at github for trouble shooting and listing devices, we only got this "JACK default" device, which wasn't listed in the users system audio devices, perhaps it's some dummy the driver returns if there are no devices, I don't know. Editing config for "pulse audio", that I'm completely clueless about, seemed to turn everything back to normal.