[openal] Convolution reverb

Chris Robinson chris.kcat at gmail.com
Tue Aug 25 20:53:30 EDT 2020


Hello,

I've been working on a new feature for OpenAL Soft, a convolution
reverb effect. An initial implementation is available in the git repo,
with an example (examples/alconvolve). I'm curious if there's any
desire to continue work on this, or what specific features may be
desired. Source for the effect and example are here, respectively:

https://github.com/kcat/openal-soft/blob/9dab2db3/alc/effects/convolution.cpp
https://github.com/kcat/openal-soft/blob/9dab2db3/examples/alconvolve.cpp

From a developer's perspective, there's some things to take note of.
The major one is that convolution reverb is more costly on both the CPU
and memory compared to standard or EAX reverb. There's still plenty of
room for improvement, but at least for the more "interesting" impulse
responses available, I don't imagine it'll win out on resources compared
to existing reverbs. It's also less flexible; it can't be panned, or
have other parameters (like decay time, hf/lf ratio, early reflection
and late reverb delay) adjusted*, given that it's working with a
precalculated impulse response. It's main benefit is that it's more
realistic since it's a direct real-life measurement of an environment's
response, rather than approximations based on algorithms.

* Panning could work by adjusting virtual output points, and the early
  reflection delay can be increased by adding a manual delay before
  convolution. These could be implemented if desired. The overall
  length (decay time and late reverb delay together) could also
  theoretically be scaled by applying a time-stretching process on the
  response, but direct adjustments to the impulse response can't
  reasonably occur smoothly. 

Additionally, sources that feed standard or EAX reverb automatically
have their send levels adjusted based on distance to provide a more
dynamic response model. With convolution reverb, this can't happen
since it doesn't have information about the decay rate of low, mid, and
high frequencies. Theoretically, the impulse response can be analyzed
to find out roughly what they may be, or an app could provide
approximate values separately. In either case, a source send filter can
be used to apply distance-based room adjustment manually instead.

There's also an issue that there's currently a fixed 512-sample delay
on the effect's output. I do have plans for fixing that, but it will
come with higher CPU consumption.


Using convolution reverb is pretty straight forward. Create an effect
with the AL_EFFECT_CONVOLUTION_REVERB_SOFT type, load an impulse
response sound into a standard buffer, then set the effect and buffer
onto an effect slot.

ALuint effect, buffer, slot;
...
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_CONVOLUTION_REVERB_SOFT);

alBufferData(buffer, ir_format, ir_data, ir_data_size, ir_samplerate);

/* This is now valid. Note that the buffer is kept referenced, just
 * like with a source, and thus can't be changed until unset or the
 * slot is deleted. Without a buffer, convolution will be silent.
 */
alAuxiliaryEffectSloti(slot, AL_BUFFER, buffer);
alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect);

Currently only mono and stereo buffer formats are supported, but the
plan is to support any channel configuration (using either panning or
direct channel mapping, I'm not quite sure how to work it yet). Any
sample rate (within reason) will work, and will get properly adjusted
for the mix.

One thing to watch out for is, at least with the impulse responses I've
tested, the result is really loud. I don't know if this is normal or if
there's a problem with the implementation, but you may want to turn
down the effect slot's gain:

/* More reasonable volume, but still a little loud? */
alAuxiliaryEffectSlotf(slot, AL_EFFECTSLOT_GAIN, 1.0f / 16.0f);


If there's any questions, feel free to ask. I'll be interested in how
well (or not well) it performs on various systems, and if you have
experience with convolution reverbs more generally, how its quality
holds up and what features would be expected. I would also be curious
to know if impulse responses for convolution reverb typically have the
initial 'dry' response omitted or not. It'd be kinda silly to have it,
but it's hard to tell.


More information about the openal mailing list