use libc::{c_float, size_t};
use std::mem;
use std::ffi::CString;
use std::io::{Read, Seek};
use audio::{SoundStatus, SoundSource};
use system::Time;
use sfml_types::Vector3f;
use system::inputstream::InputStream;
use traits::Wrappable;
use sfml_types::sfBool;
use csfml_audio_sys as ffi;
pub struct Music {
music: *mut ffi::sfMusic
}
impl Music {
pub fn new_from_file(filename: &str) -> Option<Music> {
let c_str = CString::new(filename.as_bytes()).unwrap().as_ptr();
let music_tmp: *mut ffi::sfMusic = unsafe {
ffi::sfMusic_createFromFile(c_str)
};
if music_tmp.is_null() {
None
} else {
Some(Music{
music: music_tmp
})
}
}
pub fn new_from_stream<T: Read + Seek>(stream: &mut T) -> Option<Music> {
let mut input_stream = InputStream::new(stream);
let music_tmp: *mut ffi::sfMusic = unsafe {
ffi::sfMusic_createFromStream(&mut input_stream.0)
};
if music_tmp.is_null() {
None
} else {
Some(Music{
music: music_tmp
})
}
}
pub fn new_from_memory(mem: &[u8]) -> Option<Music> {
let music_tmp = unsafe { ffi::sfMusic_createFromMemory(&mem[0], mem.len() as size_t) };
if music_tmp.is_null() {
None
} else {
Some(Music{
music: music_tmp
})
}
}
pub fn set_loop(&mut self, lloop: bool) {
unsafe { ffi::sfMusic_setLoop(self.music, sfBool::from_bool(lloop)) }
}
pub fn get_loop(&self) -> bool {
unsafe { ffi::sfMusic_getLoop(self.music) }.to_bool()
}
pub fn get_duration(&self) -> Time {
Wrappable::wrap( unsafe { ffi::sfMusic_getDuration(self.music) })
}
pub fn play(&mut self) {
unsafe {
ffi::sfMusic_play(self.music)
}
}
pub fn pause(&mut self) {
unsafe {
ffi::sfMusic_pause(self.music)
}
}
pub fn stop(&mut self) {
unsafe {
ffi::sfMusic_stop(self.music)
}
}
pub fn get_channel_count(&self) -> u32 {
unsafe {
ffi::sfMusic_getChannelCount(self.music) as u32
}
}
pub fn get_sample_rate(&self) -> u32 {
unsafe {
ffi::sfMusic_getSampleRate(self.music) as u32
}
}
pub fn get_status(&self) -> SoundStatus {
unsafe { mem::transmute(ffi::sfMusic_getStatus(self.music))}
}
pub fn get_playing_offset(&self) -> Time {
Wrappable::wrap(unsafe { ffi::sfMusic_getPlayingOffset(self.music) })
}
pub fn set_playing_offset(&mut self, time_offset: Time) {
unsafe {
ffi::sfMusic_setPlayingOffset(self.music, time_offset.unwrap())
}
}
}
impl SoundSource for Music {
fn set_pitch(&mut self, pitch: f32) {
unsafe {
ffi::sfMusic_setPitch(self.music, pitch as c_float)
}
}
fn set_volume(&mut self, volume: f32) {
unsafe {
ffi::sfMusic_setVolume(self.music, volume as c_float)
}
}
fn set_position(&mut self, position: &Vector3f) {
unsafe {
ffi::sfMusic_setPosition(self.music, *position)
}
}
fn set_position3f(&mut self, x: f32, y: f32, z: f32) {
unsafe {
ffi::sfMusic_setPosition(self.music, Vector3f::new(x, y, z))
}
}
fn set_relative_to_listener(&mut self, relative: bool) {
unsafe {
ffi::sfMusic_setRelativeToListener(self.music, sfBool::from_bool(relative))
}
}
fn set_min_distance(&mut self, distance: f32) {
unsafe {
ffi::sfMusic_setMinDistance(self.music, distance as c_float)
}
}
fn set_attenuation(&mut self, attenuation: f32) {
unsafe {
ffi::sfMusic_setAttenuation(self.music, attenuation as c_float)
}
}
fn get_pitch(&self) -> f32 {
unsafe {
ffi::sfMusic_getPitch(self.music) as f32
}
}
fn get_volume(&self) -> f32 {
unsafe {
ffi::sfMusic_getVolume(self.music) as f32
}
}
fn get_position(&self) -> Vector3f {
unsafe {
ffi::sfMusic_getPosition(self.music)
}
}
fn is_relative_to_listener(&self) -> bool {
unsafe {
ffi::sfMusic_isRelativeToListener(self.music).to_bool()
}
}
fn get_min_distance(&self) -> f32 {
unsafe {
ffi::sfMusic_getMinDistance(self.music) as f32
}
}
fn get_attenuation(&self) -> f32 {
unsafe {
ffi::sfMusic_getAttenuation(self.music) as f32
}
}
}
impl Drop for Music {
fn drop(&mut self) {
unsafe {
ffi::sfMusic_destroy(self.music);
}
}
}