Skip to content

fix(audio): keep APAC priming so TrueHD Atmos stays in sync with the video - #8

Merged
Quick104 merged 1 commit into
mainfrom
fix/apac-priming-sync
Sep 26, 2026
Merged

Quick104 merged 1 commit into
mainfrom
fix/apac-priming-sync

Conversation

@Quick104

@Quick104 Quick104 commented Sep 26, 2026 •

Copy link
Copy Markdown

Summary

TrueHD Atmos rendered to APAC played 42.7 ms ahead of the video in every session. The spatial bridge dropped the encoder's 2048 frames of priming, and AVFoundation removes the same 2048 frames again on playback. The bridge now keeps the priming packets and stamps packet k at anchor + k × 1024, the layout AVAssetWriter writes, so the first content frame plays on its source position.

Follow-up to #6.

What changed

  • SpatialAudioBridge.emit keeps the encoder's two priming packets and stamps every packet from the anchor. Gap fill, restarts and the end-of-stream flush already count packets from the encoder start, so nothing else moves.
  • New test clickDecodesOnItsSourcePosition renders a click at a known source position, encodes and muxes it, and decodes the result with AVAssetReader. On the old stamping the click comes out at 0.2074 s instead of 0.25 s; it now lands within 1 ms.
  • SpatialAudioBridgeTests and TrueHDAtmosSampleTests expect two more packets, the priming.
  • formats.md, the APACEncoder notes and CHANGELOG.md describe the new layout.

Test plan

  • Device / OS: macOS 27 on Apple silicon. AVPlayer played each stream over HLS; ScreenCaptureKit recorded the output, and each click's capture time was mapped onto the item timeline.
  • Source media: synthetic 60 s streams with a 3 ms click every second, encoded with the engine's APAC settings, plus an ALAC HLS reference with the same clicks. The APAC streams are 5.1 because macOS AVPlayer rejects 7.1.4 APAC; every layout primes the same 2048 frames.
  • Result, as click time minus source time. The ALAC reference reads −4.70 ms, which is the capture path's own offset.
APAC layout From the start After a seek After a seek into a restarted encoder
Priming dropped (before) −47.37 ms −47.35 ms −47.44 ms
Priming kept (this PR) −4.70 ms −4.70 ms −4.76 ms
  • Unit tests: the full suite passes (3377 tests in 456 suites), and so do the authorization suites (43 tests). With AE_TRUEHD_ATMOS_SAMPLE set to Dolby's Unfold .thd, the 9.1.6 bridge emits 1270 contiguous packets.
  • iOS 27 simulator: aetherctl serve --atmos-bed 7.1.4 --audio-index 1 on the Unfold demo plays from the start and after a seek to 15 s.
  • Not yet checked on Apple TV hardware. The offset was noticed there before this fix.

Checklist

  • CHANGELOG.md updated
  • Commit messages follow Conventional Commits (feat(...), fix(...), chore(...))
  • The fix lives in the engine, not in a host-side workaround
  • Public API changes are intentional and documented (no public API change)

AI disclosure: written with Claude Opus 5.5 (claude-opus-5-5) in Claude Code. Claude Opus 5.5 review subagents found the offset while reviewing #6; the fix, tests and measurement harness were written in the same session. No other AI tooling was used.

🤖 Generated with Claude Code

Note

Fix APAC TrueHD Atmos sync by retaining encoder priming packets

  • SpatialAudioBridge previously dropped the APAC encoder's two priming packets and subtracted leading frames from packet timestamps, so AVFoundation's 2048-frame pre-timestamp presentation placed the first content audio 42.7 ms early. It now emits every encoder packet and timestamps each at the encoder start frame plus its packet index × 1024 frames (SpatialAudioBridge.swift).
  • Adds an end-to-end test that muxes a synthetic 1 kHz click through the bridge, decodes it via AVFoundation, and asserts the click lands at 0.25 s within 1 ms (SpatialAudioBridgeTests.swift).
  • Updates APAC packet-count expectations in SpatialAudioBridgeTests and TrueHDAtmosSampleTests to include the two priming packets, and documents the retained priming behavior in docs/formats.md and CHANGELOG.md.
  • Behavioral Change: APAC streams now carry two extra priming packets, and packet timestamps no longer subtract the 2048 leading frames. Tests and docs that assume the old packet counts are updated.

Macroscope summarized 455bcd6.

…video

The spatial bridge dropped the encoder's two priming packets (2048 frames) and
stamped the first content packet on the source position. AVFoundation presents
an APAC packet's audio 2048 frames before its timestamp, so it removed the
priming a second time and every TrueHD Atmos session played 42.7 ms ahead of
the video, at load and after every seek.

Packet k is now stamped anchor + k*1024 with the priming packets kept, the
layout AVAssetWriter writes. Measured with AVPlayer over HLS on macOS 27 (5.1
APAC; macOS rejects 7.1.4) against an ALAC reference: the old layout played a
click 42.7 ms early at the start, after a seek, and after a restarted encoder;
the new one matches the reference in all three.

A new test decodes the bridge's muxed output through AVAssetReader and checks
that a click lands on its source position; it fails on the old stamping
(0.2074 s instead of 0.25 s).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 70682c15-adb1-437e-8618-6062157b8129

📥 Commits

Reviewing files that changed from the base of the PR and between 557afc2 and 455bcd6.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • Sources/AetherEngine/Audio/Spatial/APACEncoder.swift
  • Sources/AetherEngine/Audio/Spatial/SpatialAudioBridge.swift
  • Tests/AetherEngineTests/SpatialAudioBridgeTests.swift
  • Tests/AetherEngineTests/TrueHDAtmosSampleTests.swift
  • docs/formats.md

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The bridge now retains APAC priming packets and timestamps each packet from the encoder start frame. Tests check packet timing, packet counts, muxing, and decoded audio onset.

Changes

APAC packet timing

Layer / File(s) Summary
Emit and timestamp APAC priming packets
Sources/AetherEngine/Audio/Spatial/APACEncoder.swift, Sources/AetherEngine/Audio/Spatial/SpatialAudioBridge.swift, docs/formats.md, CHANGELOG.md
The bridge emits priming packets and timestamps packet k from the encoder start frame. Documentation describes retaining priming packets and their source-position timestamp.
Verify packet timing and decoded onset
Tests/AetherEngineTests/SpatialAudioBridgeTests.swift, Tests/AetherEngineTests/TrueHDAtmosSampleTests.swift
Tests account for two priming packets, exercise muxing through a reusable helper, and verify decoded click onset.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 455bc

The change retains APAC priming packets to align TrueHD Atmos audio with video. No actionable merge-blocking issue is established; normal checks remain appropriate.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 455bc

The new packet layout is documented and tested through decoding, and the review found no new security boundary or verified security issue. Recovery behavior and platform coverage remain less certain.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The effective changed output is APAC audio timing in sessions using this bridge and their downstream muxing and playback. Evidence does not establish a wider asset, tenant, credential, or service-authority exposure.

Trust Boundaries and Controls

  • observed — Input packet data passes to the decoder, whereas emitted packet bytes come from the encoder; output timestamps use the bridge's source-derived anchor and local counter. The assessed change does not replace that authority path.

Resilience and Maintainability Implications

  • inferred — Malformed-media interruption may leave an audible or timestamp gap after the producer skips a failed feed, but the available change evidence does not show a newly introduced security-control failure. Recovery after interruption and gaps beyond the five-second fill cap remain unverified.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 4 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: retaining APAC priming to correct TrueHD Atmos synchronization.
Description check ✅ Passed The description is directly related to the changeset and explains the cause, implementation, tests, documentation updates, and remaining hardware coverage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 4 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeapp Bot commented Sep 26, 2026

Copy link
Copy Markdown

Approvability

Verdict: Approved at 455bcd6

Macroscope's review found this PR approvable — This is a focused APAC synchronization bug fix that retains encoder priming packets and corrects packet timestamps, while leaving other audio paths unchanged. Added tests verify both packet timelines and the decoded audio position through AVFoundation.

You can add or adjust custom eligibility rules. Learn more.

@Quick104
Quick104 merged commit a02975e into main Sep 26, 2026
10 checks passed
Quick104 added a commit to Silo-Server/silo-apple that referenced this pull request Sep 26, 2026
Silo-Server/AetherEngine#8 merged as a02975ed. Its tree is identical to the
PR head 455bcd60 this branch pinned before, so only the recorded revision moves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Quick104 added a commit to Silo-Server/silo-apple that referenced this pull request Sep 26, 2026
* fix(player): pick up AetherEngine's TrueHD Atmos sync fix

TrueHD Atmos played 42.7 ms ahead of the video: AetherEngine's APAC bridge
dropped the encoder's 2048 frames of priming, which AVFoundation removes again
on playback. Silo-Server/AetherEngine#8 keeps the priming packets. Move the pin,
Package.resolved and the notices to that commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore(deps): pin AetherEngine to the TrueHD Atmos sync fix merge commit

Silo-Server/AetherEngine#8 merged as a02975ed. Its tree is identical to the
PR head 455bcd60 this branch pinned before, so only the recorded revision moves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant