Repository navigation
Unfold Auro-3D carriers into their bed and height layer - #56
Merged
Merged
Conversation
Auro-3D ships its height layer inside an ordinary 24-bit carrier: the low bits of every carrier sample hold a serial side channel that names the fold (original and carrier layouts) and carries the residuals a decoder needs to undo it. Only the first part is publicly described, and that is what this reads. A new dependency-free `auro` crate parses the block sync, the CRC-16 that guards it, and the ADOL bytecode that announces the channel-input configuration; a streaming detector with fixed per-channel storage latches once three consecutive blocks agree. Its bit map is checked by a synthetic writer in the tests and by an optional corpus test on a real extract, where every block of every channel validates. `dca::HdDecoder` gains `lossless_samples`, the integer XLL output before the float conversion, because the side channel does not survive the round trip. `harletty decode` feeds it to the detector and logs what the carrier holds; the output is unchanged, the carrier bed, since the residual layer is not specified anywhere public. The research note that guessed a patent scheme is replaced with what the streams actually do. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The side channel's stream layer is now read in full and undone. Per block and per carrier: a 112-bit header (Rice parameter, codebook size and width, ADOL block count, stream-id slots), the predictor seeds, the ADOL bytecode (gain codes in tenths of a dB via 0x40, an offset via 0x41), a codebook of sign-magnitude residual values, and a Golomb-Rice stream of codebook indices, one per sample. The unfold treats the carrier as the exact sum of the folded streams: each sample one stream is extrapolated from its history (linear for two streams, three-phase for three) and the others derived from the sum, the residual correcting the derived value before it feeds the next prediction; outputs are scaled by their gain codes and clamped to 24 bits. Checked against the published original/encoded pair (a 5.1 mix and its Auro-2D carrier): every restored channel correlates 0.99999 with the original, within 0.01 dB. On the demo carriers every block decodes and the outputs sum back to the carrier. `auro::Unfolder` joins the carriers of one stream with the one-block latency the scheme imposes, averaging a stream folded into two carriers and playing the carrier as authored where no block claims a sample. `harletty decode` holds its DTS-HD frames back until the carrier is confirmed, then writes a master set of the original layout: bed and corner heights as bed channels, centre height and top as static objects, labelled Auro-3D-13.1 / -11.1 / -10.1 / -9.1. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The bridge now does what the CLI does: a lossless DTS-HD track that turns out to be an Auro-Codec carrier plays as the layout it folds, with the bed and the height layer as labelled fixed channels (corner heights as Tfl/Tfr/Tbl/Tbr, the centre height as Tfc, the top as Tc). Frames are held back until the carrier question is settled — two of the largest blocks when no block validates, four when blocks validate but the layout has not latched — then replayed into the unfolder from their own PCM, which is the lossless bed exactly. From then on output lags input by one block, the unfolder's latency now following the detected block size instead of the largest possible one (the CLI gets the same). A track that is not a carrier, or that carries a DTS:X presentation, gets its held frames back unchanged and the stage steps aside. Checked by a synthetic carrier whose blocks announce a height stream on the L channel (it comes out on Tfl with L silent, the other channels play as themselves) and, when the corpus is at hand, by a real 13.1 extract through push_packet: every frame out is the 14-channel layout, one block held back at the end. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The channel-count label a decoded stream is stored under (Auro-3D-13.1 and friends) now comes from auro::Layout::source_codec_label, so the DAMF sourceCodec and the atmos-ranker probe cannot drift apart. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
If possible, please add a link to my GitHub account @almirus Thank you. |
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.
What
Auro-3D ships its height layer inside an ordinary 24-bit 5.1/7.1 carrier: the low bits of every carrier sample hold a serial side channel that names the fold and carries the residuals a decoder needs to undo it. This PR reads that side channel in full and unfolds the carrier back into the layout it was encoded from, offline and in realtime.
Three commits:
aurocrate: block sync, CRC-16/CCITT, the ADOL bytecode that announces the channel-input configuration, the public layout tables, and a streamingDetectorwith fixed per-channel storage.dca::HdDecoder::lossless_samplesexposes the integer XLL output the side channel needs.Unfolderthat joins the carriers with the one-block latency the scheme imposes, and the CLI:harletty decodeholds DTS-HD frames back until the carrier is confirmed, then writes a master set of the original layout — bed and corner heights as bed channels, centre height and top as static objects — labelledAuro-3D-13.1/-11.1/-10.1/-9.1.docs/pcm-aux-layer-research.mddocuments the format as found; the earlier draft reasoned from a patent example the streams do not follow.Verification
cargo test -p auro: a synthetic writer mirrors the reader's bit map; an encoder round trip checks the two-stream unfold; the three-stream sum invariant; Rice/codebook decoding on hand-built bit strings.auro/tests/pair.rsagainst the published original/encoded pair (HARLETTY_AURO_PAIR_*): 1880 blocks, 0 decode errors, correlation 0.999996–0.999998 and gain −0.002 dB on L, R, C, Ls, Rs.auro/tests/corpus.rson real 13.1 and 11.1 extracts: every block of every channel validates.push_packet(HARLETTY_AURO_DTS_CORPUS) yields 2923 frames of 14 channels with exactly one block held back at the end.cargo test --workspacegreen;scripts/check-crate-isolation.shok.Not in this PR
Sources for the layout layer: almirus, Habr (2026-08);
almirus/Orua-D3(MIT); MediaArea/MediaInfoLib#2531. The stream layer was worked out here by analysis of the carriers and is checked against the published pair.🤖 Generated with Claude Code