diff options
author | Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> | 2022-11-11 00:45:01 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2023-01-23 19:00:34 +0100 |
commit | 4f7e1af85ad79797cf7195def1564930072d2cc0 (patch) | |
tree | d8f20e3bab06fc6a816f5f7db3045ecceb436283 | |
parent | f67b3ed002fc4327ece6e7533cae038539e80e36 (diff) | |
download | alsa-utils-4f7e1af85ad79797cf7195def1564930072d2cc0.tar.gz |
aplay: Fix parsing of format with WAV_FMT_EXTENSIBLE header
WAV_FMT_EXTENSIBLE header contains valid bits per sample, which can be
different than bits per sample. Make sure it is taken into account when
parsing headers and choosing playback format.
BugLink: https://github.com/alsa-project/alsa-utils/pull/178
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | aplay/aplay.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/aplay/aplay.c b/aplay/aplay.c index 6ce7191..2b06abc 100644 --- a/aplay/aplay.c +++ b/aplay/aplay.c @@ -1002,6 +1002,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) u_int type, len; unsigned short format, channels; int big_endian, native_format; + u_char vbps = 0; if (size < sizeof(WaveHeader)) return -1; @@ -1058,6 +1059,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) error(_("wrong format tag in extensible 'fmt ' chunk")); prg_exit(EXIT_FAILURE); } + vbps = TO_CPU_SHORT(fe->bit_p_spl, big_endian); format = TO_CPU_SHORT(fe->guid_format, big_endian); } if (format != WAV_FMT_PCM && @@ -1071,6 +1073,10 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) prg_exit(EXIT_FAILURE); } hwparams.channels = channels; + if (vbps > TO_CPU_SHORT(f->bit_p_spl, big_endian)) { + error(_("valid bps greater than bps: %d > %d"), vbps, TO_CPU_SHORT(f->bit_p_spl, big_endian)); + prg_exit(EXIT_FAILURE); + } switch (TO_CPU_SHORT(f->bit_p_spl, big_endian)) { case 8: if (hwparams.format != DEFAULT_FORMAT && @@ -1123,10 +1129,20 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) break; case 32: if (format == WAV_FMT_PCM) { - if (big_endian) - native_format = SND_PCM_FORMAT_S32_BE; - else - native_format = SND_PCM_FORMAT_S32_LE; + switch (vbps) { + case 24: + if (big_endian) + native_format = SND_PCM_FORMAT_S24_BE; + else + native_format = SND_PCM_FORMAT_S24_LE; + break; + default: + if (big_endian) + native_format = SND_PCM_FORMAT_S32_BE; + else + native_format = SND_PCM_FORMAT_S32_LE; + break; + } hwparams.format = native_format; } else if (format == WAV_FMT_IEEE_FLOAT) { if (big_endian) |