Skip to content

Anti-alias decimation: replace the box average on the integer-factor AAC downsample path #582

Description

@EtienneLescot

Follow-up to #565 (snap illegal AAC sample rates to 48 kHz on Windows), which introduced the integer-factor downsample path in electron/native/wgc-capture/src/audio_sample_utils.cpp (convertAudioWithGain).

Context. The 96 kHz / 192 kHz → 48 kHz path currently averages each group of factor source frames (box average) instead of picking one frame — a clear improvement over the previous nearest-neighbour decimation, and state (the remainder) is correctly carried across packets by AudioMixer. This tradeoff was accepted when #565 was reviewed (CodeRabbit flagged it twice as 🟠 Major / Heavy lift), with this issue recorded so the subject is not lost.

Problem. A box average is not an adequate anti-alias filter: for 96 kHz → 48 kHz, a 36 kHz source tone survives at roughly 38% amplitude and aliases to 12 kHz in the output. The existing Nyquist test passes only because the two-tap average happens to have a zero exactly at 48 kHz. In practice desktop system audio carries almost no energy above 24 kHz, which is why this was accepted — but it is a real limitation, not a solved problem.

Acceptance criteria.

  • Replace the box average with a stateful low-pass decimator whose cutoff is at or below the target Nyquist frequency, preserving the existing cross-packet remainder handling in AudioMixer (systemResampleRemainder_ / microphoneResampleRemainder_).
  • Add unit-test coverage in audio_sample_utils_test.cpp for an input tone between 24 kHz and 48 kHz, asserting the aliased component stays below an explicit threshold.
  • No regression on the existing suite (sub-factor packets, one-frame packets, remainder three-then-one/full), which runs as part of npm run build:native:win.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions