From c5193f0b5e965c466143718cc256df8cba005ec5 Mon Sep 17 00:00:00 2001 From: Notheisz57 <17867971+Notheisz57@users.noreply.github.com> Date: Sun, 18 Sep 2022 18:11:51 -0700 Subject: [PATCH 1/3] Update WaveFile.cs Fix to allow parsing WAV files which use an Extension chunk to describe PCM audio formats greater than 16-bit. Microsoft states that any WAV file with a Bit Depth of more than 16 should use the Extension chunk to describe it's Audio Format, but it still uses the same Audio Format constants that are used at the container-level Audio Format definition. --- NWaves/Audio/WaveFile.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/NWaves/Audio/WaveFile.cs b/NWaves/Audio/WaveFile.cs index 9dc73f4..cd76446 100644 --- a/NWaves/Audio/WaveFile.cs +++ b/NWaves/Audio/WaveFile.cs @@ -122,13 +122,25 @@ protected void ReadWaveStream(Stream waveStream, bool normalized = true) waveFmt.Align = reader.ReadInt16(); waveFmt.BitsPerSample = reader.ReadInt16(); - WaveFmt = waveFmt; - - if (fmtSize == 18) + // Header size might not include sizeof extension block. + if (fmtSize == 18 || fmtSize == 40) { var fmtExtraSize = reader.ReadInt16(); - reader.ReadBytes(fmtExtraSize); + // Additional info for the following: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html + // Here is a good link from that page for the Extension chunk: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html + // Any non-16bit WAV file should include a format extension chunk describing how the data should be interpreted. + var fmtUsedBitsPerSample = reader.ReasInt16(); // Number of bits-per-sample actually used of container-specified bits-per-sample + var fmtChannelSpeakerMap = reader.ReadInt32(); // Bitmask/flags indicating which channels are included in the file. + var fmtSubFormatCode = reader.ReadInt16(); // Similar to container-level format code (1 = PCM, 3 = IEEE, etc.). + var fmtSubFormatRemainder = reader.ReadBytes(14); // Remainder of SubFormat GUID. Usually just "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71". + // Above link says our AudioFormat dictates whether an extension chunk should actually exist, but we've been lenient to standards up to this point anyways. + if (waveFmt.AudioFormat == 0xFFFE) + waveFmt.AudioFormat = fmtSubFormatCode; + if (fmtExtraSize > 22) // Read any leftovers + reader.ReadBytes(fmtExtraSize - 22); } + + WaveFmt = waveFmt; // there may be some wavefile meta info here, // so try to find "data" header in the file: From d501ab09ab69f30c7c821b6cfa218461ffae6340 Mon Sep 17 00:00:00 2001 From: Notheisz57 <17867971+Notheisz57@users.noreply.github.com> Date: Sun, 18 Sep 2022 18:24:07 -0700 Subject: [PATCH 2/3] Update WaveFile.cs Typo. Authored in Web editor == no red squiggles. --- NWaves/Audio/WaveFile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NWaves/Audio/WaveFile.cs b/NWaves/Audio/WaveFile.cs index cd76446..ce3a8ec 100644 --- a/NWaves/Audio/WaveFile.cs +++ b/NWaves/Audio/WaveFile.cs @@ -129,7 +129,7 @@ protected void ReadWaveStream(Stream waveStream, bool normalized = true) // Additional info for the following: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html // Here is a good link from that page for the Extension chunk: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html // Any non-16bit WAV file should include a format extension chunk describing how the data should be interpreted. - var fmtUsedBitsPerSample = reader.ReasInt16(); // Number of bits-per-sample actually used of container-specified bits-per-sample + var fmtUsedBitsPerSample = reader.ReadInt16(); // Number of bits-per-sample actually used of container-specified bits-per-sample var fmtChannelSpeakerMap = reader.ReadInt32(); // Bitmask/flags indicating which channels are included in the file. var fmtSubFormatCode = reader.ReadInt16(); // Similar to container-level format code (1 = PCM, 3 = IEEE, etc.). var fmtSubFormatRemainder = reader.ReadBytes(14); // Remainder of SubFormat GUID. Usually just "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71". From 40a58d877c6e5ac9c7697c2cb3036f29df4d3cde Mon Sep 17 00:00:00 2001 From: Notheisz57 <17867971+Notheisz57@users.noreply.github.com> Date: Tue, 27 Sep 2022 09:36:19 -0700 Subject: [PATCH 3/3] Update WaveFile.cs --- NWaves/Audio/WaveFile.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/NWaves/Audio/WaveFile.cs b/NWaves/Audio/WaveFile.cs index ce3a8ec..6c9c7a9 100644 --- a/NWaves/Audio/WaveFile.cs +++ b/NWaves/Audio/WaveFile.cs @@ -126,18 +126,19 @@ protected void ReadWaveStream(Stream waveStream, bool normalized = true) if (fmtSize == 18 || fmtSize == 40) { var fmtExtraSize = reader.ReadInt16(); - // Additional info for the following: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html - // Here is a good link from that page for the Extension chunk: https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html // Any non-16bit WAV file should include a format extension chunk describing how the data should be interpreted. var fmtUsedBitsPerSample = reader.ReadInt16(); // Number of bits-per-sample actually used of container-specified bits-per-sample var fmtChannelSpeakerMap = reader.ReadInt32(); // Bitmask/flags indicating which channels are included in the file. var fmtSubFormatCode = reader.ReadInt16(); // Similar to container-level format code (1 = PCM, 3 = IEEE, etc.). var fmtSubFormatRemainder = reader.ReadBytes(14); // Remainder of SubFormat GUID. Usually just "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71". - // Above link says our AudioFormat dictates whether an extension chunk should actually exist, but we've been lenient to standards up to this point anyways. if (waveFmt.AudioFormat == 0xFFFE) + { waveFmt.AudioFormat = fmtSubFormatCode; + } if (fmtExtraSize > 22) // Read any leftovers + { reader.ReadBytes(fmtExtraSize - 22); + } } WaveFmt = waveFmt;