diff --git a/aplay/aplay.c b/aplay/aplay.c index 9b22eb5..e02ca98 100644 --- a/aplay/aplay.c +++ b/aplay/aplay.c @@ -745,16 +745,29 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) check_wavefile_space(buffer, len, blimit); test_wavefile_read(fd, buffer, &size, len, __LINE__); f = (WaveFmtBody*) buffer; + if (LE_SHORT(f->format) == WAV_FMT_EXTENSIBLE) { + WaveFmtExtensibleBody *fe = (WaveFmtExtensibleBody*)buffer; + if (len < sizeof(WaveFmtExtensibleBody)) { + error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"), + len, (u_int)sizeof(WaveFmtExtensibleBody)); + exit(EXIT_FAILURE); + } + if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) { + error(_("wrong format tag in extensible 'fmt ' chunk")); + exit(EXIT_FAILURE); + } + f->format = fe->guid_format; + } if (LE_SHORT(f->format) != WAV_FMT_PCM && LE_SHORT(f->format) != WAV_FMT_IEEE_FLOAT) { error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), LE_SHORT(f->format)); exit(EXIT_FAILURE); } - if (LE_SHORT(f->modus) < 1) { - error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->modus)); + if (LE_SHORT(f->channels) < 1) { + error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); exit(EXIT_FAILURE); } - hwparams.channels = LE_SHORT(f->modus); + hwparams.channels = LE_SHORT(f->channels); switch (LE_SHORT(f->bit_p_spl)) { case 8: if (hwparams.format != DEFAULT_FORMAT && @@ -1805,7 +1818,7 @@ static void begin_wave(int fd, size_t cnt) f.format = LE_SHORT(WAV_FMT_IEEE_FLOAT); else f.format = LE_SHORT(WAV_FMT_PCM); - f.modus = LE_SHORT(hwparams.channels); + f.channels = LE_SHORT(hwparams.channels); f.sample_fq = LE_INT(hwparams.rate); #if 0 tmp2 = (samplesize == 8) ? 1 : 2; diff --git a/aplay/formats.h b/aplay/formats.h index 3ba0bfa..b5314f9 100644 --- a/aplay/formats.h +++ b/aplay/formats.h @@ -69,6 +69,10 @@ typedef struct voc_ext_block { #define WAV_FMT_PCM 0x0001 #define WAV_FMT_IEEE_FLOAT 0x0003 #define WAV_FMT_DOLBY_AC3_SPDIF 0x0092 +#define WAV_FMT_EXTENSIBLE 0xfffe + +/* Used with WAV_FMT_EXTENSIBLE format */ +#define WAV_GUID_TAG "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71" /* it's in chunks like .voc and AMIGA iff, but my source say there are in only in this combination, so I combined them in one header; @@ -81,14 +85,23 @@ typedef struct { } WaveHeader; typedef struct { - u_short format; /* should be 1 for PCM-code */ - u_short modus; /* 1 Mono, 2 Stereo */ + u_short format; /* see WAV_FMT_* */ + u_short channels; u_int sample_fq; /* frequence of sample */ u_int byte_p_sec; u_short byte_p_spl; /* samplesize; 1 or 2 bytes */ u_short bit_p_spl; /* 8, 12 or 16 bit */ } WaveFmtBody; +typedef struct { + WaveFmtBody format; + u_short ext_size; + u_short bit_p_spl; + u_int channel_mask; + u_short guid_format; /* WAV_FMT_* */ + u_char guid_tag[14]; /* WAV_GUID_TAG */ +} WaveFmtExtensibleBody; + typedef struct { u_int type; /* 'data' */ u_int length; /* samplecount */