use std::f32::consts::PI;
pub fn synth_wav_musical_light(sample_rate: u32, seconds: f32) -> Vec<u8> {
let channels: u16 = 2;
let bits_per_sample: u16 = 16;
let total_samples = (sample_rate as f32 * seconds) as usize;
let mut pcm = Vec::with_capacity(total_samples * channels as usize * 2);
for n in 0..total_samples {
let t = n as f32 / sample_rate as f32;
let carrier = (2.0 * PI * 220.0 * t).sin();
let overtone = (2.0 * PI * 440.0 * t).sin() * 0.45;
let shimmer = (2.0 * PI * 3.5 * t).sin() * 0.2;
let left = (carrier + overtone + shimmer).clamp(-1.0, 1.0);
let right = (carrier * 0.9 - overtone * 0.7 + shimmer).clamp(-1.0, 1.0);
let l_sample = (left * i16::MAX as f32 * 0.6) as i16;
let r_sample = (right * i16::MAX as f32 * 0.6) as i16;
pcm.extend_from_slice(&l_sample.to_le_bytes());
pcm.extend_from_slice(&r_sample.to_le_bytes());
}
let byte_rate = sample_rate * channels as u32 * (bits_per_sample as u32 / 8);
let block_align = channels * (bits_per_sample / 8);
let subchunk2_size = pcm.len() as u32;
let chunk_size = 36 + subchunk2_size;
let mut wav = Vec::with_capacity(44 + pcm.len());
wav.extend_from_slice(b"RIFF");
wav.extend_from_slice(&chunk_size.to_le_bytes());
wav.extend_from_slice(b"WAVE");
wav.extend_from_slice(b"fmt ");
wav.extend_from_slice(&16u32.to_le_bytes());
wav.extend_from_slice(&1u16.to_le_bytes());
wav.extend_from_slice(&channels.to_le_bytes());
wav.extend_from_slice(&sample_rate.to_le_bytes());
wav.extend_from_slice(&byte_rate.to_le_bytes());
wav.extend_from_slice(&block_align.to_le_bytes());
wav.extend_from_slice(&bits_per_sample.to_le_bytes());
wav.extend_from_slice(b"data");
wav.extend_from_slice(&subchunk2_size.to_le_bytes());
wav.extend_from_slice(&pcm);
wav
}
pub fn synth_y4m_musical_light(width: usize, height: usize, frames: usize, fps: usize) -> Vec<u8> {
let header = format!("YUV4MPEG2 W{width} H{height} F{fps}:1 Ip A1:1 C420jpeg\n");
let mut out =
Vec::with_capacity(header.len() + frames * (6 + width * height + (width * height) / 2));
out.extend_from_slice(header.as_bytes());
let y_len = width * height;
let uv_len = y_len / 4;
for frame in 0..frames {
out.extend_from_slice(b"FRAME\n");
for y in 0..height {
for x in 0..width {
let wave = (((x as f32 * 0.12) + (frame as f32 * 0.9)).sin() * 42.0)
+ (((y as f32 * 0.07) + (frame as f32 * 0.5)).cos() * 35.0);
let value = (128.0 + wave).clamp(0.0, 255.0) as u8;
out.push(value);
}
}
for i in 0..uv_len {
let phase = frame as f32 * 0.15 + i as f32 * 0.02;
let u = (128.0 + phase.sin() * 30.0).clamp(0.0, 255.0) as u8;
out.push(u);
}
for i in 0..uv_len {
let phase = frame as f32 * 0.18 + i as f32 * 0.023;
let v = (128.0 + phase.cos() * 26.0).clamp(0.0, 255.0) as u8;
out.push(v);
}
}
out
}
pub fn synth_symbolic_words(target_bytes: usize) -> Vec<u8> {
let mut out = Vec::with_capacity(target_bytes + 512);
let phrase = b"PARACLETIC-HYPERCUBE|music<->light<->words|";
while out.len() < target_bytes {
out.extend_from_slice(phrase);
out.push(b'\n');
}
out
}