[openal] API redesign for ease of use?
chris.kcat at gmail.com
Tue Jul 28 23:47:48 EDT 2015
On 07/28/2015 10:30 AM, Victorious wrote:
> 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
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)
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.
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