diff --git a/DeepDrftTests/AudioProcessorTests.cs b/DeepDrftTests/AudioProcessorTests.cs index 0fd5223..04cce45 100644 --- a/DeepDrftTests/AudioProcessorTests.cs +++ b/DeepDrftTests/AudioProcessorTests.cs @@ -74,6 +74,14 @@ public class AudioProcessorTests Assert.That(ReadFmtAudioFormat(audio.Buffer), Is.EqualTo(WaveFormatPcm)); // 4 float samples (4 bytes each) → 4 PCM samples (3 bytes each) = 12 data bytes after the 44-byte header. Assert.That(audio.Buffer.Length, Is.EqualTo(44 + 12)); + // Verify the converted sample values: (int)(sample * 8388607.0), clamped, little-endian 3 bytes. + // 0.5f → 4194303 = 0x3FFFFF → FF FF 3F + // -0.5f → -4194303 = 0xFFC00001 → 24-bit LE: 01 00 C0 + // 1.0f → 8388607 = 0x7FFFFF → FF FF 7F + // -1.0f → -8388607 = 0xFF800001 → 24-bit LE: 01 00 80 + var expectedData = new byte[] { 0xFF, 0xFF, 0x3F, 0x01, 0x00, 0xC0, 0xFF, 0xFF, 0x7F, 0x01, 0x00, 0x80 }; + var actualData = audio.Buffer[44..]; + Assert.That(actualData, Is.EqualTo(expectedData), "Float samples must be converted to 24-bit PCM correctly"); } [Test] @@ -93,6 +101,14 @@ public class AudioProcessorTests Assert.That(ReadFmtAudioFormat(audio.Buffer), Is.EqualTo(WaveFormatPcm)); // 4 container samples (4 bytes each) → 4 PCM samples (3 bytes each) = 12 data bytes. Assert.That(audio.Buffer.Length, Is.EqualTo(44 + 12)); + // Verify the repacked sample values: lowest 3 bytes of each 4-byte little-endian container. + // 0x123456 → LE 4 bytes: 56 34 12 00 → keep 3: 56 34 12 + // 0xFFEDCBA9 → LE 4 bytes: A9 CB ED FF → keep 3: A9 CB ED + // 0x000001 → LE 4 bytes: 01 00 00 00 → keep 3: 01 00 00 + // 0xFF800000 → LE 4 bytes: 00 00 80 FF → keep 3: 00 00 80 + var expectedData = new byte[] { 0x56, 0x34, 0x12, 0xA9, 0xCB, 0xED, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80 }; + var actualData = audio.Buffer[44..]; + Assert.That(actualData, Is.EqualTo(expectedData), "Padded 24-in-32 samples must strip the padding byte correctly"); } [Test] @@ -123,6 +139,26 @@ public class AudioProcessorTests Assert.That(audio!.Duration, Is.EqualTo(180.0), "Undersized EXTENSIBLE fmt chunk must fall back to default metadata"); } + [Test] + public void TryExtractPcm_FloatWav_ReturnsNull() + { + var subFormat = SubFormatGuid(0x0003); + var wav = BuildMinimalWav(channels: 2, sampleRate: 44100, bitsPerSample: 32, audioFormat: WaveFormatExtensible, + subFormatGuid: subFormat, validBitsPerSample: 32); + var result = new AudioProcessor().TryExtractPcm(wav); + Assert.That(result, Is.Null); + } + + [Test] + public void TryExtractPcm_Padded24in32_ReturnsNull() + { + var subFormat = SubFormatGuid(WaveFormatPcm); + var wav = BuildMinimalWav(channels: 2, sampleRate: 44100, bitsPerSample: 32, audioFormat: WaveFormatExtensible, + subFormatGuid: subFormat, validBitsPerSample: 24); + var result = new AudioProcessor().TryExtractPcm(wav); + Assert.That(result, Is.Null); + } + // -- helpers -------------------------------------------------------------------------------- ///