#![deny(warnings)] #![allow(dead_code)] //! [TSM.ID].[11031972] -- Platform X Ecosystem //! xcu-opus-quantum -- Opus Audio Frame Handler with VAD #[derive(Debug)] pub enum OpusError { InvalidToc(String), FrameTooShort(String) } impl std::fmt::Display for OpusError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::InvalidToc(e)|Self::FrameTooShort(e) => write!(f, "{e}") } } } impl std::error::Error for OpusError {} #[derive(Debug, Clone, Copy, PartialEq)] pub enum OpusBandwidth { Narrowband, Mediumband, Wideband, Superwideband, Fullband } impl OpusBandwidth { pub fn sample_rate(&self) -> u32 { match self { Self::Narrowband=>8000, Self::Mediumband=>12000, Self::Wideband=>16000, Self::Superwideband=>24000, Self::Fullband=>48000 } } } #[derive(Debug, Clone)] pub struct OpusFrame { pub bandwidth: OpusBandwidth, pub channels: u8, pub frame_size_ms: f32, pub stereo: bool, pub payload: Vec } pub fn decode_toc(toc: u8) -> Result<(OpusBandwidth, bool, u8), OpusError> { let config = (toc >> 3) & 0x1F; let stereo = (toc >> 2) & 1 == 1; let frame_code = toc & 0x03; let bw = match config { 0..=3 => OpusBandwidth::Narrowband, 4..=7 => OpusBandwidth::Mediumband, 8..=11 => OpusBandwidth::Wideband, 12..=15 => OpusBandwidth::Superwideband, 16..=31 => OpusBandwidth::Fullband, _ => return Err(OpusError::InvalidToc(format!("config {config}"))) }; Ok((bw, stereo, frame_code)) } pub fn encode_toc(bw: &OpusBandwidth, stereo: bool, frame_code: u8) -> u8 { let config: u8 = match bw { OpusBandwidth::Narrowband=>0, OpusBandwidth::Mediumband=>4, OpusBandwidth::Wideband=>8, OpusBandwidth::Superwideband=>12, OpusBandwidth::Fullband=>16 }; (config << 3) | ((stereo as u8) << 2) | (frame_code & 0x03) } pub struct SilenceDetector { pub threshold: f64 } impl SilenceDetector { pub fn new(threshold: f64) -> Self { Self { threshold } } pub fn is_silence(&self, samples: &[i16]) -> bool { if samples.is_empty() { return true; } let energy: f64 = samples.iter().map(|&s| (s as f64) * (s as f64)).sum::() / samples.len() as f64; energy.sqrt() < self.threshold } } #[cfg(test)] mod tests { use super::*; #[test] fn test_toc_roundtrip() { let toc = encode_toc(&OpusBandwidth::Fullband, true, 1); let (bw, st, fc) = decode_toc(toc).unwrap(); assert_eq!(bw, OpusBandwidth::Fullband); assert!(st); assert_eq!(fc, 1); } #[test] fn test_silence() { let d = SilenceDetector::new(100.0); assert!(d.is_silence(&[0, 1, -1, 0, 2])); assert!(!d.is_silence(&[10000, -10000, 8000])); } }