pub(super) use super::*;
use audio_codec::{Decoder, Encoder};
fn encode_telephony<E: Encoder>(encoder: &mut E, samples: &[i16]) -> Vec<u8> {
let n = encoder.max_encode_bytes(samples.len());
let mut out = vec![0u8; n];
let written = encoder
.encode_into(samples, &mut out)
.unwrap_or_else(|e| panic!("test encode failed: {e}"));
out.truncate(written);
out
}
fn decode_telephony_pcm<D: Decoder>(decoder: &mut D, data: &[u8]) -> Vec<i16> {
let n = decoder.max_decode_samples(data.len());
let mut pcm = vec![0i16; n];
let written = decoder
.decode_into(data, &mut pcm)
.unwrap_or_else(|e| panic!("test decode failed: {e}"));
pcm.truncate(written);
pcm
}
pub(super) fn make_wav_bytes(samples: &[i16], sample_rate: u32) -> Vec<u8> {
let data_size = (samples.len() * 2) as u32;
let file_size = 36 + data_size;
let mut buf = Vec::new();
buf.extend_from_slice(b"RIFF");
buf.extend_from_slice(&file_size.to_le_bytes());
buf.extend_from_slice(b"WAVE");
buf.extend_from_slice(b"fmt ");
buf.extend_from_slice(&16u32.to_le_bytes()); buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&sample_rate.to_le_bytes());
buf.extend_from_slice(&(sample_rate * 2).to_le_bytes()); buf.extend_from_slice(&2u16.to_le_bytes()); buf.extend_from_slice(&16u16.to_le_bytes()); buf.extend_from_slice(b"data");
buf.extend_from_slice(&data_size.to_le_bytes());
for &s in samples {
buf.extend_from_slice(&s.to_le_bytes());
}
buf
}
fn make_stereo_wav_from_frames(frames: &[(i16, i16)], sample_rate: u32) -> Vec<u8> {
let data_size = (frames.len() * 4) as u32; let file_size = 36 + data_size;
let mut buf = Vec::new();
buf.extend_from_slice(b"RIFF");
buf.extend_from_slice(&file_size.to_le_bytes());
buf.extend_from_slice(b"WAVE");
buf.extend_from_slice(b"fmt ");
buf.extend_from_slice(&16u32.to_le_bytes()); buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&2u16.to_le_bytes()); buf.extend_from_slice(&sample_rate.to_le_bytes());
buf.extend_from_slice(&(sample_rate * 4).to_le_bytes()); buf.extend_from_slice(&4u16.to_le_bytes()); buf.extend_from_slice(&16u16.to_le_bytes()); buf.extend_from_slice(b"data");
buf.extend_from_slice(&data_size.to_le_bytes());
for &(l, r) in frames {
buf.extend_from_slice(&l.to_le_bytes());
buf.extend_from_slice(&r.to_le_bytes());
}
buf
}
fn make_stereo_wav_bytes(left: &[i16], right: &[i16], sample_rate: u32) -> Vec<u8> {
assert_eq!(left.len(), right.len());
let num_samples = left.len();
let data_size = (num_samples * 4) as u32; let file_size = 36 + data_size;
let mut buf = Vec::with_capacity(file_size as usize);
buf.extend_from_slice(b"RIFF");
buf.extend_from_slice(&file_size.to_le_bytes());
buf.extend_from_slice(b"WAVE");
buf.extend_from_slice(b"fmt ");
buf.extend_from_slice(&16u32.to_le_bytes()); buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&2u16.to_le_bytes()); buf.extend_from_slice(&sample_rate.to_le_bytes());
buf.extend_from_slice(&(sample_rate * 4).to_le_bytes()); buf.extend_from_slice(&4u16.to_le_bytes()); buf.extend_from_slice(&16u16.to_le_bytes()); buf.extend_from_slice(b"data");
buf.extend_from_slice(&data_size.to_le_bytes());
for i in 0..num_samples {
buf.extend_from_slice(&left[i].to_le_bytes());
buf.extend_from_slice(&right[i].to_le_bytes());
}
buf
}
fn make_compressed_wav(tag: u16, sample_rate: u32, byte_rate: u32, payload: &[u8]) -> Vec<u8> {
let data_size = payload.len() as u32;
let mut buf = Vec::with_capacity(46 + payload.len());
buf.extend_from_slice(b"RIFF");
buf.extend_from_slice(&(38 + data_size).to_le_bytes());
buf.extend_from_slice(b"WAVE");
buf.extend_from_slice(b"fmt ");
buf.extend_from_slice(&18u32.to_le_bytes()); buf.extend_from_slice(&tag.to_le_bytes());
buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&sample_rate.to_le_bytes());
buf.extend_from_slice(&byte_rate.to_le_bytes());
buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&8u16.to_le_bytes()); buf.extend_from_slice(&0u16.to_le_bytes()); buf.extend_from_slice(b"data");
buf.extend_from_slice(&data_size.to_le_bytes());
buf.extend_from_slice(payload);
buf
}
fn test_tone_8k(n_samples: usize) -> Vec<i16> {
(0..n_samples)
.map(|i| ((i as f32 * 0.05).sin() * 12000.0) as i16)
.collect()
}
pub(super) fn best_lag_rmse(a: &[f32], b: &[f32], max_lag: usize) -> f64 {
let mut best = f64::INFINITY;
for lag in 0..=max_lag {
for (a_slice, b_slice) in [
(a.get(lag..).unwrap_or(&[]), b),
(a, b.get(lag..).unwrap_or(&[])),
] {
let n = a_slice.len().min(b_slice.len());
if n < 100 {
continue;
}
let mse = a_slice[..n]
.iter()
.zip(&b_slice[..n])
.map(|(x, y)| {
let d = f64::from(x - y);
d * d
})
.sum::<f64>()
/ n as f64;
best = best.min(mse.sqrt());
}
}
best
}
mod decode;
mod opus;
mod pcm;
mod resample;
mod stream;
mod telephony;