use super::*;
#[test]
fn test_ng16_white_noise_flat_spectrum() {
let config = NoiseConfig::white();
let mut gen = NoiseGenerator::new(config).unwrap();
let mut all_samples = Vec::new();
for _ in 0..100 {
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
all_samples.extend_from_slice(&buffer);
}
let low_power = compute_band_power(&all_samples, 44100, 100.0, 1000.0);
let high_power = compute_band_power(&all_samples, 44100, 5000.0, 10000.0);
let ratio = low_power / high_power.max(1e-10);
assert!(
ratio > 0.1 && ratio < 10.0,
"White noise should be relatively flat: low/high ratio = {}",
ratio
);
}
#[test]
fn test_ng17_brown_noise_slope() {
let config = NoiseConfig::brown();
let mut gen = NoiseGenerator::new(config).unwrap();
let mut all_samples = Vec::new();
for _ in 0..100 {
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
all_samples.extend_from_slice(&buffer);
}
let low_power = compute_band_power(&all_samples, 44100, 100.0, 500.0);
let high_power = compute_band_power(&all_samples, 44100, 5000.0, 10000.0);
assert!(
low_power > high_power,
"Brown noise should emphasize low frequencies: low={}, high={}",
low_power,
high_power
);
}
#[test]
fn test_ng18_pink_noise_slope() {
let config = NoiseConfig::pink();
let mut gen = NoiseGenerator::new(config).unwrap();
let mut all_samples = Vec::new();
for _ in 0..100 {
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
all_samples.extend_from_slice(&buffer);
}
let low_power = compute_band_power(&all_samples, 44100, 100.0, 500.0);
let high_power = compute_band_power(&all_samples, 44100, 5000.0, 10000.0);
assert!(
low_power > high_power,
"Pink noise should emphasize low frequencies: low={}, high={}",
low_power,
high_power
);
}
#[test]
fn test_ng19_modulation_depth_zero_no_variation() {
let config = NoiseConfig::brown().with_modulation(0.0, 1.0).unwrap();
let mut gen = NoiseGenerator::new(config).unwrap();
let mut energies = Vec::new();
for _ in 0..20 {
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
let energy: f32 = buffer.iter().map(|x| x * x).sum();
energies.push(energy);
}
let mean_energy: f32 = energies.iter().sum::<f32>() / energies.len() as f32;
let variance: f32 = energies
.iter()
.map(|e| (e - mean_energy).powi(2))
.sum::<f32>()
/ energies.len() as f32;
let cv = variance.sqrt() / mean_energy;
assert!(
cv < 0.5,
"With modulation_depth=0, energy should be stable. CV={}",
cv
);
}
#[test]
fn test_ng20_modulation_affects_output() {
let config = NoiseConfig::brown()
.with_modulation(1.0, 5.0) .unwrap();
let mut gen = NoiseGenerator::new(config).unwrap();
let mut all_samples = Vec::new();
for _ in 0..20 {
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
all_samples.extend_from_slice(&buffer);
}
assert!(all_samples.len() >= 8820);
let energy: f32 = all_samples.iter().map(|x| x * x).sum();
assert!(energy > 0.0, "Output should not be silent with modulation");
}
#[test]
fn test_noise_generator_debug() {
let config = NoiseConfig::brown();
let gen = NoiseGenerator::new(config).unwrap();
let debug_str = format!("{:?}", gen);
assert!(debug_str.contains("NoiseGenerator"));
assert!(debug_str.contains("time"));
assert!(debug_str.contains("sample_counter"));
}
#[test]
fn test_from_apr_with_valid_model() {
use tempfile::NamedTempFile;
let n_freqs = 1024 / 2 + 1; let mlp = SpectralMLP::random_init(8, 64, n_freqs, 42);
let temp = NamedTempFile::new().unwrap();
mlp.save_apr(temp.path()).unwrap();
let config = NoiseConfig::brown();
let gen = NoiseGenerator::from_apr(temp.path(), config).unwrap();
let _buffer = vec![0.0; 1024];
gen.clone_config();
assert_eq!(gen.config().buffer_size, 1024);
}
#[test]
fn test_from_apr_dimension_mismatch() {
use tempfile::NamedTempFile;
let wrong_n_freqs = 256; let mlp = SpectralMLP::random_init(8, 64, wrong_n_freqs, 42);
let temp = NamedTempFile::new().unwrap();
mlp.save_apr(temp.path()).unwrap();
let config = NoiseConfig::brown(); let result = NoiseGenerator::from_apr(temp.path(), config);
assert!(result.is_err());
match result.unwrap_err() {
NoiseError::ModelError(msg) => {
assert!(msg.contains("n_freqs"));
}
_ => panic!("Expected ModelError"),
}
}
#[test]
fn test_with_mlp_valid() {
let config = NoiseConfig::brown();
let n_freqs = config.buffer_size / 2 + 1;
let mlp = SpectralMLP::random_init(8, 64, n_freqs, 42);
let mut gen = NoiseGenerator::with_mlp(config, mlp).unwrap();
let mut buffer = vec![0.0; 1024];
gen.generate(&mut buffer).unwrap();
for &sample in &buffer {
assert!(sample.is_finite());
}
}
#[test]
fn test_with_mlp_dimension_mismatch() {
let config = NoiseConfig::brown(); let wrong_mlp = SpectralMLP::random_init(8, 64, 256, 42);
let result = NoiseGenerator::with_mlp(config, wrong_mlp);
assert!(result.is_err());
match result.unwrap_err() {
NoiseError::ModelError(msg) => {
assert!(msg.contains("n_freqs"));
}
_ => panic!("Expected ModelError"),
}
}
#[test]
fn test_set_phase_seed() {
let config = NoiseConfig::brown();
let mut gen1 = NoiseGenerator::new(config.clone()).unwrap();
let mut gen2 = NoiseGenerator::new(config).unwrap();
gen1.set_phase_seed(99999);
gen2.set_phase_seed(99999);
let mut buf1 = vec![0.0; 1024];
let mut buf2 = vec![0.0; 1024];
gen1.generate(&mut buf1).unwrap();
gen2.generate(&mut buf2).unwrap();
for (a, b) in buf1.iter().zip(buf2.iter()) {
assert!((a - b).abs() < 1e-6, "Outputs differ: {} vs {}", a, b);
}
}
impl NoiseGenerator {
fn clone_config(&self) -> NoiseConfig {
self.config.clone()
}
}