summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>2022-11-11 00:45:01 +0100
committerJaroslav Kysela <perex@perex.cz>2023-01-23 19:00:34 +0100
commit4f7e1af85ad79797cf7195def1564930072d2cc0 (patch)
treed8f20e3bab06fc6a816f5f7db3045ecceb436283
parentf67b3ed002fc4327ece6e7533cae038539e80e36 (diff)
downloadalsa-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.c24
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)