// Unit tests for shared audio transport metadata. // // Scope: exercise `common/src/audio_transport.rs` without GStreamer or network // dependencies. // Targets: `common/src/audio_transport.rs`. // Why: Opus should be evaluated as a transport codec without weakening the // known-good raw PCM microphone path. use lesavka_common::audio_transport::{ AudioTransportProfile, UpstreamAudioCodec, bundle_audio_profile, mark_bundle_audio_profile, mark_packet_opus, mark_packet_pcm_s16le, normalize_audio_encoding, packet_audio_profile, packet_is_raw_pcm_s16le, parse_upstream_audio_codec, }; use lesavka_common::lesavka::{AudioEncoding, AudioPacket, UpstreamMediaBundle}; #[test] fn opus_profile_is_low_bandwidth_without_changing_capture_clock() { let pcm = AudioTransportProfile::pcm_s16le(); let opus = AudioTransportProfile::opus_voice(); assert_eq!(pcm.sample_rate, 48_000); assert_eq!(opus.sample_rate, 48_000); assert_eq!(pcm.channels, 2); assert_eq!(opus.channels, 2); assert_eq!(pcm.frame_duration_us, 20_000); assert_eq!(opus.frame_duration_us, 20_000); assert_eq!(pcm.expected_payload_bytes(), 3_840); assert_eq!(opus.expected_payload_bytes(), 160); } #[test] fn unstamped_legacy_audio_remains_pcm_for_backward_compatibility() { let packet = AudioPacket::default(); assert_eq!( normalize_audio_encoding(packet.encoding), AudioEncoding::PcmS16le ); assert_eq!( packet_audio_profile(&packet), AudioTransportProfile::pcm_s16le() ); assert!(packet_is_raw_pcm_s16le(&packet)); } #[test] fn packet_and_bundle_metadata_can_select_opus_without_payload_guessing() { let packet = AudioPacket { encoding: AudioEncoding::Opus as i32, sample_rate: 48_000, channels: 2, frame_duration_us: 20_000, data: vec![0xaa; 160], ..AudioPacket::default() }; let bundle = UpstreamMediaBundle { audio_encoding: AudioEncoding::Opus as i32, audio_sample_rate: 48_000, audio_channels: 2, audio: vec![packet.clone()], ..UpstreamMediaBundle::default() }; assert_eq!( packet_audio_profile(&packet), AudioTransportProfile::opus_voice() ); assert_eq!( bundle_audio_profile(&bundle), AudioTransportProfile::opus_voice() ); assert!(!packet_is_raw_pcm_s16le(&packet)); } #[test] fn marking_helpers_keep_current_pcm_path_explicit() { let mut packet = AudioPacket { frame_duration_us: 10_000, ..AudioPacket::default() }; mark_packet_pcm_s16le(&mut packet); assert_eq!(packet.encoding, AudioEncoding::PcmS16le as i32); assert_eq!(packet.sample_rate, 48_000); assert_eq!(packet.channels, 2); assert_eq!( packet.frame_duration_us, 10_000, "caller-supplied packet duration should be preserved" ); let mut bundle = UpstreamMediaBundle::default(); mark_bundle_audio_profile(&mut bundle, AudioTransportProfile::pcm_s16le()); assert_eq!(bundle.audio_encoding, AudioEncoding::PcmS16le as i32); assert_eq!(bundle.audio_sample_rate, 48_000); assert_eq!(bundle.audio_channels, 2); } #[test] fn upstream_audio_codec_parser_keeps_opus_and_pcm_names_stable() { assert_eq!( parse_upstream_audio_codec("opus"), Some(UpstreamAudioCodec::Opus) ); assert_eq!( parse_upstream_audio_codec("raw"), Some(UpstreamAudioCodec::PcmS16le) ); assert_eq!(parse_upstream_audio_codec("aac"), None); let mut packet = AudioPacket { data: vec![0xaa; 160], ..AudioPacket::default() }; mark_packet_opus(&mut packet); assert_eq!(packet.encoding, AudioEncoding::Opus as i32); assert_eq!( packet_audio_profile(&packet), AudioTransportProfile::opus_voice() ); }