1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// pub use crate::effects::*;
use std::convert::From;
use std::os::raw::*;
use std::{fmt, io};
use std::path::Path;

#[derive(Debug)]
pub enum SoloudError {
    IoError(io::Error),
    NullError(std::ffi::NulError),
    Internal(SoloudErrorKind),
    Unknown(String),
}

/// Error kinds enum for SoloudError
#[repr(i32)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum SoloudErrorKind {
    InvalidParameter = 1, // Some parameter is invalid
    FileNotFound = 2,     // File not found
    FileLoadFailed = 3,   // File found, but could not be loaded
    DllNotFound = 4,      // DLL not found, or wrong DLL
    OutOfMemory = 5,      // Out of memory
    NotImplemented = 6,   // Feature not implemented
    UnknownError = 7,     // Other error
}

impl SoloudErrorKind {
    pub fn from_i32(val: i32) -> SoloudErrorKind {
        unsafe { std::mem::transmute(val) }
    }
}

impl std::error::Error for SoloudError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            SoloudError::IoError(err) => Some(err),
            SoloudError::NullError(err) => Some(err),
            _ => None,
        }
    }
}

impl fmt::Display for SoloudError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SoloudError::IoError(ref err) => err.fmt(f),
            SoloudError::NullError(ref err) => err.fmt(f),
            SoloudError::Internal(ref err) => write!(f, "An internal error occured {:?}", err),
            SoloudError::Unknown(ref err) => write!(f, "An unknown error occurred {:?}", err),
        }
    }
}

impl From<io::Error> for SoloudError {
    fn from(err: io::Error) -> SoloudError {
        SoloudError::IoError(err)
    }
}

impl From<std::ffi::NulError> for SoloudError {
    fn from(err: std::ffi::NulError) -> SoloudError {
        SoloudError::NullError(err)
    }
}

#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub enum SoloudFlag {
    ClipRoundoff = 1,
    EnableVisualization = 2,
    LeftHanded3D = 4,
    NoFpuRegisterChange = 8,
}

impl std::ops::BitOr for SoloudFlag {
    type Output = Self;

    fn bitor(self, rhs: Self) -> Self {
        unsafe { std::mem::transmute(self as u32 | rhs as u32) }
    }
}

#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub enum WaveForm {
    Square = 0,
    Saw,
    Sin,
    Triangle,
    Bounce,
    Jaws,
    Humps,
    FSquare,
    FSaw,
}

#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub enum Resampler {
    Point,
    Linear,
    Catmullrom,
}

#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub enum AttenuationModel {
    // No attenuation
    NoAttenuation = 0,
    // Inverse distance attenuation model
    InverseDistance = 1,
    // Linear distance attenuation model
    LinearDistance = 2,
    // Exponential distance attenuation model
    ExponentialDistance = 3,
}

pub unsafe trait AudioExt {
    /// Creates a default initialized object
    fn default() -> Self;
    /// Sets the volume
    fn set_volume(&mut self, volume: f32);
    /// Set whether the audio is looping
    fn set_looping(&mut self, flag: bool);
    /// Set auto stop
    fn set_auto_stop(&mut self, flag: bool);
    /// Set 3D min and max distances
    fn set_3d_min_max_distance(&mut self, min_distance: f32, max_distance: f32);
    /// Set 3D attenuation
    fn set_3d_attenuation(&mut self, model: AttenuationModel, rolloff_factor: f32);
    /// Set 3D doppler factor
    fn set_3d_doppler_factor(&mut self, doppler_factor: f32);
    /// Set 3D listener relative
    fn set_3d_listener_relative(&mut self, flag: bool);
    /// Set 3D distance delay
    fn set_3d_distance_delay(&mut self, delay: i32);
    // /// Set 3D collider
    // fn set_3d_collider(&mut self, collider: Option<&AudioCollider>);
    // /// Set 3D attenuator
    // fn set_3d_attenuator(&mut self, attenuator: Option<&AudioAttenuator>);
    /// Set inaudible behavior
    fn set_inaudible_behavior(&mut self, must_tick: bool, kill: bool);
    /// Set a loop point
    fn set_loop_point(&mut self, loop_point: f64);
    /// Get the loop point
    fn loop_point(&self) -> f64;
    /// Set a filter, the filter_id is assigned by the developer and becomes the id for that filter,
    /// and to cancel pass None as a filter to the already assigned id
    fn set_filter<F: FilterExt>(&mut self, filter_id: u32, filter: Option<&F>);
    /// Stop
    fn stop(&mut self);
    /// Get the inner pointer
    /// # Safety
    /// The inner pointer should be modified with care!
    unsafe fn inner(&self) -> *mut *mut c_void;
}

pub unsafe trait LoadExt {
    /// Load audio from a file
    fn load<P: AsRef<Path>>(&mut self, path: P) -> Result<(), SoloudError>;
    /// Load audio from memory
    fn load_mem(&mut self, data: &[u8]) -> Result<(), SoloudError>;
    /// Load audio from memory with options to copy and/or take ownership
    /// # Safety
    /// The audio source should not be invalidated
    unsafe fn load_mem_ex(
        &mut self,
        data: &[u8],
        copy: bool,
        take_ownership: bool,
    ) -> Result<(), SoloudError>;
}

pub unsafe trait FilterExt {
    /// Creates a default initialized object
    fn default() -> Self;
    /// Get the param count
    fn param_count(&mut self) -> i32;
    /// Get the param name by index
    fn param_name(&mut self, param_idx: u32) -> Option<String>;
    /// Get the param type by index
    fn param_type(&mut self, param_idx: u32) -> crate::filter::ParamType;
    /// Get the maximum value of a parameter
    fn param_max(&mut self, param_idx: u32) -> f32;
    /// Get the minimum value of a parameter
    fn param_min(&mut self, param_idx: u32) -> f32;
    /// Get the inner pointer
    /// # Safety
    /// The inner pointer should be modified with care!
    unsafe fn inner(&self) -> *mut *mut c_void;
}

pub trait FilterAttr {
    /// Convert a filter attribute to a u32
    fn to_u32(self) -> u32;
}

pub unsafe trait FromExt: Sized {
    /// Helper methods for loading an audio source from a path
    fn from_path<P: AsRef<Path>>(p: P) -> Result<Self, SoloudError>;
    /// Helper methods for loading an audio source from memory
    fn from_mem(data: &[u8]) -> Result<Self, SoloudError>;
}

unsafe impl<T: AudioExt + LoadExt> FromExt for T {
    fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, SoloudError> {
        let mut x = Self::default();
        x.load(path.as_ref())?;
        Ok(x)
    }

    fn from_mem(data: &[u8]) -> Result<Self, SoloudError> {
        let mut x = Self::default();
        x.load_mem(data)?;
        Ok(x)
    }
}