3 use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired};
8 const SAMPLE_RATE: i32 = 48000;
14 impl AudioCallback for XmCallback {
17 fn callback(&mut self, out: &mut [f32]) {
18 self.xm.generate_samples(out);
22 pub struct SoundPlayer {
23 device: Option<AudioDevice<XmCallback>>,
26 fn play_xm(raw_xm: &[u8]) -> SoundPlayer {
27 let sdl_context = sdl2::init().unwrap();
28 let sdl_audio = sdl_context.audio().unwrap();
30 let desired_spec = AudioSpecDesired {
31 freq: Some(SAMPLE_RATE),
33 samples: Some(4096), // 85ms
35 let device = sdl_audio.open_playback(None, &desired_spec, |actual_spec| {
36 let xm = XMContext::new(&raw_xm, actual_spec.freq as u32).unwrap();
50 pub fn start() -> SoundPlayer {
51 let filename = "flora.xm";
52 match File::open(filename) {
53 Result::Ok(mut f) => {
54 let mut xm = Vec::new();
55 f.read_to_end(&mut xm).unwrap();
59 println!("Couldn't open module {}: {:?}", filename, err);
62 return SoundPlayer { device: None };
65 pub fn hit_event(player: &mut SoundPlayer) -> f32 {
67 let audio_device_lock = player.device.as_mut().unwrap().lock();
68 let xm_callback = audio_device_lock.deref();
69 let xm = &xm_callback.xm;
70 let n_samples = xm.latest_trigger_of_instrument(0x1D);
71 return n_samples as f32 / SAMPLE_RATE as f32;