use std::env;
use std::io::{stdin, stdout, Read, Write};
use ausnd::{AuEvent, AuWriteInfo, AuStreamParser};
fn main() {
let mut volume_level = 1.0;
let mut noise_level = 0.0;
for arg in env::args() {
if arg.starts_with("-v") {
volume_level = arg[2..].parse().expect("Invalid volume value, should be a float");
} else if arg.starts_with("-n") {
noise_level = arg[2..].parse().expect("Invalid noise value, should be a float");
}
}
let mut writer: Option<ausnd::AuWriter<std::io::Stdout>> = None;
let mut rng: u32 = 1;
let mut streamer = AuStreamParser::new(|event| {
match event {
AuEvent::Header(h) => {
let stdout = stdout();
let winfo = AuWriteInfo {
channels: h.channels,
sample_rate: h.sample_rate,
sample_format: ausnd::SampleFormat::F32,
};
writer = Some(ausnd::AuWriter::new(stdout, &winfo)
.expect("Writer failed"));
},
AuEvent::DescData(_) => { },
AuEvent::SampleData(samples) => {
if let Some(w) = &mut writer {
for s in samples {
let sf32 = effect(simple_sample_to_f32(&s),
volume_level, noise_level, &mut rng);
w.write_samples_f32(&[ sf32 ]).expect("stdout write failed");
}
}
},
AuEvent::End => {
}
}
});
let mut stdin = stdin();
let mut buf = [0u8; 32];
loop {
match stdin.read(&mut buf) {
Ok(size) => {
if size == 0 {
break;
}
streamer.write(&buf[0..size]).expect("Write error");
},
Err(e) => {
eprintln!("ERROR: {:?}", e);
},
}
}
streamer.finalize();
}
fn effect(value: f32, volume: f32, noise: f32, rng: &mut u32) -> f32 {
value * volume + noise * pseudo_random(rng)
}
fn pseudo_random(rng: &mut u32) -> f32 {
*rng = rng.overflowing_mul(48271).0 % 0x7fff_ffff;
*rng as f32 / 0x8000_0000u32 as f32 * 2.0 - 1.0
}
fn simple_sample_to_f32(s: &ausnd::Sample) -> f32 {
match s {
ausnd::Sample::I8(s) => { *s as f32 / (1u32 << 7) as f32 },
ausnd::Sample::I16(s) => { *s as f32 / (1u32 << 15) as f32 },
ausnd::Sample::I24(s) => { *s as f32 / (1u32 << 23) as f32 },
ausnd::Sample::I32(s) => { (*s as f64 / (1u32 << 31) as f64) as f32 },
ausnd::Sample::F32(s) => { *s },
ausnd::Sample::F64(s) => { *s as f32 },
}
}