diff --git a/crates/interchange/src/wav.rs b/crates/interchange/src/wav.rs
--- a/crates/interchange/src/wav.rs
+++ b/crates/interchange/src/wav.rs
@@ -50,6 +50,13 @@ pub fn parse_wav(b: &[u8]) -> Option<(Vec<u8>, u16, u32, u16)> {
             if tag != 1 && tag != 0xFFFE {
                 return None;
             }
+            if tag == 0xFFFE {
+                // The first two bytes of the sub-format GUID carry the real format code.
+                let sub = body.get(24..26)?;
+                if u16::from_le_bytes([sub[0], sub[1]]) != 1 {
+                    return None;
+                }
+            }
             fmt = Some((ch, sr, bits));
         } else if id == b"data" {
             let (ch, sr, bits) = fmt?;
diff --git a/crates/interchange/tests/it/main.rs b/crates/interchange/tests/it/main.rs
--- a/crates/interchange/tests/it/main.rs
+++ b/crates/interchange/tests/it/main.rs
@@ -10,3 +10,4 @@ mod otio;
 mod point_markers;
 mod support;
 mod uncarried_clips;
+mod wav_extensible;
diff --git a/crates/interchange/tests/it/wav_extensible.rs b/crates/interchange/tests/it/wav_extensible.rs
new file mode 100644
--- /dev/null
+++ b/crates/interchange/tests/it/wav_extensible.rs
@@ -0,0 +1,47 @@
+use filmcraft_interchange::wav::parse_wav;
+
+const TAIL: [u8; 12] = [0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71];
+
+fn extensible(sub_format: u16, fmt_len: usize) -> Vec<u8> {
+    let mut fmt = Vec::new();
+    fmt.extend_from_slice(&0xFFFEu16.to_le_bytes());
+    fmt.extend_from_slice(&1u16.to_le_bytes());
+    fmt.extend_from_slice(&48_000u32.to_le_bytes());
+    fmt.extend_from_slice(&192_000u32.to_le_bytes());
+    fmt.extend_from_slice(&4u16.to_le_bytes());
+    fmt.extend_from_slice(&32u16.to_le_bytes());
+    fmt.extend_from_slice(&22u16.to_le_bytes());
+    fmt.extend_from_slice(&32u16.to_le_bytes());
+    fmt.extend_from_slice(&4u32.to_le_bytes());
+    fmt.extend_from_slice(&sub_format.to_le_bytes());
+    fmt.extend_from_slice(&[0, 0]);
+    fmt.extend_from_slice(&TAIL);
+    fmt.truncate(fmt_len);
+    let mut v = b"RIFF".to_vec();
+    v.extend_from_slice(&((4 + 8 + fmt.len() + 8 + 4) as u32).to_le_bytes());
+    v.extend_from_slice(b"WAVEfmt ");
+    v.extend_from_slice(&(fmt.len() as u32).to_le_bytes());
+    v.extend_from_slice(&fmt);
+    v.extend_from_slice(b"data");
+    v.extend_from_slice(&4u32.to_le_bytes());
+    v.extend_from_slice(&[1, 2, 3, 4]);
+    v
+}
+
+#[test]
+fn extensible_float_is_rejected() {
+    assert!(parse_wav(&extensible(3, 40)).is_none());
+}
+
+#[test]
+fn extensible_pcm_is_accepted() {
+    let (pcm, ch, sr, bits) = parse_wav(&extensible(1, 40)).expect("pcm");
+    assert_eq!((pcm, ch, sr, bits), (vec![1, 2, 3, 4], 1, 48_000, 32));
+}
+
+#[test]
+fn extensible_truncated_does_not_panic() {
+    for n in 16..40 {
+        let _ = parse_wav(&extensible(3, n));
+    }
+}
