Skip to content

Reconcile spliced sample counts in signed space; absorb one-sample rounding drift (fixes #68, #39) - #79

Merged
jwcullen merged 1 commit into
AOMediaCodec:mainfrom
jlivingston-Cipher:wav-splicer-sample-reconciliation
Aug 5, 2026
Merged

Reconcile spliced sample counts in signed space; absorb one-sample rounding drift (fixes #68, #39)#79
jwcullen merged 1 commit into
AOMediaCodec:mainfrom
jlivingston-Cipher:wav-splicer-sample-reconciliation

Conversation

@jlivingston-Cipher

Copy link
Copy Markdown
Contributor

Follows up on #75's invitation to send fixes for the recently filed issues.

Root cause

As analyzed in #68 and independently measured in #39: the objects-to-3OA
splice (wav_file_splicer.cc) computes per-segment sample counts by
floor()-ing double products of parsed ADM durations. When a segment
boundary falls on an exact sample but the double product rounds just below
it (e.g. 163.89 s × 48000 Hz = 7866719.99999999906…), the splice comes up
one sample short. The final reconciliation —
fabs(num_samples_count - *total_samples_per_channel) — then promotes the
int count through unsigned arithmetic, so the −1 shortfall wraps to
~1.84467e+19 and the CHECK aborts (SIGABRT). Whether a given input trips
this depends only on which way the products round, which is why roughly
half of plausible authoring grids crash (boundary table in #68).

fecb716 moved the total sample count into integer space; the
per-segment products and the final reconciliation still ran through
doubles and unsigned promotion. This PR completes that arc:

  • Reconcile in signed 64-bit space and return a Status instead of
    crashing.
  • Absorb a one-sample shortfall by splicing the still-unread remainder
    through the panner, so the output stays sample-exact (no padding, the
    real final sample).
  • Convert the per-segment and total-duration CHECKs on input-dependent
    values to Statuses (an encoder should not abort on valid input).
  • Add a regression test — the first to exercise the Dolby objects-to-3OA
    path: a 6005-sample mono ADM BWF (00:00:00.12510 at 48 kHz, i.e. the
    5-decimal ADM timecode quantization of 0.125104166… s) that previously
    crashed with Issue Check failed: fabs(num_samples_count - *total_samples_per_channel) <= kErrorTolerance #39's exact signature and must now produce sample-exact 3OA
    output.

What this deliberately does not do: re-time the segmentation.
Per-segment lengths are computed exactly as before, so output for inputs
that already worked is unchanged (verified below).

Verification (Linux, at dd03679)

On #37: fecb716 addressed that report's total-samples computation; this
change converts the remaining aborts in the same function to clean errors.

Contributor agreement: executed and on file since 2026-07-27 (per
CONTRIBUTING), as with #78.

…ample rounding drift.

The objects-to-3OA splice computes per-segment sample counts by
floor()-ing double products of parsed ADM durations. When a segment
boundary lands on an exact sample but the double product rounds just
below it (e.g. 163.89 s * 48000 Hz = 7866719.99999999906...), the
splice comes up one sample short, and the final reconciliation
(fabs(num_samples_count - *total_samples_per_channel)) promotes the
count through unsigned arithmetic, wraps to ~1.8e19, and CHECK-crashes
with SIGABRT.

- Reconcile in signed 64-bit space and return a Status instead of
  crashing (continuing the direction of fecb716).
- Absorb a one-sample shortfall by splicing the still-unread remainder
  through the panner, so the output stays sample-exact.
- Convert the per-segment and total-duration CHECKs on input-dependent
  values to Statuses.
- Add a regression test: a 6005-sample mono Dolby-mode ADM BWF
  (00:00:00.12510 at 48 kHz) that previously crashed and must now
  produce sample-exact 3OA output.

Fixes AOMediaCodec#68. Fixes AOMediaCodec#39. Related: AOMediaCodec#37 (the remaining CHECK from that
report class now returns a clean error instead of aborting).
@jwcullen
jwcullen merged commit 04bc8c8 into AOMediaCodec:main Aug 5, 2026
6 checks passed
@jlivingston-Cipher

Copy link
Copy Markdown
Contributor Author

Thanks

@jlivingston-Cipher
jlivingston-Cipher deleted the wav-splicer-sample-reconciliation branch August 6, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants