]> git.alsa-project.org Git - tinycompress.git/commit
Utils: cplay: Fix WAV header parsing for multi-channel (5.1/7.1) formats
authorSeppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Wed, 11 Mar 2026 10:27:37 +0000 (12:27 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 29 May 2026 11:24:13 +0000 (13:24 +0200)
commit8f2fc6b92d8b9e676aa586f728ba6d646faac7db
tree77f076ad9bf0e81036f520325e4e230128d88b80
parentb03a9d458a3efac72dd37264c18859226f55f464
Utils: cplay: Fix WAV header parsing for multi-channel (5.1/7.1) formats

Multi-channel WAV files (>2 channels) use WAVE_FORMAT_EXTENSIBLE
(type 0xFFFE) with a larger fmt chunk that includes a channel mask
and subformat GUID. The existing parser only handled basic PCM
(type 0x0001), causing several issues with 5.1 (6ch) and 7.1 (8ch)
content:

 - The fixed-size fread of struct wave_header (44 bytes) misaligned
   the data chunk read when the fmt chunk was larger than 16 bytes,
   resulting in audio data being read from the wrong file offset.

 - No chunk scanning was performed, so intermediate chunks (fact,
   LIST, PEAK) between fmt and data caused parse failures.

 - The WAV channel mask (speaker positions FL, FR, FC, LFE, BL, BR,
   SL, SR) was never extracted, so firmware received ch_mode=0 and
   could not determine the correct channel-to-speaker routing.

Add parse_wave_file() that properly scans chunks, handles both basic
PCM and WAVE_FORMAT_EXTENSIBLE formats, extracts the channel mask,
and positions the file pointer at the start of audio data. For basic
PCM files with >2 channels, a standard default channel mask is
generated per the Microsoft WAV specification.

The channel mask is passed to firmware via snd_codec.ch_mode so it
can correctly map channels to speaker positions. Also add 24-bit
sample format support (SNDRV_PCM_FORMAT_S24_LE).

Closes: https://github.com/alsa-project/tinycompress/pull/32
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/tinycompress/tinywave.h
src/utils/cplay.c
src/utils/wave.c