use ponko::*;
fn in_tick(f: impl FnMut(&mut Ctx) + 'static) {
Game::new("audio", 1, 1).sim_system(f).run_headless(1, |_| {});
}
fn wav(sample_rate: u32, samples: &[i16]) -> Vec<u8> {
let data_len = (samples.len() * 2) as u32;
let mut out = Vec::new();
out.extend_from_slice(b"RIFF");
out.extend_from_slice(&(36 + data_len).to_le_bytes());
out.extend_from_slice(b"WAVEfmt ");
out.extend_from_slice(&16u32.to_le_bytes());
out.extend_from_slice(&1u16.to_le_bytes()); out.extend_from_slice(&1u16.to_le_bytes()); out.extend_from_slice(&sample_rate.to_le_bytes());
out.extend_from_slice(&(sample_rate * 2).to_le_bytes());
out.extend_from_slice(&2u16.to_le_bytes());
out.extend_from_slice(&16u16.to_le_bytes());
out.extend_from_slice(b"data");
out.extend_from_slice(&data_len.to_le_bytes());
for s in samples {
out.extend_from_slice(&s.to_le_bytes());
}
out
}
fn temp_file(name: &str, bytes: &[u8]) -> String {
let path = std::env::temp_dir().join(format!("crabby-audio-{}-{name}", std::process::id()));
std::fs::write(&path, bytes).unwrap();
path.to_string_lossy().into_owned()
}
#[test]
fn generated_sounds_know_their_length() {
in_tick(|ctx| {
let beep = ctx.create_sound(8000, &vec![0.0; 4000]);
assert!((beep.seconds() - 0.5).abs() < 1e-3, "{}", beep.seconds());
let playing = ctx.play_sound(&beep);
ctx.stop_sound(playing); });
}
#[test]
fn wav_files_load() {
let path = temp_file("tone.wav", &wav(22_050, &vec![1000; 22_050 / 4]));
in_tick(move |ctx| {
let tone = ctx.load_sound(&path);
assert!((tone.seconds() - 0.25).abs() < 0.01, "{}", tone.seconds());
ctx.play_sound_ex(
&tone,
SoundParams {
volume: 0.5,
speed: 2.0,
looping: true,
},
);
});
}
#[test]
#[should_panic(expected = "could not decode the sound")]
fn files_that_are_not_sound_say_so() {
let path = temp_file("bad.ogg", b"this is not audio");
Game::new("audio", 1, 1).run_headless(0, move |ctx| {
ctx.load_sound(&path);
});
}
#[test]
#[should_panic(expected = "not found in assets/")]
fn missing_sounds_say_where_they_looked() {
Game::new("audio", 1, 1).run_headless(0, |ctx| {
ctx.load_sound("no-such-sound.ogg");
});
}
#[cfg(feature = "audio")]
#[test]
fn loading_a_sound_file_twice_gives_the_same_sound() {
let path = temp_file("twice.wav", &wav(22_050, &vec![1000; 2205]));
in_tick(move |ctx| {
let a = ctx.load_sound(&path);
let b = ctx.load_sound(&path);
assert_eq!(a, b);
assert_ne!(a, ctx.create_sound(8000, &[0.0; 80]));
});
}