[openal] Configurable resampling quality
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
we could have
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