119 lines
4.1 KiB
Rust
119 lines
4.1 KiB
Rust
pub(crate) fn append_processed_i16_bounded(
|
|
pcm_accum: &mut Vec<i16>,
|
|
frame: &[f32],
|
|
gain: f32,
|
|
) -> bool {
|
|
if (gain - 1.0).abs() < f32::EPSILON {
|
|
for src in frame.iter().copied() {
|
|
if pcm_accum.len() == pcm_accum.capacity() {
|
|
return true;
|
|
}
|
|
pcm_accum.push(crate::frame::f32_to_i16(src));
|
|
}
|
|
} else {
|
|
for src in frame.iter().copied() {
|
|
if pcm_accum.len() == pcm_accum.capacity() {
|
|
return true;
|
|
}
|
|
let scaled = (crate::frame::f32_to_i16(src) as f32) * gain;
|
|
pcm_accum.push(scaled.clamp(i16::MIN as f32, i16::MAX as f32) as i16);
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
pub(crate) fn append_i16_bounded(pcm_accum: &mut Vec<i16>, frame: &[i16]) -> bool {
|
|
for src in frame.iter().copied() {
|
|
if pcm_accum.len() == pcm_accum.capacity() {
|
|
return true;
|
|
}
|
|
pcm_accum.push(src);
|
|
}
|
|
false
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{append_i16_bounded, append_processed_i16_bounded};
|
|
|
|
#[test]
|
|
fn append_processed_i16_bounded_does_not_grow_when_full() {
|
|
let frame = [0.25_f32; crate::frame::FRAME_10MS_SAMPLES];
|
|
let mut accum = Vec::with_capacity(crate::frame::FRAME_10MS_SAMPLES / 2);
|
|
let warmed_capacity = accum.capacity();
|
|
let warmed_ptr = accum.as_ptr();
|
|
|
|
let dropped = append_processed_i16_bounded(&mut accum, &frame, 1.0);
|
|
|
|
assert!(dropped);
|
|
assert_eq!(accum.len(), warmed_capacity);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
}
|
|
|
|
#[test]
|
|
fn append_processed_i16_bounded_preserves_expected_10ms_append() {
|
|
let frame = [0.25_f32; crate::frame::FRAME_10MS_SAMPLES];
|
|
let mut accum = Vec::with_capacity(crate::frame::FRAME_20MS_SAMPLES * 2);
|
|
let warmed_capacity = accum.capacity();
|
|
let warmed_ptr = accum.as_ptr();
|
|
|
|
let dropped = append_processed_i16_bounded(&mut accum, &frame, 1.0);
|
|
|
|
assert!(!dropped);
|
|
assert_eq!(accum.len(), crate::frame::FRAME_10MS_SAMPLES);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
}
|
|
|
|
#[test]
|
|
fn append_i16_bounded_does_not_grow_when_preroll_exceeds_capacity() {
|
|
let frame = [7_i16; crate::frame::FRAME_10MS_SAMPLES];
|
|
let mut accum = Vec::with_capacity(crate::frame::FRAME_10MS_SAMPLES / 2);
|
|
let warmed_capacity = accum.capacity();
|
|
let warmed_ptr = accum.as_ptr();
|
|
|
|
let dropped = append_i16_bounded(&mut accum, &frame);
|
|
|
|
assert!(dropped);
|
|
assert_eq!(accum.len(), warmed_capacity);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
}
|
|
|
|
#[test]
|
|
fn append_i16_bounded_preserves_expected_10ms_append() {
|
|
let frame = [7_i16; crate::frame::FRAME_10MS_SAMPLES];
|
|
let mut accum = Vec::with_capacity(crate::frame::FRAME_20MS_SAMPLES * 2);
|
|
let warmed_capacity = accum.capacity();
|
|
let warmed_ptr = accum.as_ptr();
|
|
|
|
let dropped = append_i16_bounded(&mut accum, &frame);
|
|
|
|
assert!(!dropped);
|
|
assert_eq!(accum.len(), crate::frame::FRAME_10MS_SAMPLES);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
}
|
|
|
|
#[test]
|
|
fn append_i16_bounded_preserves_full_vad_preroll_window() {
|
|
let frame = [7_i16; crate::frame::FRAME_10MS_SAMPLES];
|
|
let mut accum = Vec::with_capacity(crate::frame::FRAME_10MS_SAMPLES * 16);
|
|
let warmed_capacity = accum.capacity();
|
|
let warmed_ptr = accum.as_ptr();
|
|
|
|
for _ in 0..16 {
|
|
assert!(!append_i16_bounded(&mut accum, &frame));
|
|
}
|
|
|
|
assert_eq!(accum.len(), crate::frame::FRAME_10MS_SAMPLES * 16);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
assert!(append_i16_bounded(&mut accum, &frame));
|
|
assert_eq!(accum.len(), warmed_capacity);
|
|
assert_eq!(accum.capacity(), warmed_capacity);
|
|
assert_eq!(accum.as_ptr(), warmed_ptr);
|
|
}
|
|
}
|