1use std::ffi::c_float;
2use std::os::raw::{c_uchar, c_void, c_int, c_uint};
3use std::fs;
4
5#[derive(Default, Debug, Copy, Clone)]
6pub enum AudioUsage {
7 Static,
8 #[default]
9 Stream
10}
11
12#[repr(C)]
13#[derive(Debug, Copy, Clone)]
14pub struct AudioParams {
15 pub volume: c_float,
16 pub pitch: c_float,
17 pub loop_: c_uchar,
18}
19
20impl Default for AudioParams {
21 fn default() -> Self {
22 AudioParams {
23 volume: 1.0,
24 pitch: 0.0,
25 loop_: 0,
26 }
27 }
28}
29
30#[repr(C)]
31#[derive(Debug, Clone, Copy)]
32struct AudioData {
33 usage: c_int,
34 size: c_uint,
35 data: *mut c_void
36}
37
38impl Default for AudioData {
39 fn default() -> Self {
40 AudioData {
41 usage: 0,
42 size: 0,
43 data: std::ptr::null_mut()
44 }
45 }
46}
47
48#[repr(C)]
49#[derive(Debug, Copy, Clone)]
50struct Decoder([c_uchar; 10312]);
51impl Default for Decoder {
52 fn default() -> Self {
53 Decoder([0; 10312])
54 }
55}
56
57#[repr(C)]
58#[derive(Debug, Copy, Clone)]
59pub struct AudioBuffer {
60 id: u32,
61 playing: i8,
62 loaded: i8,
63 offset: u32,
64 params: AudioParams,
65 data: AudioData,
66 decoder: Decoder
67}
68
69impl ToString for AudioBuffer {
70 fn to_string(&self) -> String {
71 format!("{} {} {} {}", self.id, self.playing, self.loaded, self.data.size)
72 }
73}
74
75impl Default for AudioBuffer {
76 fn default() -> Self {
77 AudioBuffer {
78 id: 0,
79 playing: 0,
80 loaded: 0,
81 offset: 0,
82 params: AudioParams::default(),
83 data: AudioData::default(),
84 decoder: Decoder::default()
85 }
86 }
87}
88
89extern "C" {
90 fn core_init() -> c_int;
91 fn core_quit();
92
93 fn core_new_data_from_memory(data: *mut c_void, size: c_uint, usage: c_int) -> c_int;
97 fn core_release_data(id: c_int);
98 fn core_setup_free_buffer(data_id: c_int, params: *const AudioParams) -> c_int;
99
100 fn core_get_buffer(id: c_int) -> *mut AudioBuffer;
101}
102
103#[derive(Default, Debug, Copy, Clone)]
104pub struct Audio {
105 id: u32,
106 params: AudioParams
107}
108
109impl Audio {
110 pub fn play(&self) -> AudioInstance {
111 let id = unsafe { core_setup_free_buffer(self.id as c_int, &self.params) } as u32;
112 let buffer = get_buffer(id);
113 buffer.playing = 1;
114 AudioInstance(id)
115 }
116
117 pub fn free(&self) {
118 unsafe { core_release_data(self.id as i32) };
119 }
120
121 pub fn id(&self) -> u32 { self.id }
122
123 pub fn loop_(&self) -> bool {
124 self.params.loop_ == 1
125 }
126
127 pub fn set_loop(&mut self, val: bool) {
128 self.params.loop_ = val as u8;
129 }
130}
131
132#[derive(Default, Debug, Copy, Clone)]
133pub struct AudioInstance(u32);
134
135pub fn init() { unsafe { core_init(); } }
136pub fn quit() { unsafe { core_quit(); } }
137
138pub fn load(filename: &str, usage: AudioUsage) -> Result<Audio, String> {
139 let data = fs::read(filename)
140 .expect(filename);
141 let id = unsafe { core_new_data_from_memory(data.as_ptr() as *mut c_void, data.len() as u32, usage as i32) } as u32;
142
143 Ok(Audio {
144 id,
145 params: AudioParams::default()
146 })
147}
148
149fn get_buffer<'a>(id: u32) -> &'a mut AudioBuffer {
150 unsafe { core_get_buffer(id as c_int).as_mut().unwrap() }
151}
152
153impl AudioInstance {
154 fn get_buffer(&self) -> &mut AudioBuffer {
155 get_buffer(self.0)
156 }
157
158 pub fn resume(&self) {
159 let buffer = self.get_buffer();
160 buffer.playing = 1;
161 }
162
163 pub fn pause(&self) {
164 let buffer = self.get_buffer();
165 buffer.playing = 0;
166 }
167
168 pub fn stop(&self) {
169 let buffer = self.get_buffer();
170 buffer.playing = 0;
171 buffer.loaded = 0;
172 }
173
174 pub fn is_playing(&self) -> bool {
175 let buffer = self.get_buffer();
176 buffer.playing == 1
177 }
178
179 pub fn volume(&self) -> f32 { self.get_buffer().params.volume }
180 pub fn set_volume(&self, volume: f32) {
181 self.get_buffer().params.volume = volume;
182 }
183
184 pub fn looping(&self) -> bool { self.get_buffer().params.loop_ == 1 }
185 pub fn set_looping(&self, val: bool) {
186 self.get_buffer().params.loop_ = val as u8;
187 }
188}