[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 

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