use fmod::{self, ChannelControl};
#[derive(Debug, Default, PartialEq)]
pub struct Voice {
channel : Option <fmod::Channel>,
channel_group : Option <fmod::ChannelGroup>
}
pub type IndexType = u16;
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Id (pub IndexType);
impl Voice {
pub fn new() -> Self {
Voice::default()
}
pub fn channel (&self) -> Option <&fmod::Channel> {
self.channel.as_ref()
}
pub fn channel_mut (&mut self) -> Option <&mut fmod::Channel> {
self.channel.as_mut()
}
pub fn channel_group (&self) -> Option <&fmod::ChannelGroup> {
self.channel_group.as_ref()
}
pub fn channel_group_mut (&mut self) -> Option <&mut fmod::ChannelGroup> {
self.channel_group.as_mut()
}
pub fn is_playing (&self) -> Option <bool> {
if let Some (channel) = self.channel.as_ref() {
let playing = match channel.is_playing() {
Ok (playing) => playing,
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => false,
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
pub fn play (&mut self,
sound : &mut fmod::Sound,
mut channel_group : Option <fmod::ChannelGroup>
) {
let _ = self.stop();
sound.set_mode (fmod::Mode::LOOP_OFF | fmod::Mode::_2D).unwrap();
self.channel = Some (sound.play (channel_group.as_mut(), false).unwrap());
self.channel_group = channel_group;
}
pub fn loop_ (&mut self,
sound : &mut fmod::Sound,
mut channel_group : Option <fmod::ChannelGroup>
) {
let _ = self.stop();
sound.set_mode (fmod::Mode::LOOP_NORMAL | fmod::Mode::_2D).unwrap();
self.channel = Some (sound.play (channel_group.as_mut(), false).unwrap());
self.channel_group = channel_group;
}
pub fn play_from (&mut self,
sound : &mut fmod::Sound,
channel_group : Option <fmod::ChannelGroup>,
position : u32
) {
let _ = self.stop();
self.cue (sound, channel_group);
assert!(!self.position (position, None).unwrap());
assert!(!self.resume().unwrap());
}
pub fn loop_from (&mut self,
sound : &mut fmod::Sound,
mut channel_group : Option <fmod::ChannelGroup>,
position : u32
) {
let _ = self.stop();
sound.set_mode (fmod::Mode::LOOP_NORMAL | fmod::Mode::_2D).unwrap();
self.channel = Some (sound.play (channel_group.as_mut(), true).unwrap());
self.channel_group = channel_group;
assert!(!self.position (position, None).unwrap());
assert!(!self.resume().unwrap());
}
pub fn cue (&mut self,
sound : &mut fmod::Sound,
mut channel_group : Option <fmod::ChannelGroup>
) {
let _ = self.stop();
sound.set_mode (fmod::Mode::LOOP_OFF | fmod::Mode::_2D).unwrap();
self.channel = Some (sound.play (channel_group.as_mut(), true).unwrap());
self.channel_group = channel_group;
}
pub fn trigger (&mut self) -> Option <bool> {
if let Some (mut channel) = self.channel.take() {
let playing = match channel.is_playing() {
Ok (playing) => {
channel.set_position (0, fmod::Timeunit::PCM).unwrap();
channel.set_paused (false).unwrap();
self.channel = Some (channel);
playing
}
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => {
let mut sound = channel.sound_ref();
self.play (&mut sound, self.channel_group.clone());
false
}
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
pub fn pause (&mut self) -> Option <bool> {
if let Some (mut channel) = self.channel.take() {
let playing = match channel.is_playing() {
Ok (playing) => {
channel.set_paused (true).unwrap();
self.channel = Some (channel);
playing
}
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => {
let mut sound = channel.sound_ref();
self.cue (&mut sound, self.channel_group.clone());
false
}
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
pub fn resume (&mut self) -> Option <bool> {
if let Some (mut channel) = self.channel.take() {
let playing = match channel.is_playing() {
Ok (playing) => {
channel.set_paused (false).unwrap();
self.channel = Some (channel);
playing
}
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => {
let mut sound = channel.sound_ref();
self.play (&mut sound, self.channel_group.clone());
false
}
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
pub fn position (&mut self,
position : u32, timeunit : Option <fmod::Timeunit>
) -> Option <bool> {
if let Some (mut channel) = self.channel.take() {
let timeunit = timeunit.unwrap_or (fmod::Timeunit::PCM);
let playing = match channel.is_playing() {
Ok (playing) => {
channel.set_position (position, timeunit).unwrap();
self.channel = Some (channel);
playing
}
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => {
let mut sound = channel.sound_ref();
self.cue (&mut sound, self.channel_group.clone());
self.channel.as_mut().unwrap().set_position (position, timeunit)
.unwrap();
false
}
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
pub fn stop (&mut self) -> Option <bool> {
self.channel_group = None;
if let Some (mut channel) = self.channel.take() {
let playing = match channel.is_playing() {
Ok (playing) => {
channel.stop().unwrap();
playing
},
Err (fmod::Error::ChannelStolen) |
Err (fmod::Error::InvalidHandle) => false,
Err (err) => unreachable!("err: {:?}", err)
};
Some (playing)
} else {
None
}
}
}
impl Drop for Voice {
fn drop (&mut self) {
self.stop();
}
}