jstrait / wavefile

A Ruby gem for reading and writing sound files in Wave format (*.wav)
https://wavefilegem.com
MIT License
208 stars 24 forks source link

Format Chunks With Extra Bytes at the End Sometimes Cause `InvalidFormatError` to be Raised #33

Closed jstrait closed 1 year ago

jstrait commented 4 years ago

Normally, the "fmt " chunk has an expected size based on the format code. For example:

When attempting to read a file using Reader.new(), an InvalidFormatError will be raised if the "fmt " chunk has fewer bytes than the expected size, because the chunk has incomplete data.

However (as of v1.1.1), if a "fmt " chunk has more bytes than expected, then an InvalidFormatError will also sometimes be raised with the message "Not a supported wave file. The format chunk extension is shorter than expected.". This error message is misleading, because the problem is that the chunk is longer than expected, not shorter. If the format code is 1, it's doubly misleading because the "fmt " chunk won't even have an extension.

Why is this error only sometimes raised? There is a scenario in which this error won't be raised if the "fmt " chunk is larger than the normal expected size: if the format code is 1, and the value of bytes 16 and 17 (0-based) when interpreted as a 16-bit unsigned little endian integer is the same as the subsequent number of bytes in the chunk body, no error will be raised. For example, if the "fmt " chunk size is 22, the format code is 1, and the value of bytes 16 and 17 is 4 (when interpreted as a 16-bit unsigned little endian integer), the file can be opened correctly. Note that this implies that if the format code is not 1, the required chunk extension can contain extra bytes, but there can't be extra bytes following the extension. (However, if the file is in WAVE_FORMAT_EXTENSIBLE format (i.e. format code 65534) and the extension has extra bytes, the "sub format GUID" field won't be read correctly; see #37 for more info on that issue).

In general, it seems like an error shouldn't be raised if the "fmt " chunk is larger than the default expected size. Page 60 of the original "Multimedia Programming Interface and Data Specifications 1.0" document with the original definition of the *.wav file spec states:

"The < format-specific-fields> consists of zero or more bytes of parameters. Which parameters occur depends on the WAVE format category–see the following section for details. Playback software should be written to allow for (and ignore) any unknown < format-specific-fields> parameters that occur at the end of this field."

Which seems like it could be interpreted as meaning extra bytes at the end of a format chunk should be ignored without raising an error.

See #24 for more info on the background of this issue.

jstrait commented 1 year ago

This is now fixed in v1.1.2, so closing this issue.

@CromonMS thanks for reporting this!