[openal] Configurable resampling quality

Chris Robinson chris.kcat at gmail.com
Wed Aug 20 20:42:50 EDT 2014


Something I've been thinking about on and off is a way for apps to 
specify the resampling quality used for sources, since there can be a 
bit of a quality vs performance trade-off depending on the system. For 
instance, with OpenAL Soft, there's the choice between nearest/point, 
linear, and cubic resampling, but the only way to choose is for the user 
to select one in a config file. But this doesn't take into account that 
some apps may be less demanding on the CPU so can use cubic (or better, 
if available), while others want to be able to conserve the CPU for 
other things on weaker systems, so would want linear or nearest.

Here's a few ideas I've had of tackling the problem.


1) A resample hint context state. Much like how OpenGL has

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

we could have

alHint(AL_RESAMPLE_HINT, AL_NICEST);

The problem with this, though, is that it gives very little control. 
You'd have AL_NICEST, AL_FASTEST, and AL_DONT_CARE, while an 
implementation could have many more resamplers available than just 'a 
good one' and 'a fast one'. I could maybe see this being extended with 
additional AL_NICER or AL_FASTER values, but it still feels limiting and 
obfuscating. It does, though, make things simple: do you care about 
quality or speed?


2) A resample type source/buffer property. Like how OpenGL has

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

we could have

alSourcei(sid, AL_RESAMPLE_FILTER, AL_LINEAR);

The obvious problem here is that it then requires an enum for each 
possible resampling method, and it would require or compel an 
implementation to have resamplers it may not otherwise want to. Of 
course, the benefit is that the app can know what it's getting.


3) A resample quality source/buffer property. Something different from 
OpenGL. In this way, an app would be able to query the number of 
resampler quality levels, and then set one. e.g.

ALint maxq = alGetInteger(AL_MAX_RESAMPLE_QUALITY);
...
alSourcei(sid, AL_RESAMPLE_QUALITY, value); // 0 <= value <= maxq

The quality value would be an implementation-dependent scale. That is, 
if implementation A has a max quality of 2 and implementation B has a 
max quality of 4, that does *not* mean B's max is better than A's, it 
just means B has more steps between its fastest and nicest resamplers).

This has the problem that the app can't know what exactly it's getting, 
but it does allow an implementation to expose all its available 
resamplers, and not be required or compelled to add what it doesn't want.


I think I'm leaning toward option 3 or 1. And even for 3, I'm wondering 
if it would be better as a context creation attribute since it could 
affect non-source things (like certain effects).

Anyone else have any thoughts? Any other option I may not have thought of?


More information about the openal mailing list