120 lines
3.8 KiB
Rust
120 lines
3.8 KiB
Rust
// 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()
|
|
);
|
|
}
|