[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