native ambisonics support#25
Merged
Merged
Conversation
thirv
reviewed
Mar 27, 2026
|
Could the support be extended to 7OA? |
Contributor
Author
That's relatively easy to do. |
thirv
approved these changes
Apr 6, 2026
thirv
left a comment
There was a problem hiding this comment.
As we build the multichannel capacity, there are number of tools that people are interested in having to handle correlations and joint bit allocation. Clarifying the former, it seems that we want to include the mechanism of 1) constructing a downmix and 2) demixing at the decoder. Regardless of the methods of how to actually implement them, either/both of these could be static or dynamic.
I'd advocate to keep these possibilities open, and this PR seems like it would be a valid basis for adding these later. Feel free to discuss if the above does not resonate.
jmvalin
reviewed
Apr 7, 2026
c11b255 to
c1e749d
Compare
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
jmvalin
reviewed
Apr 22, 2026
1411dc2 to
eafaf8f
Compare
eafaf8f to
d695da4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Native Ambisonics Support
Summary
Adds native multi-channel ambisonics encoding/decoding to OAC, supporting ambisonics orders 0–5 (1, 4, 9, 16, 25, or 36 channels). In ambisonics mode, each channel is encoded independently per band using CELT, bypassing the stereo mid/side coupling path entirely.
Key Changes
New API surface (include/oac.h, include/oac_defines.h)
New format constants: OAC_FORMAT_STANDARD (mono/stereo) and OAC_FORMAT_AMBISONICS (up to 36ch)
oac_encoder_create(), oac_decoder_create(), and their _init/_get_size variants now take a format parameter
New CTL: OAC_GET_FORMAT to query the initialized format
CELT band quantization (celt/bands.c, celt/bands.h)
Renamed the existing oaci_quant_all_bands to quant_all_bands_twoch (static, handles 1–2 channels)
Added quant_all_bands_multi — a multi-mono quantization path where each channel is encoded independently per band with its own spectral folding norm, lowband scratch, and split memory
New public dispatcher oaci_quant_all_bands routes to the appropriate implementation based on channel count
Bit allocation (celt/rate.c)
Replaced hardcoded >>stereo shifts with
C
division to generalize fine-energy bit allocation for arbitrary channel counts
Energy quantization (celt/quant_bands.c)
Expanded prev[] arrays from fixed size 2 to OAC_MAX_CHANNELS for multi-channel coarse energy quantization/unquantization
Encoder/Decoder (src/oac_encoder.c, src/oac_decoder.c, celt/celt_encoder.c, celt/celt_decoder.c)
Encoder and decoder state structs carry a format field
Format/channel validation via oaci_validate_format_channels() in oac_private.h
Ambisonics mode forces CELT-only encoding (no SILK) and OAC_APPLICATION_AUDIO
Multistream (src/oac_multistream_encoder.c, src/oac_multistream_decoder.c)
Updated to pass format through to underlying encoder/decoder instances
Tests
New tests/test_oac_ambisonics.c — encode/decode round-trip tests for all valid ambisonics channel counts
Usage — oac_demo with ambisonics input
Encode a 4-channel (1st order) ambisonics file
./oac_demo -e -format ambix input_4ch.pcm encoded.oac 48000 4 64000
Decode back
./oac_demo -d -format ambix encoded.oac output_4ch.pcm 48000 4
Encode + decode in one pass (default)
./oac_demo -format ambix input_4ch.pcm output_4ch.pcm 48000 4 64000
-format ambix enables ambisonics mode (default is std for standard mono/stereo)
Note that channel count is an out-of-band parameter for ambix i.e. we do not support order conversion (yet).