alGenSources throws OpenALException

Started by Sardtok, August 03, 2006, 17:08:44

Previous topic - Next topic

Sardtok

Hi,
I'm working on my sound framework,
and I try to generate as many sound sources as possible with a maximum number of 32 (actually it will try to generate more sources if it runs out of sources and playing a sound is requested).
Problem is, alGenSources throws an OpenALException:
Exception in thread "main" org.lwjgl.openal.OpenALException: OpenAL error: Invalid Value (40963)
        at org.lwjgl.openal.Util.checkALError(Util.java:56)
        at org.lwjgl.openal.AL10.alGenSources(AL10.java:719)
        at com.chickensoft.sound.SoundSystem.init(SoundSystem.java:108)
        at com.chickensoft.starcruiserclassic.StarcruiserClassic.init(StarcruiserClassic.java:376)
        at com.chickensoft.starcruiserclassic.StarcruiserClassic.<init>(StarcruiserClassic.java:123)
        at com.chickensoft.starcruiserclassic.StarcruiserClassic.main(StarcruiserClassic.java:186)

I think this happens because I try to generate too many sources(my sound card should be able to handle 128, but for some reason it won't generate more than 30), but I never get to my alGetError check, which is supposed to break out of the loop and stop generating sources.
I guess I could simply catch the exception and break out of the loop if it catches an OpenALException, same as what would happen if I did an alGetError check.
Basically I'm doing the exact same thing as in the Advanced Loading and Error Handles tutorial, except I try to generate as many sources as possible, and play whatever sound is requested to play on the first available source, instead of binding sounds to sources.

Not sure if this has changed in the 1.0 beta (2), as I'm still using .99.

Another minor thing, loading au files with WaveData gives some pretty weird distortion, I guess au isn't a supported format, but shouldn't create jsimply return null if it isn't?
I'm not going to use au sounds, but I just had an old au, that I wanted to use for testing, and it sounded kind of weird (not sure what it's called in English, but I think the wave gets cut at some point, and I end up with a square wave instead of a sawtooth or triangle wave which I think the sound currently is)..
igg -- Take me off for great justice?

Sormuras

Hello Sardtok,

afaik, the implementation regarding AL10.alGenSources didn't change between 0.99 and the current release. The AL10.alGenSources looks like this...
public static void alGenSources(IntBuffer sources) {
		BufferChecks.checkDirect(sources);
		nalGenSources((sources.remaining()), sources, sources.position());
		Util.checkALError();
	}

...and the Util.checkALError(); checks for an AL error and throws the unchecked OpenALException. So, it seems, that all AL10.alGenSources/Buffers calls should be wrapped by try-catch blocks. Same goes for AL10.alDeleteSources/Buffers.

Cheers,
Sor

darkprophet

I dont see why it should be wrapped. If OpenAL is throwing an error for some reason, then the user should deal with it...

Maybe its an OpenAL/Driver limit that it can't generate more than 30 sources at a time...

Sormuras

OpenAL doesn't throw an error by itself. It just sets an internal error state flag, which is checked by LWJGL and transformed into an exception object that is thrown against the user "silently" here. Whether the Java declaration, nor the javadoc of AL10.alGenSources() says something about it. Sure, the user should deal with it, but he can't handle it with the usual state-machine pattern:

machine.doSomething();
if (machine.isInErrorState()) {
  // handle error
}
machine.doSomethingElse();


Here, the user has to wrap the call in a try-catch-block:

try {
  machine.doSomething();
}
catch(RuntimeException e) {
  // handle error
}
machine.doSomethingElse();


If OpenALException wasn't derived from RuntimeException... but that's another story. See http://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html and many other links.

Cheers,
Sor

darkprophet

yes, i do realise the way OpenGL and OpenAL do their error handling; but im not sure that OpenAL/OpenGL does recover after an error has been flagged and carry on like business as usual...so it doesn't make sense to catch it and try again.

Also, every method could potentially flag an error, your not going to make every method throw an exception are you ?

DP

Sormuras

Sure not, otherwise you'll only code error/exception handling code. :)

And it depends on the kind of error. In case of AL10.alGenSources() it can make perfect sense to carry on as usual ... and Sardtok wonders why "never get to my alGetError check, which is supposed to break out of the loop and stop generating sources." And this happens because of Lightwights way to handle the situation. So, he has to proceed as proposed by himself: "I guess I could simply catch the exception and break out of the loop if it catches an OpenALException, same as what would happen if I did an alGetError check." I just noted, that if the method declared... never mind.

Cheers,
Sor