[openal] Alure 2.0
Chris Robinson
chris.kcat at gmail.com
Fri Oct 17 13:37:35 EDT 2014
Hey guys.
I've started work on the API rewrite I've had planned for Alure. As it's
a rewrite, no code using the old API will work, but I hope the changes
will be more functional and more extensible than the old API.
http://repo.or.cz/w/alure.git
The old API/code can be found in the alure-1.x branch, if you still need
it. The new API is still in progress; in particular it's missing a lot
of functionality, and what's there is subject to change. The reason I'm
showing it now is to get some feedback on the design. There's a few
examples provided that show how device enumeration and playback work.
Some points of note:
The API is C++ only. It should theoretically be possible to make a C
wrapper later if there's enough interest in it, but it's currently not
there.
It's intended more as a static library that gets included in the
application. A shared library is possible, but potential ABI breaks
caused by changing C++ classes has me wary.
The design is more of a C++ wrapper for OpenAL, with added utility for
file reading/decoding, buffer and source management, streaming, etc (as
opposed to the old API, which provided extra utility while you oterwise
used OpenAL directly).
The general idea is that you can get a buffer by simply doing:
alure::Buffer *buffer = context->getBuffer("somefile.ogg");
Calling that multiple times will give you back the same buffer so you're
not constantly loading in new copies. Additionally, you can create as
many Source objects as you want by simply doing
alure::Source *source = context->getSource();
regardless of how many sources the underlying implementation can handle;
it'll only use an OpenAL source while it's playing. Playing the source
is then as simple as
source->play(buffer);
Currently it'll throw an exception if you try to play too many
simultaneously, but I hope to add priority-based virtualization so that
it'll automatically cut off the least important sources so it can play
the most important.
Aside from feedback on the current design, I'm also looking for feedback
on how you'd like to see certain things implemented. For instance,
custom decoders.
Currently it is possible to define custom decoders by inheriting from
the alure::Decoder class, implementing the requisite methods, then
passing an instance of it in wherever the API wants a decoder. However,
creating managed buffers from this decoder isn't yet possible. Some
ideas I've had:
A method that takes a name and a decoder, e.g.
buffer = context->getBuffer("somename", my_decoder);
and if a buffer named "somename" doesn't exist, it creates one using the
decoder. The problem here is it requires having a decoder instantiated
even if the buffer is already loaded.
Alternatively, a callback can be registered for a particular name,
alure::Decoder *create_my_decoder(const char *name, void *userptr);
context->registerDecoder("somename", create_my_decoder, userptr);
and when you call context->getBuffer("somename"); it'll call
create_my_decoder("somename", userptr); as needed, to create a decoder
and fill the buffer. The problem here is it'll often mean the app has to
register most or all of their audio files, if it has files the default
decoder(s) can't handle.
The other possibility is to register a callback to a particular file
extension, or even a uri. So basically
context->registerDecoder("myuri", create_my_decoder, userptr);
then calling context->getBuffer("myuri://somename"); will call your
callback if the buffer doesn't already exist. The registration can be
stored per-context, per-device, or globally.
Sorry if this was long and rambly. But I'm interested in what you guys
think.
More information about the openal
mailing list