Skip to content

WAVEFORMATEX fallback is unsafe for 24 bit formats #62

Description

@HEnquist

is_supported_exclusive_with_quirks falls back to querying the format as WAVEFORMATEX for mono and stereo formats. That fallback is not safe for 24 bit formats.

WAVEFORMATEX has no wValidBitsPerSample. The two 24 bit layouts can still be told apart by nBlockAlign, 6 bytes per stereo frame for packed and 8 for padded, but that is not a reliable way to specify them. For 8, 16 and 32 bit int and for f32 there is only one possible layout, so the simple structure is unambiguous. 24 bit is the only case with two options.

Old drivers handle this badly. Reported in HEnquist/camilladsp#509, where a Realtek ALC236 with a 2017 driver correctly rejects 3-byte packed as WAVEFORMATEXTENSIBLE and then accepts the same format as WAVEFORMATEX:

api.rs:878> Repeating query with format as WAVEFORMATEX
api.rs:884> The requested format is supported as WAVEFORMATEX

Initialize succeeds as well, so nothing catches it. The driver seems to map "24 bit" onto its native 24-in-32 mode and ignore nBlockAlign, so it reads 8 byte frames from a buffer filled with 6 byte ones. The result is loud noise and constant underruns. Switching to the Microsoft inbox HDAudio driver fixes it.

PortAudio avoids this by always using WAVEFORMATEXTENSIBLE for anything that is not 8 or 16 bits, see MakeWaveFormatFromParams in pa_win_wasapi.c.

Fix: skip the WAVEFORMATEX fallback unless the container is 8, 16 or 32 bits and wValidBitsPerSample equals wBitsPerSample.

Two related things in to_waveformatex:

  • it drops wValidBitsPerSample without checking it, so a 24-in-32 format silently becomes plain 32 bit int
  • the .unwrap() on the call in is_supported_exclusive_with_quirks can panic, since to_waveformatex returns an error for subformats other than PCM and float

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions