]> git.alsa-project.org Git - alsa-utils.git/commitdiff
aplay: Fix parsing of format with WAV_FMT_EXTENSIBLE header
authorAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Thu, 10 Nov 2022 23:45:01 +0000 (00:45 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 23 Jan 2023 18:00:34 +0000 (19:00 +0100)
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>
aplay/aplay.c

index 6ce71915fcde80c1a1d0e1a799498bc2f5d32374..2b06abccc1941b719198fc5bb955b55d5773c9d0 100644 (file)
@@ -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)