#![allow(dead_code)]
use std::str::*;
use std::ptr;
use std::ffi::CString;
use std::ffi::CStr;
use std::ops::BitOr;
use std::i32::*;
use std::intrinsics::transmute;
#[doc(hidden)]
mod libsndfile {
#[link(name = "sndfile")]
extern {}
}
#[doc(hidden)]
#[path = "sndfile_ffi.rs"]
mod ffi;
#[repr(C)]
#[derive(Clone)]
pub struct SndInfo {
pub frames : i64,
pub samplerate : i32,
pub channels : i32,
pub format : i32,
pub sections : i32,
pub seekable : i32
}
#[derive(Copy, Clone)]
pub enum OpenMode {
Read = ffi::SFM_READ as isize,
Write = ffi::SFM_WRITE as isize,
ReadWrite = ffi::SFM_RDWR as isize
}
#[derive(Copy, Clone)]
pub enum StringSoundType {
Title = ffi::SF_STR_TITLE as isize,
Copyright = ffi::SF_STR_COPYRIGHT as isize,
Software = ffi::SF_STR_SOFTWARE as isize,
Artist = ffi::SF_STR_ARTIST as isize,
Comment = ffi::SF_STR_COMMENT as isize,
Date = ffi::SF_STR_DATE as isize,
Album = ffi::SF_STR_ALBUM as isize,
License = ffi::SF_STR_LICENSE as isize,
TrackNumber = ffi::SF_STR_TRACKNUMBER as isize,
Genre = ffi::SF_STR_GENRE as isize
}
#[repr(C)]
#[derive(Copy, Clone)]
pub enum Error {
NoError = ffi::SF_ERR_NO_ERROR as isize,
UnrecognizedFormat = ffi::SF_ERR_UNRECOGNISED_FORMAT as isize,
SystemError = ffi::SF_ERR_SYSTEM as isize,
MalformedFile = ffi::SF_ERR_MALFORMED_FILE as isize,
UnsupportedEncoding = ffi::SF_ERR_UNSUPPORTED_ENCODING as isize,
}
#[derive(Copy, Clone)]
pub enum SeekMode {
SeekSet = ffi::SEEK_SET as isize,
SeekCur = ffi::SEEK_CUR as isize,
SeekEnd = ffi::SEEK_END as isize
}
#[repr(C)]
#[derive(Debug, Clone, PartialOrd, PartialEq, Copy)]
pub enum FormatType {
FormatWav = ffi::SF_FORMAT_WAV as isize,
FormatAiff = ffi::SF_FORMAT_AIFF as isize,
FormatAu = ffi::SF_FORMAT_AU as isize,
FormatRaw = ffi::SF_FORMAT_RAW as isize,
FormatPaf = ffi::SF_FORMAT_PAF as isize,
FormatSvx = ffi::SF_FORMAT_SVX as isize,
FormatNist = ffi::SF_FORMAT_NIST as isize,
FormatVoc = ffi::SF_FORMAT_VOC as isize,
FormatIrcam = ffi::SF_FORMAT_IRCAM as isize,
FormatW64 = ffi::SF_FORMAT_W64 as isize,
FormatMat4 = ffi::SF_FORMAT_MAT4 as isize,
FormatMat5 = ffi::SF_FORMAT_MAT5 as isize,
FormatPvf = ffi::SF_FORMAT_PVF as isize,
FormatXi = ffi::SF_FORMAT_XI as isize,
FormatHtk = ffi::SF_FORMAT_HTK as isize,
FormatSds = ffi::SF_FORMAT_SDS as isize,
FormatAvr = ffi::SF_FORMAT_AVR as isize,
FormatWavex = ffi::SF_FORMAT_WAVEX as isize,
FormatSd2 = ffi::SF_FORMAT_SD2 as isize,
FormatFlac = ffi::SF_FORMAT_FLAC as isize,
FormatCaf = ffi::SF_FORMAT_CAF as isize,
FormatWve = ffi::SF_FORMAT_WVE as isize,
FormatOgg = ffi::SF_FORMAT_OGG as isize,
FormatMpc2k = ffi::SF_FORMAT_MPC2K as isize,
FormatRf64 = ffi::SF_FORMAT_RF64 as isize,
FormatPcmS8 = ffi::SF_FORMAT_PCM_S8 as isize,
FormatPcm16 = ffi::SF_FORMAT_PCM_16 as isize,
FormatPcm24 = ffi::SF_FORMAT_PCM_24 as isize,
FormatPcm32 = ffi::SF_FORMAT_PCM_32 as isize,
FormatPcmU8 = ffi::SF_FORMAT_PCM_U8 as isize,
FormatFloat = ffi::SF_FORMAT_FLOAT as isize,
FormatDouble = ffi::SF_FORMAT_DOUBLE as isize,
FormatUlaw = ffi::SF_FORMAT_ULAW as isize,
FormatAlaw = ffi::SF_FORMAT_ALAW as isize,
FormatImaAdpcm = ffi::SF_FORMAT_IMA_ADPCM as isize,
FormatApcm = ffi::SF_FORMAT_MS_ADPCM as isize,
FormatGsm610 = ffi::SF_FORMAT_GSM610 as isize,
FormatVoxAdpcm = ffi::SF_FORMAT_VOX_ADPCM as isize,
FormatG72132 = ffi::SF_FORMAT_G721_32 as isize,
FormatG72324 = ffi::SF_FORMAT_G723_24 as isize,
FormatG72340 = ffi::SF_FORMAT_G723_40 as isize,
FormatDww12 = ffi::SF_FORMAT_DWVW_12 as isize,
FormatDww16 = ffi::SF_FORMAT_DWVW_16 as isize,
FormatDww24 = ffi::SF_FORMAT_DWVW_24 as isize,
FormatDwwN = ffi::SF_FORMAT_DWVW_N as isize,
FormatDpcm8 = ffi::SF_FORMAT_DPCM_8 as isize,
FormatDpcm16 = ffi::SF_FORMAT_DPCM_16 as isize,
FormatVorbis = ffi::SF_FORMAT_VORBIS as isize,
EndianFile = ffi::SF_ENDIAN_FILE as isize,
EndianLittle = ffi::SF_ENDIAN_LITTLE as isize,
EndianBig = ffi::SF_ENDIAN_BIG as isize,
EndianCpu = ffi::SF_ENDIAN_CPU as isize,
FormatSubMask = ffi::SF_FORMAT_SUBMASK as isize,
FormatTypeMask = ffi::SF_FORMAT_TYPEMASK as isize,
}
impl BitOr for FormatType {
type Output = FormatType;
fn bitor(self, _rhs: FormatType) -> Self::Output {
unsafe { transmute((self as i32) | (_rhs as i32)) }
}
}
pub struct SndFile {
handle : ffi::SNDFILEhandle, info : Box<SndInfo>
}
impl Clone for SndFile {
fn clone(&self) -> SndFile {
SndFile {
handle : self.handle,
info : self.info.clone()
}
}
}
impl SndFile {
pub fn new(path : &str, mode : OpenMode) -> Result<SndFile, String> {
let mut info = Box::new(SndInfo {
frames : 0,
samplerate : 0,
channels : 0,
format : 0,
sections : 0,
seekable : 0
});
let c_path = CString::new(path).unwrap();
let tmp_sndfile = {
unsafe {ffi::sf_open(c_path.as_ptr() as *mut _, mode as i32, &mut *info) }
};
if tmp_sndfile == 0 {
Err(unsafe {
from_utf8(CStr::from_ptr(ffi::sf_strerror(0) as *const _).to_bytes()).unwrap().to_owned()
})
} else {
Ok(SndFile {
handle : tmp_sndfile,
info : info
})
}
}
pub fn new_with_info(path : &str, mode : OpenMode, mut info: Box<SndInfo>) -> Result<SndFile, String> {
let c_path = CString::new(path).unwrap();
let tmp_sndfile = {
unsafe {ffi::sf_open(c_path.as_ptr() as *mut _, mode as i32, &mut *info) }
};
if tmp_sndfile == 0 {
Err(unsafe {
from_utf8(CStr::from_ptr(ffi::sf_strerror(0) as *const _).to_bytes()).unwrap().to_owned()
})
} else {
Ok(SndFile {
handle : tmp_sndfile,
info : info
})
}
}
pub fn new_with_fd(fd : i32,
mode : OpenMode,
close_desc : bool)
-> Result<SndFile, String> {
let mut info = Box::new(SndInfo {
frames : 0,
samplerate : 0,
channels : 0,
format : 0,
sections : 0,
seekable : 0
});
let tmp_sndfile = match close_desc {
true => unsafe {
ffi::sf_open_fd(fd, mode as i32, &mut *info, ffi::SF_TRUE)
},
false => unsafe {
ffi::sf_open_fd(fd, mode as i32, &mut *info, ffi::SF_FALSE)
}
};
if tmp_sndfile == 0 {
Err(unsafe {
from_utf8(CStr::from_ptr(ffi::sf_strerror(0) as *const _).to_bytes()).unwrap().to_owned()
})
} else {
Ok(SndFile {
handle : tmp_sndfile,
info : info
})
}
}
pub fn get_sndinfo(&self) -> SndInfo {
*self.info.clone()
}
pub fn get_string(&self, string_type : StringSoundType) -> Option<String> {
let c_string = unsafe {
ffi::sf_get_string(self.handle, string_type as i32)
};
if c_string == ptr::null_mut() {
None
} else {
Some(unsafe {
from_utf8(CStr::from_ptr(c_string as *const _).to_bytes()).unwrap().to_owned()
})
}
}
pub fn set_string(&mut self,
string_type : StringSoundType,
string : String) -> Error {
unsafe {
ffi::sf_set_string(self.handle,
string_type as i32,
string.as_ptr() as *mut _)
}
}
pub fn check_format<'r>(info : &'r mut SndInfo) -> bool {
match unsafe {ffi::sf_format_check(info) } {
ffi::SF_TRUE => true,
ffi::SF_FALSE => false,
_ => unreachable!()
}
}
pub fn close(&self) -> Error {
unsafe {
ffi::sf_close(self.handle)
}
}
pub fn write_sync(&mut self) -> () {
unsafe {
ffi::sf_write_sync(self.handle)
}
}
pub fn seek(&mut self, frames : i64, whence : SeekMode) -> i64{
unsafe {
ffi::sf_seek(self.handle, frames, whence as i32)
}
}
pub fn read_i16<'r>(&'r mut self, array : &'r mut [i16], items : i64) -> i64 {
unsafe {
ffi::sf_read_short(self.handle, array.as_mut_ptr(), items)
}
}
pub fn read_int<'r>(&'r mut self, array : &'r mut [i32], items : i64) -> i64 {
unsafe {
ffi::sf_read_int(self.handle, array.as_mut_ptr(), items)
}
}
pub fn read_f32<'r>(&'r mut self, array : &'r mut [f32], items : i64) -> i64 {
unsafe {
ffi::sf_read_float(self.handle, array.as_mut_ptr(), items)
}
}
pub fn read_f64<'r>(&'r mut self, array : &'r mut [f64], items : i64) -> i64 {
unsafe {
ffi::sf_read_double(self.handle, array.as_mut_ptr(), items)
}
}
pub fn readf_i16<'r>(&'r mut self, array : &'r mut [i16], frames : i64) -> i64 {
unsafe {
ffi::sf_readf_short(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn readf_int<'r>(&'r mut self, array : &'r mut [i32], frames : i64) -> i64 {
unsafe {
ffi::sf_readf_int(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn readf_f32<'r>(&'r mut self, array : &'r mut [f32], frames : i64) -> i64 {
unsafe {
ffi::sf_readf_float(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn readf_f64<'r>(&'r mut self, array : &'r mut [f64], frames : i64) -> i64 {
unsafe {
ffi::sf_readf_double(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn write_i16<'r>(&'r mut self, array : &'r mut [i16], items : i64) -> i64 {
unsafe {
ffi::sf_write_short(self.handle, array.as_mut_ptr(), items)
}
}
pub fn write_int<'r>(&'r mut self, array : &'r mut [i32], items : i64) -> i64 {
unsafe {
ffi::sf_write_int(self.handle, array.as_mut_ptr(), items)
}
}
pub fn write_f32<'r>(&'r mut self, array : &'r mut [f32], items : i64) -> i64 {
unsafe {
ffi::sf_write_float(self.handle, array.as_mut_ptr(), items)
}
}
pub fn write_f64<'r>(&'r mut self, array : &'r mut [f64], items : i64) -> i64 {
unsafe {
ffi::sf_write_double(self.handle, array.as_mut_ptr(), items)
}
}
pub fn writef_i16<'r>(&'r mut self, array : &'r mut [i16], frames : i64) -> i64 {
unsafe {
ffi::sf_writef_short(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn writef_int<'r>(&'r mut self, array : &'r mut [i32], frames : i64) -> i64 {
unsafe {
ffi::sf_writef_int(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn writef_f32<'r>(&'r mut self, array : &'r mut [f32], frames : i64) -> i64 {
unsafe {
ffi::sf_writef_float(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn writef_f64<'r>(&'r mut self, array : &'r mut [f64], frames : i64) -> i64 {
unsafe {
ffi::sf_writef_double(self.handle, array.as_mut_ptr(), frames)
}
}
pub fn error(&self) -> Error {
unsafe {
ffi::sf_error(self.handle)
}
}
pub fn string_error(&self) -> String {
unsafe {
from_utf8(CStr::from_ptr(ffi::sf_strerror(self.handle) as *const _).to_bytes()).unwrap().to_owned()
}
}
pub fn error_number(error_num : Error) -> String {
unsafe {
from_utf8(CStr::from_ptr(ffi::sf_error_number(error_num as i32) as *const _).to_bytes()).unwrap().to_owned()
}
}
}