Skip to content

test: require real AAC packets from native capture - #83

Merged
My-Denia merged 1 commit into
mainfrom
fix/rust-audio-packets
Jul 17, 2026
Merged

test: require real AAC packets from native capture#83
My-Denia merged 1 commit into
mainfrom
fix/rust-audio-packets

Conversation

@My-Denia

Copy link
Copy Markdown
Owner

Description

Hardens the Windows native audio regression gates so an AAC metadata-only MP4 cannot pass as a successful audio capture.

This change adds:

  • packet, decoded-frame, signal-energy, sample-rate, channel-count, and 997 Hz tone assertions for Rust and legacy helpers;
  • first/middle/last audible-window checks across pause/resume and shutdown;
  • a Windows WARP + Media Foundation regression for non-aligned trailing PCM and video-only output;
  • a mixer regression proving stop() waits for an in-flight trailing output callback;
  • read-only CoreAudio default eRender/eConsole endpoint evidence and bounded stimulus cleanup;
  • failure artifact retention with success cleanup, plus matching validation documentation.

Production capture, exporter, Electron, version, packaging, and release code are unchanged.

Motivation

The fork.4 release smoke initially appeared to show an exporter dropping AAC. Packet-level inspection instead found that the source MP4 had AAC configuration metadata but zero audio packets. A deterministic active loopback stimulus then proved that the unmodified Rust and legacy helpers both produce real AAC packets and decoded frames; the earlier idle-loopback smoke had not generated system audio.

The compatibility boundary was therefore a validation gap: existing checks could accept an AAC track header without proving packet production, decode, endpoint stimulus, or trailing audio retention. This PR closes that gap without applying an unjustified runtime workaround or generating silent AAC.

Type of Change

  • Bug Fix
  • New Feature
  • Refactor / Code Cleanup
  • Documentation Update
  • Other: deterministic native regression coverage

Related Issue(s)

None. This is the release-blocker follow-up discovered during the v1.5.0-fork.4 candidate smoke.

Screenshots / Video

Not applicable; there is no UI change and retained local capture/export artifacts were deleted after verification.

Testing

  • cargo +1.96.1 fmt --check
  • cargo +1.96.1 clippy --locked --target x86_64-pc-windows-msvc --all-targets -- -D warnings
  • cargo +1.96.1 test --locked --target x86_64-pc-windows-msvc — 42 WGC tests passed, including the new WARP/MF and mixer-tail regressions
  • npm run test — 489 tests passed
  • npm run lint
  • npm run i18n:check
  • npx tsc --noEmit
  • npm run build-vite
  • npm run test:browser — 7 tests passed
  • npm run build:native:win
  • npm run test:wgc-audio:win — Rust and legacy each produced AAC 48 kHz stereo with 235 packets/frames and a fully decoded approximately 997 Hz signal
  • CLOSESCREEN_PARITY_AUDIO=1 npm run test:wgc-parity:win — both backends retained the expected tone in the first, middle, and trailing audible windows across pause/resume
  • npm run test:wgc-helper:win — explicit video-only/no-audio behavior passed for both backends
  • npm run test:wgc-fault:win — bounded shutdown passed for both backends
  • Rust capture to editor/export smoke — source and exported MP4 each retained 235 AAC packets; full decode passed; GIF remained valid

Independent execution audit and Codex diff review both passed with no blocking findings. Human listening was not used as evidence; decoded non-silent PCM and frequency analysis provide the deterministic media assertion.

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos. (Not applicable: no UI change.)
  • I have linked related issue(s) and updated the changelog if applicable. (No issue/changelog entry; validation documentation is updated.)

@My-Denia
My-Denia marked this pull request as ready for review July 17, 2026 06:03
Copilot AI review requested due to automatic review settings July 17, 2026 06:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@My-Denia
My-Denia merged commit 0c58b89 into main Jul 17, 2026
13 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7db984191a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +693 to +697
if (
WITH_SYSTEM_AUDIO &&
(audioEvidence.rms < AUDIO_RMS_MIN ||
audioEvidence.peak < AUDIO_PEAK_MIN ||
Math.abs(audioEvidence.frequency - SYSTEM_AUDIO_TONE_HZ) > TONE_TOLERANCE_HZ)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Isolate the loopback tone before checking its frequency

When npm run test:wgc-mixed-audio:win enables both system audio and a real microphone, this condition still requires the zero-crossing frequency of the combined signal to be within 10 Hz of 997 Hz. Ambient microphone input—amplified by the configured microphoneGain—can add crossings and fail an otherwise valid mixed-audio recording. Analyze the tone spectrally, isolate the loopback channel, or apply this frequency assertion only to system-audio-only runs.

Useful? React with 👍 / 👎.

Comment on lines +679 to +682
if (
WITH_SYSTEM_AUDIO &&
(Number(audioStream.sample_rate) !== AUDIO_SAMPLE_RATE ||
Number(audioStream.channels) !== AUDIO_CHANNELS)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept the render endpoint's actual sample rate

On a Windows machine whose default render endpoint is configured for 44.1 kHz, both helpers legitimately encode 44.1 kHz AAC, but this assertion makes test:wgc-audio:win fail. The production format normalization explicitly preserves a nonzero source rate in electron/native/rust/wgc-capture/src/audio/format.rs:43-47 (and the legacy implementation does the same), so 48 kHz is only a property of the tested laptop, not the helper contract; the parity harness repeats the same hardcoded assumption. Compare against the reported endpoint/audio format or allow supported AAC sample rates instead.

Useful? React with 👍 / 👎.

Comment on lines +929 to +932
assert!(
decoded_bytes >= AUDIO_FRAMES * 4,
"decoded PCM tail was truncated: {decoded_bytes} bytes"
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify the final PCM chunk instead of only decoded length

This length assertion does not prove that the final short write_audio call was retained. The fixture writes 48,000 frames in full chunks and then a final 123-frame chunk; if that last call is dropped, AAC can pad the preceding 48,000 frames to 47 1,024-sample access units (48,128 decoded frames), which still satisfies decoded_bytes >= AUDIO_FRAMES * 4. Validate the decoded tone/content through the expected tail—or choose counts that cannot be masked by AAC padding—so the regression actually detects loss of the trailing chunk it is named for.

Useful? React with 👍 / 👎.

@My-Denia
My-Denia deleted the fix/rust-audio-packets branch July 17, 2026 10:20
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.

2 participants