From 8f96da8b2000fcf43d1c19ed3b9ae84b74c26284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Mon, 31 Mar 2025 08:53:24 +0900 Subject: [PATCH] fix: better mp3 detection; drop mp1/mp2 format test --- um_audio/src/lib.rs | 8 ++++++++ um_audio/src/sync_frame.rs | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/um_audio/src/lib.rs b/um_audio/src/lib.rs index f4af545..05f0454 100644 --- a/um_audio/src/lib.rs +++ b/um_audio/src/lib.rs @@ -103,4 +103,12 @@ mod tests { let result = detect_audio_type(mp3_data).expect("failed to parse mp3"); assert_eq!(result, AudioType::MP3); } + + #[test] + fn test_mp3_invalid_data() { + let mut mp3_data = [0; 4096]; + mp3_data[0..4].copy_from_slice(&[0xff; 4]); + let result = detect_audio_type(&mp3_data).expect("failed to parse mp3"); + assert_eq!(result, AudioType::Unknown); + } } diff --git a/um_audio/src/sync_frame.rs b/um_audio/src/sync_frame.rs index 45ee29a..b717554 100644 --- a/um_audio/src/sync_frame.rs +++ b/um_audio/src/sync_frame.rs @@ -1,11 +1,21 @@ pub const SYNC_FRAME_TEST_SIZE: usize = 0xff; pub fn is_mp3(magic: u32) -> bool { - // Frame sync should have the first 11 bits set to 1. - const MP3_AND_MASK: u32 = 0b1111_1111_1110_0000u32 << 16; - const MP3_EXPECTED: u32 = 0b1111_1111_1110_0000u32 << 16; + // Check for 11-bit sync word, followed by 2 bits of version, and 2 bits of layer. + // MPEG Version: MPEG Version 2 (ISO/IEC 13818-3) or MPEG Version 1 (ISO/IEC 11172-3) + const MP3_AND_MASK: u32 = 0b1111_1111_1111_0110u32 << 16; + const MP3_EXPECTED: u32 = 0b1111_1111_1111_0010u32 << 16; - (magic & MP3_AND_MASK) == MP3_EXPECTED + if (magic & MP3_AND_MASK) != MP3_EXPECTED { + return false; + } + + // Check for bitrate index and sampling rate frequency index. + let bitrate = ((magic >> 12) & 0b1111) as u8; + let sampling_rate = ((magic >> 10) & 0b11) as u8; + + // They should not be all 1s. + bitrate != 0b1111 && sampling_rate != 0b11 } pub fn is_aac(magic: u32) -> bool {