80afd5cbf37436a5f4090b39eba68c639afe26e3
[mandelwow.git] / sound.rs
1 #[macro_use]
2
3 use libxm::XMContext;
4 use sdl2;
5 use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired};
6 use std::fs::File;
7 use std::io::Read;
8
9
10 struct XmCallback {
11     xm: XMContext,
12 }
13
14 impl AudioCallback for XmCallback {
15     type Channel = f32;
16
17     fn callback(&mut self, out: &mut [f32]) {
18         self.xm.generate_samples(out);
19     }
20 }
21
22 pub struct SoundPlayer {
23     _device: AudioDevice<XmCallback>,
24 }
25
26 fn play_xm(raw_xm: &[u8]) -> SoundPlayer {
27     let sdl_context = sdl2::init().unwrap();
28     let sdl_audio = sdl_context.audio().unwrap();
29
30     let sample_rate = 48000u32;
31     let desired_spec = AudioSpecDesired {
32         freq: Some(sample_rate as i32),
33         channels: Some(2u8),
34         samples: None,
35     };
36     let device = sdl_audio.open_playback(None, &desired_spec, |actual_spec| {
37         let xm = XMContext::new(&raw_xm, actual_spec.freq as u32).unwrap();
38
39         XmCallback {
40             xm: xm,
41         }
42     }).unwrap();
43
44     device.resume();
45
46     SoundPlayer {
47         _device: device,
48     }
49 }
50
51 pub fn start() -> SoundPlayer {
52     let mut xm = Vec::new();
53     let filename = "flora.xm";
54     File::open(filename).unwrap()
55         .read_to_end(&mut xm).unwrap();
56     return play_xm(&xm);
57 }