[openal] UHJ support
Chris Robinson
chris.kcat at gmail.com
Thu Dec 9 03:18:20 EST 2021
For a while now, OpenAL Soft has had a user config option to have stereo
output be UHJ-encoded[1]. Since the audio is mixed internally as B-Format, an
option to output UHJ-encoded stereo that can be used as-is or decoded back to
surround sound seemed like a nice "easy" feature to have.
Some sources say UHJ is the "proper" way to derive stereo from an ambisonic
mix[2], with some also saying it sounds more spacious, with wider and more
stable sound imaging compared to panpot[3]. So even beyond being a nice easy
feature, it could be better for stereo output. OpenAL Soft does default to
panpot for stereo (unless headphones are detected where it'll use HRTF if
possible), but I have been thinking about either changing that or at least
somehow encouraging people to try UHJ for stereo speakers. I know people can
get a bit unhappy or off-put when audio starts sounding "different" from
expected, so changing the default may not be a great idea, but if it does
provide a better stereo experience for people willing to try it, along with
other benefits, I think that's a good thing.
[1] https://github.com/kcat/openal-soft/blob/a8ea3cad2274/alsoftrc.sample#L94
[2] https://wiki.xiph.org/Ambisonics#Default_channel_conversions_from_B-Format
[3] https://en.wikipedia.org/wiki/Ambisonic_UHJ_format#Undecoded_UHJ
Relatedly and more recently, I've also been playing around with an extension
to support UHJ buffer formats[4]. Since 2-channel UHJ is a nice way to provide
a stereo mix for surround sound content, which can be played back as surround
sound with a proper decoder while only using two channels of storage, it does
seem as though it would be a useful capability if content creators take
advantage of it.
Although there is a stumbling block. 2-channel UHJ requires using different
shelf filters compared to normal B-Format, which the intermediate device mix
is. Which means a 2-channel UHJ buffer can't be decoded to B-Format for mixing
without some form of adjustment to correct for the shelf filters used on
output. On top of this, there's no information readily available for 2-channel
UHJ shelf filters on anything but a plain quad/square output, or information
on how to make them. I could work around this using a technique that
effectively acts like 2-channel UHJ sound decodes to a virtual 4-channel quad
using the known shelf filters, then those 4 virtual channels are encoded onto
the B-Format mix with the rest of the scene. This should sound fine, if not
optimal.
3- and 4-channel UHJ do not require different shelf filters, and are part of
the extension since very little extra work is needed. In fact, 2-channel UHJ
can be seen as a degenerate case of 3-channel UHJ with the third channel gain
at 0, so it's practically free. However, I don't suspect 3- and 4-channel UHJ
will be used much since they break an important feature of 2-channel UHJ (that
it can be played as normal stereo by an unaware system; 3- and 4-channel UHJ
require the system to drop the third and fourth channels if it's not decoding
them, so it needs to be UHJ-aware just to play the stereo signal undecoded).
Unless a file format comes along that can mask the extra UHJ channels when the
app doesn't know what UHJ is, an app would have to be aware of having 3- and
4-channel UHJ content, in which case it may as well just use B-Format.
[4] https://github.com/kcat/openal-soft/blob/a8ea3cad2274/alc/inprogext.h#L79
On another related note, I also ran across Super Stereo, or Stereo Enhance[5].
This is a method to "enhance" normal stereo sounds and music with surround
sound output by giving it a wider, more encompassing stereo image, with a
configurable width, while maintaining a stable front image (normal stereo
tends to collapse in the center when widening the left and right responses).
This is implemented using the same core methods as UHJ, though with different
parameters applied, and is apparently a feature often seen with UHJ decoders.
Interestingly, unlike 2-channel UHJ, the resulting B-Format signal from Super
Stereo processing should use the normal B-Format shelf filters, so it can be
mixed normally.
I've been thinking about making this an option, either as another buffer
format, or some kind of buffer or source flag for when playing stereo buffers.
This could be its own extension, or part of the UHJ extension (since it
utilizes the same functionality, and tends to go hand-in-hand with UHJ).
[5] https://sursound.music.vt.narkive.com/xkMrL00t/what-is-super-stereo (site
seems to be down right now, though it was working not long ago. it's available
on the wayback machine if it's still not working)
Anyway, those are some thoughts I've been having recently and things I've been
playing with. If anyone has any comments or questions or anything, I'm
interested in what your thoughts are.
More information about the openal
mailing list