use crate::analyse::rms_db;
use crate::temporal::{HEAD_DURATION, TAIL_DURATION};
const WINDOW_MS: u32 = 50;
pub fn gate_to_room_tone(
samples: &mut [i16],
sample_rate: u32,
threshold_db: f32,
room_tone: &[i16],
) {
if room_tone.is_empty() {
return;
}
let window_size = ((sample_rate as usize) * WINDOW_MS as usize) / 1000;
if window_size == 0 {
return;
}
let mut tone_offset = 0usize;
for chunk in samples.chunks_mut(window_size) {
if rms_db(chunk) < threshold_db {
for s in chunk.iter_mut() {
*s = room_tone[tone_offset % room_tone.len()];
tone_offset += 1;
}
}
}
}
pub fn pad_bookends(samples: &mut [i16], sample_rate: u32, room_tone: &[i16]) {
if room_tone.is_empty() || samples.is_empty() {
return;
}
let head_samples = (sample_rate as usize * HEAD_DURATION.whole_milliseconds() as usize) / 1000;
let tail_samples = (sample_rate as usize * TAIL_DURATION.whole_milliseconds() as usize) / 1000;
let fade_samples = (sample_rate as usize * 10) / 1000;
let head_end = head_samples.min(samples.len());
for (i, s) in samples[..head_end].iter_mut().enumerate() {
let tone = room_tone[i % room_tone.len()];
if head_end > fade_samples && i >= head_end - fade_samples {
let t = (i - (head_end - fade_samples)) as f32 / fade_samples as f32;
*s = (tone as f32 * (1.0 - t) + *s as f32 * t).round() as i16;
} else {
*s = tone;
}
}
let len = samples.len();
let tail_start = len.saturating_sub(tail_samples);
let mut tone_offset = tail_start;
for (i, s) in samples[tail_start..].iter_mut().enumerate() {
let abs_i = tail_start + i;
let tone = room_tone[tone_offset % room_tone.len()];
tone_offset += 1;
if i < fade_samples && tail_start > 0 {
let t = i as f32 / fade_samples as f32;
*s = (*s as f32 * (1.0 - t) + tone as f32 * t).round() as i16;
} else {
*s = tone;
}
let _ = abs_i; }
}