1use fmod::{self, ChannelControl};
4
5#[derive(Debug, Default, PartialEq)]
21pub struct Voice {
22 channel : Option <fmod::Channel>,
23 channel_group : Option <fmod::ChannelGroup>
24}
25
26pub type IndexType = u16;
27#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
28pub struct Id (pub IndexType);
29
30impl Voice {
31 pub fn new() -> Self {
32 Voice::default()
33 }
34
35 pub fn channel (&self) -> Option <&fmod::Channel> {
36 self.channel.as_ref()
37 }
38
39 pub fn channel_mut (&mut self) -> Option <&mut fmod::Channel> {
40 self.channel.as_mut()
41 }
42
43 pub fn channel_group (&self) -> Option <&fmod::ChannelGroup> {
44 self.channel_group.as_ref()
45 }
46
47 pub fn channel_group_mut (&mut self) -> Option <&mut fmod::ChannelGroup> {
48 self.channel_group.as_mut()
49 }
50
51 pub fn is_playing (&self) -> Option <bool> {
52 if let Some (channel) = self.channel.as_ref() {
53 let playing = match channel.is_playing() {
54 Ok (playing) => playing,
55 Err (fmod::Error::ChannelStolen) |
56 Err (fmod::Error::InvalidHandle) => false,
57 Err (err) => unreachable!("err: {:?}", err)
58 };
59 Some (playing)
60 } else {
61 None
62 }
63 }
64 pub fn play (&mut self,
72 sound : &mut fmod::Sound,
73 mut channel_group : Option <fmod::ChannelGroup>
74 ) {
75 let _ = self.stop();
76 sound.set_mode (fmod::Mode::LOOP_OFF | fmod::Mode::_2D).unwrap();
77 self.channel = Some (sound.play (channel_group.as_mut(), false).unwrap());
78 self.channel_group = channel_group;
79 }
80
81 pub fn loop_ (&mut self,
86 sound : &mut fmod::Sound,
87 mut channel_group : Option <fmod::ChannelGroup>
88 ) {
89 let _ = self.stop();
90 sound.set_mode (fmod::Mode::LOOP_NORMAL | fmod::Mode::_2D).unwrap();
91 self.channel = Some (sound.play (channel_group.as_mut(), false).unwrap());
92 self.channel_group = channel_group;
93 }
94
95 pub fn play_from (&mut self,
100 sound : &mut fmod::Sound,
101 channel_group : Option <fmod::ChannelGroup>,
102 position : u32
103 ) {
104 let _ = self.stop();
105 self.cue (sound, channel_group);
106 assert!(!self.position (position, None).unwrap());
107 assert!(!self.resume().unwrap());
108 }
109
110 pub fn loop_from (&mut self,
118 sound : &mut fmod::Sound,
119 mut channel_group : Option <fmod::ChannelGroup>,
120 position : u32
121 ) {
122 let _ = self.stop();
123 sound.set_mode (fmod::Mode::LOOP_NORMAL | fmod::Mode::_2D).unwrap();
124 self.channel = Some (sound.play (channel_group.as_mut(), true).unwrap());
125 self.channel_group = channel_group;
126 assert!(!self.position (position, None).unwrap());
127 assert!(!self.resume().unwrap());
128 }
129
130 pub fn cue (&mut self,
132 sound : &mut fmod::Sound,
133 mut channel_group : Option <fmod::ChannelGroup>
134 ) {
135 let _ = self.stop();
136 sound.set_mode (fmod::Mode::LOOP_OFF | fmod::Mode::_2D).unwrap();
137 self.channel = Some (sound.play (channel_group.as_mut(), true).unwrap());
138 self.channel_group = channel_group;
139 }
140
141 pub fn trigger (&mut self) -> Option <bool> {
150 if let Some (mut channel) = self.channel.take() {
151 let playing = match channel.is_playing() {
152 Ok (playing) => {
153 channel.set_position (0, fmod::Timeunit::PCM).unwrap();
154 channel.set_paused (false).unwrap();
155 self.channel = Some (channel);
156 playing
157 }
158 Err (fmod::Error::ChannelStolen) |
159 Err (fmod::Error::InvalidHandle) => {
160 let mut sound = channel.sound_ref();
161 self.play (&mut sound, self.channel_group.clone());
162 false
163 }
164 Err (err) => unreachable!("err: {:?}", err)
165 };
166 Some (playing)
167 } else {
168 None
169 }
170 }
171
172 pub fn pause (&mut self) -> Option <bool> {
177 if let Some (mut channel) = self.channel.take() {
178 let playing = match channel.is_playing() {
179 Ok (playing) => {
180 channel.set_paused (true).unwrap();
181 self.channel = Some (channel);
182 playing
183 }
184 Err (fmod::Error::ChannelStolen) |
185 Err (fmod::Error::InvalidHandle) => {
186 let mut sound = channel.sound_ref();
187 self.cue (&mut sound, self.channel_group.clone());
188 false
189 }
190 Err (err) => unreachable!("err: {:?}", err)
191 };
192 Some (playing)
193 } else {
194 None
195 }
196 }
197
198 pub fn resume (&mut self) -> Option <bool> {
203 if let Some (mut channel) = self.channel.take() {
204 let playing = match channel.is_playing() {
205 Ok (playing) => {
206 channel.set_paused (false).unwrap();
207 self.channel = Some (channel);
208 playing
209 }
210 Err (fmod::Error::ChannelStolen) |
211 Err (fmod::Error::InvalidHandle) => {
212 let mut sound = channel.sound_ref();
213 self.play (&mut sound, self.channel_group.clone());
214 false
215 }
216 Err (err) => unreachable!("err: {:?}", err)
217 };
218 Some (playing)
219 } else {
220 None
221 }
222 }
223
224 pub fn position (&mut self,
231 position : u32, timeunit : Option <fmod::Timeunit>
232 ) -> Option <bool> {
233 if let Some (mut channel) = self.channel.take() {
234 let timeunit = timeunit.unwrap_or (fmod::Timeunit::PCM);
235 let playing = match channel.is_playing() {
236 Ok (playing) => {
237 channel.set_position (position, timeunit).unwrap();
238 self.channel = Some (channel);
239 playing
240 }
241 Err (fmod::Error::ChannelStolen) |
242 Err (fmod::Error::InvalidHandle) => {
243 let mut sound = channel.sound_ref();
244 self.cue (&mut sound, self.channel_group.clone());
245 self.channel.as_mut().unwrap().set_position (position, timeunit)
246 .unwrap();
247 false
248 }
249 Err (err) => unreachable!("err: {:?}", err)
250 };
251 Some (playing)
252 } else {
253 None
254 }
255 }
256
257 pub fn stop (&mut self) -> Option <bool> {
264 self.channel_group = None;
266 if let Some (mut channel) = self.channel.take() {
267 let playing = match channel.is_playing() {
268 Ok (playing) => {
269 channel.stop().unwrap();
270 playing
271 },
272 Err (fmod::Error::ChannelStolen) |
273 Err (fmod::Error::InvalidHandle) => false,
274 Err (err) => unreachable!("err: {:?}", err)
275 };
276 Some (playing)
277 } else {
278 None
279 }
280 }
281}
282
283impl Drop for Voice {
284 fn drop (&mut self) {
285 self.stop();
286 }
287}