[openal] Alure 2.0

Chris Robinson chris.kcat at gmail.com
Sun Oct 19 16:07:17 EDT 2014

On 10/19/2014 06:58 AM, Lex wrote:
> Hi Chris,
> As I am currently evaluating freely available c++ openal wrappers, it
> was particularly interesting to look at alure 2.0. For some reason I did
> not observed it while googling the thing.

It's still quite new. I had just put it online not long before the 
announcement message. :)

> Answering your question about custom decoders interface:
> I like the option to pass decoder into getBuffer method. The problem
> about having decoder instantiated can be avoided by having
> DecoderFactory, which getBuffer code will ask to create a real decoder
> if it needs to.

Not a bad idea. Though I think the idea of passing in a decoder or 
decoder factory to the getBuffer method is inherently problematic. It 
would be possible to specify a name and factory to getBuffer in one 
place, and in another place specify the same name with a different 
factory, and the one that gets used to load it depends entirely on which 
is called first. That doesn't feel very intuitive to me.

> Another option (which is not mutually exclusive with
> previous IMO) is that client has a way to register their decoders, and
> each decoder has 'recognize' method which get passed stream of data and
> which reads signature or whatever and returns a bool flag indicating
> whether it can decode this stream or not.

This is a possibility. The main thing with this is, how much data should 
be passed in for the decoder to check? Or should the methods just be 
given an abstract i/o object (e.g. an std::istream&), and it reads 
however much it wants?

> Additional random notes that came to mind:
> * it would be great if library had abstractions for disk i/o, since
> games, for example, often have proprietary resource package format.

Currently the decoder itself handles disk i/o. Since I imagine that most 
games will be using their own decoders as well, it could just implement 
them with whatever i/o methods they use. Having the i/o separate, and 
using virtual i/o in the decoders, is a possibility though.

> * efx support

Certainly planned. Still need to get standard AL fully supported first, 

> * why disposing buffers / sources have to deal with context->finalize?
> it may be handled in the appropriate desttructors.

It's possible for those methods to throw exceptions in some situations, 
e.g. trying to remove/delete a buffer that's still in use or if an 
inappropriate context is current at the time. You can't throw from 
destructors, the app will just terminate if an exception tries to leave 
the function.

It's also possible that certain objects, such as Sources, aren't 
actually deleted right away, but are instead held in a vector where they 
can be reused the next time one is requested, thus avoiding unnecessary 

> * Do you *really* have to use RTTI (dynamic_cast) in the library?

It was the easiest way to handle using abstract interfaces in user code 
(so as to not expose implementation details), while internally allowing 
the library to use the implementation classes directly so it can access 
implementation-specific methods and details (and theoretically avoid 
calling through the vtable thanks to C++11's 'final' keyword).

There are a few ways I can think of to avoid it, though. One is to 
simply assume the object is the correct type and use static_cast instead 
of dynamic_cast. Other than with the Decoder, an app shouldn't be 
inheriting from those classes, though I don't know of a way to prevent 
it while still allowing the lib to inherit from them.

Another way is to add a protected virtual getImplementation() method, 
which effectively returns itself as a pointer to the implementation 
class type.

A third option is to use the pImpl paradigm instead of a virtual 
interface. I'm not sure how I feel about that, though.

On another subject, something else for consideration is whether the 
interface should rely on C++11. It could be useful for some aspects of 
the API to use things like unique_ptr, and at least internally using 
auto and lambdas would be nice. Currently the implementation just uses 
C++11 when available, but tries not to require it (though I think the 
enumeration example uses for-range loops; I'll fix that if needed).

Something else that's come to mind. Should listener properties be set 
through the context, or through a listener object? i.e. like this:

ctx->setListenerPosition(x, y, z);

or this:

alure::Listener *listener = ctx->getListener();
listener->setPosition(x, y, z);

Having a separate listener object makes the most sense to me from an 
object orientation standpoint, but there's always and ever only one 
listener per context, so it seems a bit redundant.

Thanks for the feedback so far! :)

More information about the openal mailing list