[openal] API redesign for ease of use?

Chris Robinson chris.kcat at gmail.com
Tue Jul 28 23:47:48 EDT 2015


On 07/28/2015 10:30 AM, Victorious wrote:
> Hi,
>
> OpenAl-soft is currently compatible with the original OpenAl spec.
> Its c-style API is not as user-friendly as it could be; for example,
> having to know which variant of alSourcei, alSourcef, etc to use and
> constants to modify properties. Functions also don't return any
> errors encountered, requiring you to explicitly check for it.

The need for type-specific functions is an unavoidable issue since C 
doesn't have function overloading (well, C11 kind of does with _Generic, 
but support for that is unfortunately not good enough to rely on). C++ 
and the like can, but a wrapper can easily handle that... though if 
you're building a wrapper, you'd probably want it to be a bit higher level.

Functions not returning errors is an explicit design decision; the idea 
is you're not supposed to generate errors in the first place since the 
input parameters are known and their limits are well-defined (so rather 
than reacting to errors from bad input, just don't generate bad input). 
The only errors really out of your control is out-of-memory*, but at 
that point you're in deeper trouble than just with OpenAL.

* There is also potential unpredictable errors with source playback when 
sources use shared system resources, which should only really effect 
hardware drivers, but I do wish either the API or spec was cleaner about 
that.

Though if/when you check for errors, it would ideally be after a number 
of calls, like:

alSource3f(source, AL_POSITION, pos);
alSource3f(source, AL_DIRECTION, dir);
alSourcef(source, AL_GAIN, gain);
...
alSourcei(source, AL_BUFFER, buffer);
ALenum err = alGetError();
if(err != AL_NO_ERROR)
    oops();
alSourcePlay(source);

Similarly, when updating a property you're more than likely going to 
update more than one source (e.g. it's not likely only a single source 
will move in a frame), so it's much more efficient to do it after 
they've all been updated rather than checking each individual call.


For debug purposes, I agree that it's useful for more exact information. 
With OpenAL Soft, there is a feature that can be enabled with the 
ALSOFT_TRAP_ERROR environment variable. With that set to "1", it will 
generate a breakpoint exception (or SIGTRAP under non-Windows) within 
the call that made the error, which will cause a debugger to break. With 
a debug build of OpenAL Soft, you can then inspect the backtrace to see 
which specific call generated the error, as well as the input parameters 
that caused it.

A more generic solution, something like GL_KHR_debug, has been 
suggested, and someone was willing to write up an extension spec, but it 
hasn't been finished yet.

> http://camlorn.net/posts/april2014/shortcomings-of-openal.html

I'd agree with this in that having one error code per context is an 
issue when doing certain kinds of multi-threaded work. I'd like to make 
an extension that allows apps to enable thread-local errors, so one 
context would have different error states in different threads.

The (the lack of) callbacks has its own issues, though. In the given 
example of knowing when a source stops, there's the issue that a source 
becomes stopped in the mixer after its been mixed and its offset 
updated, and the mixer is not where you want to be running random user 
code. This means the event would have to be marshaled to a separate 
thread that deals solely with calling user code for such events.

Additionally, most user code likely won't appreciate being called at 
random times and in parallel to other code. This would necessitate 
either the event being marshaled again from the user callback to 
someplace the app can safely deal with it, or using mutex locks to 
protect what it needs to access, or ensuring the callbacks are called at 
a specific time.

This isn't to say there wouldn't be a benefit, but it would need some 
consideration between what can be realistically achieved, and what apps 
can efficiently work with.

> Has an API redesign been considered? How important would
> compatibility  with the spec be?

If compatibility is broken, then I'd prefer there to be a clean break 
with all aspects of the API reconsidered, as well as a change to the 
header and lib names so that both the old API and new could co-exist. 
Either that, or some kind of deprecation/compatibility mechanism like in 
OpenGL 3. Existing apps must continue to work, and it would be 
beneficial for new apps to select which they want to use.


More information about the openal mailing list