rfmod/
dsp.rs

1/*
2* Rust-FMOD - Copyright (c) 2014 Gomez Guillaume.
3*
4* The Original software, FMOD library, is provided by FIRELIGHT TECHNOLOGIES.
5*
6* This software is provided 'as-is', without any express or implied warranty.
7* In no event will the authors be held liable for any damages arising from
8* the use of this software.
9*
10* Permission is granted to anyone to use this software for any purpose,
11* including commercial applications, and to alter it and redistribute it
12* freely, subject to the following restrictions:
13*
14* 1. The origin of this software must not be misrepresented; you must not claim
15*    that you wrote the original software. If you use this software in a product,
16*    an acknowledgment in the product documentation would be appreciated but is
17*    not required.
18*
19* 2. Altered source versions must be plainly marked as such, and must not be
20*    misrepresented as being the original software.
21*
22* 3. This notice may not be removed or altered from any source distribution.
23*/
24
25use ffi;
26use types::*;
27use callbacks::*;
28use dsp_connection;
29use fmod_sys;
30use fmod_sys::{MemoryUsageDetails, Sys};
31use std::mem::transmute;
32use channel;
33use libc::{c_char, c_void, c_uint, c_int, c_float};
34use std::default::Default;
35use c_vec::CVec;
36use std::ffi::CString;
37
38extern "C" fn create_callback(dsp_state: *mut ffi::FMOD_DSP_STATE) -> ::Status {
39    unsafe {
40        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
41            let mut tmp = ::std::ptr::null_mut();
42
43            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
44            if !tmp.is_null() {
45                let callbacks : &mut UserData = transmute(tmp);
46
47                match callbacks.callbacks.create_callback {
48                    Some(p) => p(&from_state_ptr(::std::ptr::read(
49                        dsp_state as *const ffi::FMOD_DSP_STATE))),
50                    None => ::Status::Ok
51                }
52            } else {
53              ::Status::Ok
54            }
55        } else {
56           ::Status::Ok
57        }
58    }
59}
60
61extern "C" fn release_callback(dsp_state: *mut ffi::FMOD_DSP_STATE) -> ::Status {
62    unsafe {
63        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
64            let mut tmp = ::std::ptr::null_mut();
65
66            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
67            if !tmp.is_null() {
68                let callbacks : &mut UserData = transmute(tmp);
69                
70                match callbacks.callbacks.release_callback {
71                    Some(p) => p(&from_state_ptr(::std::ptr::read(
72                        dsp_state as *const ffi::FMOD_DSP_STATE))),
73                    None => ::Status::Ok
74                }
75            } else {
76              ::Status::Ok
77            }
78        } else {
79           ::Status::Ok
80        }
81    }
82}
83
84extern "C" fn reset_callback(dsp_state: *mut ffi::FMOD_DSP_STATE) -> ::Status {
85    unsafe {
86        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
87            let mut tmp = ::std::ptr::null_mut();
88
89            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
90            if !tmp.is_null() {
91                let callbacks : &mut UserData = transmute(tmp);
92                
93                match callbacks.callbacks.reset_callback {
94                    Some(p) => p(&from_state_ptr(::std::ptr::read(
95                        dsp_state as *const ffi::FMOD_DSP_STATE))),
96                    None => ::Status::Ok
97                }
98            } else {
99              ::Status::Ok
100            }
101        } else {
102           ::Status::Ok
103        }
104    }
105}
106
107extern "C" fn read_callback(dsp_state: *mut ffi::FMOD_DSP_STATE, in_buffer: *mut c_float,
108                            out_buffer: *mut c_float, length: c_uint, in_channels: c_int,
109                            out_channels: c_int) -> ::Status {
110    unsafe {
111        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
112            let mut tmp = ::std::ptr::null_mut();
113
114            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
115            if !tmp.is_null() {
116                let callbacks : &mut UserData = transmute(tmp);
117                match callbacks.callbacks.read_callback {
118                    Some(p) => {
119                        let in_size = ((length as i32 - 1i32) * in_channels) + out_channels;
120                        let out_size = ((length as i32 - 1i32) * out_channels) + out_channels;
121                        let mut v_in_buffer = CVec::new(in_buffer,
122                                                        in_size as usize);
123                        let mut v_out_buffer = CVec::new(out_buffer, out_size as usize);
124
125                        p(&from_state_ptr(::std::ptr::read(
126                            dsp_state as *const ffi::FMOD_DSP_STATE)), v_in_buffer.as_mut(),
127                            v_out_buffer.as_mut(), length as u32, in_channels as i32,
128                            out_channels as i32)
129                    },
130                    None => ::Status::Ok
131                }
132            } else {
133              ::Status::Ok
134            }
135        } else {
136           ::Status::Ok
137        }
138    }
139}
140
141extern "C" fn set_position_callback(dsp_state: *mut ffi::FMOD_DSP_STATE, pos: c_uint) -> ::Status {
142    unsafe {
143        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
144            let mut tmp = ::std::ptr::null_mut();
145
146            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
147            if !tmp.is_null() {
148                let callbacks : &mut UserData = transmute(tmp);
149                
150                match callbacks.callbacks.set_pos_callback {
151                    Some(p) => p(&from_state_ptr(::std::ptr::read(
152                        dsp_state as *const ffi::FMOD_DSP_STATE)), pos as u32),
153                    None => ::Status::Ok
154                }
155            } else {
156              ::Status::Ok
157            }
158        } else {
159           ::Status::Ok
160        }
161    }
162}
163
164extern "C" fn set_parameter_callback(dsp_state: *mut ffi::FMOD_DSP_STATE, index: c_int,
165                                     value: c_float) -> ::Status {
166    unsafe {
167        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
168            let mut tmp = ::std::ptr::null_mut();
169
170            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
171            if !tmp.is_null() {
172                let callbacks : &mut UserData = transmute(tmp);
173                
174                match callbacks.callbacks.set_param_callback {
175                    Some(p) => p(&from_state_ptr(::std::ptr::read(
176                        dsp_state as *const ffi::FMOD_DSP_STATE)), index as i32, value),
177                    None => ::Status::Ok
178                }
179            } else {
180              ::Status::Ok
181            }
182        } else {
183           ::Status::Ok
184        }
185    }
186}
187
188extern "C" fn get_parameter_callback(dsp_state: *mut ffi::FMOD_DSP_STATE, index: c_int,
189                                     value: *mut c_float, value_str: *mut c_char) -> ::Status {
190    unsafe {
191        if !dsp_state.is_null() && !(*dsp_state).instance.is_null() {
192            let mut tmp = ::std::ptr::null_mut();
193
194            ffi::FMOD_DSP_GetUserData((*dsp_state).instance, &mut tmp);
195            if !tmp.is_null() {
196                let callbacks : &mut UserData = transmute(tmp);
197                match callbacks.callbacks.get_param_callback {
198                    Some(p) => {
199                        let mut t_value = *value;
200                        let l = ffi::strlen(value_str);
201                        let tmp = String::from_raw_parts(value_str as *mut u8, l, l);
202
203                        let ret = p(&from_state_ptr(::std::ptr::read(
204                            dsp_state as *const ffi::FMOD_DSP_STATE)), index as i32,
205                            &mut t_value, &tmp);
206                        *value = t_value;
207                        ret
208                    },
209                    None => ::Status::Ok
210                }
211            } else {
212              ::Status::Ok
213            }
214        } else {
215           ::Status::Ok
216        }
217    }
218}
219
220#[allow(unused_variables)]
221extern "C" fn config_callback(dsp_state: *mut ffi::FMOD_DSP_STATE, hwnd: *mut c_void,
222                              show: c_int) -> ::Status {
223   ::Status::Ok
224}
225
226struct UserData {
227    callbacks: DspCallbacks,
228    user_data: *mut c_void,
229}
230
231impl UserData {
232    fn new() -> UserData {
233        UserData {
234            callbacks: DspCallbacks::new(),
235            user_data: ::std::ptr::null_mut(),
236        }
237    }
238}
239
240struct DspCallbacks {
241    create_callback: DspCreateCallback,
242    release_callback: DspReleaseCallback,
243    reset_callback: DspResetCallback,
244    read_callback: DspReadCallback,
245    set_pos_callback: DspSetPositionCallback,
246    set_param_callback: DspSetParamCallback,
247    get_param_callback: DspGetParamCallback,
248}
249
250impl DspCallbacks {
251    fn new() -> DspCallbacks {
252        DspCallbacks {
253            create_callback: None,
254            release_callback: None,
255            reset_callback: None,
256            read_callback: None,
257            set_pos_callback: None,
258            set_param_callback: None,
259            get_param_callback: None,
260        }
261    }
262}
263
264impl Clone for DspCallbacks {
265    fn clone(&self) -> DspCallbacks {
266        DspCallbacks {
267            create_callback: self.create_callback,
268            release_callback: self.release_callback,
269            reset_callback: self.reset_callback,
270            read_callback: self.read_callback,
271            set_pos_callback: self.set_pos_callback,
272            set_param_callback: self.set_param_callback,
273            get_param_callback: self.get_param_callback,
274        }
275    }
276}
277
278#[derive(Debug, PartialEq, Clone)]
279/// Structure to define a parameter for a DSP unit.
280pub struct DspParameterDesc {
281    /// [w] Minimum value of the parameter (ie 100.0)
282    pub min         : f32,
283    /// [w] Maximum value of the parameter (ie 22050.0)
284    pub max         : f32,
285    /// [w] Default value of parameter
286    pub default_val : f32,
287    /// [w] Name of the parameter to be displayed (ie "Cutoff frequency")
288    pub name        : String,
289    /// [w] Short string to be put next to value to denote the unit type (ie "hz")
290    pub label       : String,
291    /// [w] Description of the parameter to be displayed as a help item / tooltip for this parameter
292    pub description : String,
293}
294
295impl Default for DspParameterDesc {
296    fn default() -> DspParameterDesc {
297        DspParameterDesc {
298            min: 0f32,
299            max: 0f32,
300            default_val: 0f32,
301            name: String::new(),
302            label: String::new(),
303            description: String::new(),
304        }
305    }
306}
307
308pub fn from_parameter_ptr(dsp_parameter: *mut ffi::FMOD_DSP_PARAMETERDESC) -> Result<DspParameterDesc, ::RStatus> {
309    if !dsp_parameter.is_null() {
310        let description = unsafe {
311            let l = ffi::strlen((*dsp_parameter).description);
312            String::from_raw_parts((*dsp_parameter).description as *mut u8, l, l)
313        };
314        let mut v1 : Vec<u8> = unsafe { Vec::with_capacity((*dsp_parameter).name.len()) };
315        let mut v2 : Vec<u8> = unsafe { Vec::with_capacity((*dsp_parameter).label.len()) };
316
317        unsafe {
318            for i in (*dsp_parameter).name.iter() {
319                if *i == 0 {
320                    break
321                }
322                v1.push(*i as u8);
323            }
324        }
325        let name = from_utf8!(v1);
326        unsafe {
327            for i in (*dsp_parameter).label.iter() {
328                if *i == 0 {
329                    break
330                }
331                v2.push(*i as u8);
332            }
333        }
334        let label = from_utf8!(v2);
335        unsafe {
336            Ok(DspParameterDesc {
337                min: (*dsp_parameter).min,
338                max: (*dsp_parameter).max,
339                default_val: (*dsp_parameter).default_val,
340                name,
341                label,
342                description,
343            })
344        }
345    } else {
346        Ok(Default::default())
347    }
348}
349
350pub fn get_parameter_ffi(dsp_parameter: &DspParameterDesc) -> Result<ffi::FMOD_DSP_PARAMETERDESC, ::RStatus> {
351    let mut tmp_name = dsp_parameter.name.as_bytes().to_vec();
352    let mut tmp_label = dsp_parameter.label.as_bytes().to_vec();
353    let tmp_description = match CString::new(dsp_parameter.description.clone()) {
354        Ok(s) => s,
355        Err(e) => return Err(::RStatus::Other(format!("Issue with dsp_parameter: {}", e))),
356    };
357
358    tmp_name.truncate(16);
359    tmp_label.truncate(16);
360    tmp_name.reserve_exact(16);
361    tmp_label.reserve_exact(16);
362    Ok(ffi::FMOD_DSP_PARAMETERDESC {
363        min: dsp_parameter.min,
364        max: dsp_parameter.max,
365        default_val: dsp_parameter.default_val,
366        name: {
367            let mut slice : [i8; 16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
368            let mut it = 0;
369
370            for tmp in tmp_name.iter() {
371                slice[it] = *tmp as i8;
372                it += 1;
373            }
374            slice
375        },
376        label: {
377            let mut slice : [i8; 16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
378            let mut it = 0;
379
380            for tmp in tmp_label.iter() {
381                slice[it] = *tmp as i8;
382                it += 1;
383            }
384            slice
385        },
386        description: tmp_description.as_ptr() as *const c_char,
387    })
388}
389
390/// When creating a DSP unit, declare one of these and provide the relevant callbacks and name for
391/// FMOD to use when it creates and uses a DSP unit of this type.
392pub struct DspDescription {
393    /// [w] Name of the unit to be displayed in the network.
394    pub name                : String,
395    /// [w] Plugin writer's version number.
396    pub version             : u32,
397    /// [w] Number of channels. Use 0 to process whatever number of channels is currently in the
398    /// network. > 0 would be mostly used if the unit is a unit that only generates sound.
399    pub channels            : i32,
400    /// [w] Create callback. This is called when DSP unit is created. Can be null.
401    pub create              : DspCreateCallback,
402    /// [w] Release callback. This is called just before the unit is freed so the user can do any
403    /// cleanup needed for the unit. Can be null.
404    pub release             : DspReleaseCallback,
405    /// [w] Reset callback. This is called by the user to reset any history buffers that may need
406    /// resetting for a filter, when it is to be used or re-used for the first time to its initial
407    /// clean state. Use to avoid clicks or artifacts.
408    pub reset               : DspResetCallback,
409    /// [w] Read callback. Processing is done here. Can be null.
410    pub read                : DspReadCallback,
411    /// [w] Set position callback. This is called if the unit wants to update its position info but
412    /// not process data, or reset a cursor position internally if it is reading data from a certain
413    /// source. Can be null.
414    pub set_position        : DspSetPositionCallback,
415    /// [w] Number of parameters used in this filter. The user finds this with DSP::getNumParameters
416    pub num_parameters      : i32,
417    /// [w] Variable number of parameter structures.
418    pub param_desc          : DspParameterDesc,
419    /// [w] This is called when the user calls DSP::setParameter. Can be null.
420    pub set_parameter       : DspSetParamCallback,
421    /// [w] This is called when the user calls DSP::getParameter. Can be null.
422    pub get_parameter       : DspGetParamCallback,
423    /// [w] This is called when the user calls DSP::showConfigDialog. Can be used to display a
424    /// dialog to configure the filter. Can be null.
425    config                  : DspDialogCallback,
426    /// [w] Width of config dialog graphic if there is one. 0 otherwise.
427    pub config_width        : i32,
428    /// [w] Height of config dialog graphic if there is one. 0 otherwise.
429    pub config_height       : i32,
430    /// [w] Optional. Specify 0 to ignore. This is user data to be attached to the DSP unit during
431    /// creation. Access via DSP::getUserData.
432    user_data               : Box<UserData>,
433}
434
435impl Default for DspDescription {
436    fn default() -> DspDescription {
437        DspDescription {
438            name: String::new(),
439            version: 0u32,
440            channels: 0i32,
441            create: None,
442            release: None,
443            reset: None,
444            read: None,
445            set_position: None,
446            num_parameters: 0i32,
447            param_desc: Default::default(),
448            set_parameter: None,
449            get_parameter: None,
450            config: None,
451            config_width: 0i32,
452            config_height: 0i32,
453            user_data: Box::new(UserData::new()),
454        }
455    }
456}
457
458pub fn get_description_ffi(dsp_description: &mut DspDescription) -> ffi::FMOD_DSP_DESCRIPTION {
459    let mut tmp_s = dsp_description.name.as_bytes().to_vec();
460
461    tmp_s.truncate(32);
462    tmp_s.reserve_exact(32);
463    ffi::FMOD_DSP_DESCRIPTION {
464        name: {
465            let mut slice : [i8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
466                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
467            let mut it = 0;
468
469            for tmp in tmp_s.iter() {
470                slice[it] = *tmp as i8;
471                it += 1;
472            }
473            slice
474        },
475        version: dsp_description.version,
476        channels: dsp_description.channels,
477        create: match dsp_description.create {
478            Some(_) => Some(create_callback as extern "C" fn(*mut _) -> _),
479            None => None
480        },
481        release: match dsp_description.release {
482            Some(_) => Some(release_callback as extern "C" fn(*mut _) -> _),
483            None => None
484        },
485        reset: match dsp_description.reset {
486            Some(_) => Some(reset_callback as extern "C" fn(*mut _) -> _),
487            None => None
488        },
489        read: match dsp_description.read {
490            Some(_) => Some(read_callback as extern "C" fn(*mut _, *mut _, *mut _, _, _, _) -> _),
491            None => None
492        },
493        set_position: match dsp_description.set_position {
494            Some(_) => Some(set_position_callback as extern "C" fn(*mut _, _) -> _),
495            None => None
496        },
497        num_parameters: dsp_description.num_parameters,
498        param_desc: &mut get_parameter_ffi(&dsp_description.param_desc).expect("get_parameter_ffi failed")
499                    as *mut ffi::FMOD_DSP_PARAMETERDESC,
500        set_parameter: match dsp_description.set_parameter {
501            Some(_) => Some(set_parameter_callback as extern "C" fn(*mut _, _, _) -> _),
502            None => None
503        },
504        get_parameter: match dsp_description.get_parameter {
505            Some(_) => Some(get_parameter_callback
506                            as extern "C" fn(*mut _, _, *mut _, *mut _) -> _),
507            None => None
508        },
509        config: match dsp_description.config {
510            Some(_) => Some(config_callback as extern "C" fn(*mut _, *mut _, _) -> _),
511            None => None
512        },
513        config_height: dsp_description.config_height,
514        config_width: dsp_description.config_width,
515        user_data: {
516            dsp_description.user_data.callbacks.create_callback = dsp_description.create;
517            dsp_description.user_data.callbacks.release_callback = dsp_description.release;
518            dsp_description.user_data.callbacks.reset_callback = dsp_description.reset;
519            dsp_description.user_data.callbacks.read_callback = dsp_description.read;
520            dsp_description.user_data.callbacks.set_pos_callback = dsp_description.set_position;
521            dsp_description.user_data.callbacks.set_param_callback = dsp_description.set_parameter;
522            dsp_description.user_data.callbacks.get_param_callback = dsp_description.get_parameter;
523            unsafe { transmute::<&mut UserData, *mut c_void>(&mut *dsp_description.user_data) }
524        },
525    }
526}
527
528pub fn get_state_ffi(state: &DspState) -> ffi::FMOD_DSP_STATE {
529    ffi::FMOD_DSP_STATE {
530        instance: ffi::FFI::unwrap(&state.instance),
531        plugin_data: state.plugin_data,
532        speaker_mask: state.speaker_mask
533    }
534}
535
536pub fn from_state_ptr(state: ffi::FMOD_DSP_STATE) -> DspState {
537    DspState {
538        instance: ffi::FFI::wrap(state.instance),
539        plugin_data: state.plugin_data,
540        speaker_mask: state.speaker_mask
541    }
542}
543
544/// DSP plugin structure that is passed into each callback.
545pub struct DspState {
546    /// [r] Handle to the DSP hand the user created. Not to be modified. C++ users cast toDSP to
547    /// use.
548    pub instance: Dsp,
549    /// [w] Plugin writer created data the output author wants to attach to this object.
550    plugin_data: *mut c_void,
551    /// [w] Specifies which speakers the DSP effect is active on
552    pub speaker_mask: u16,
553}
554
555pub fn from_ptr_first(dsp: *mut ffi::FMOD_DSP) -> Dsp {
556    Dsp {
557        dsp: dsp,
558        can_be_deleted: true,
559        user_data: UserData {
560            callbacks: DspCallbacks::new(),
561            user_data: ::std::ptr::null_mut()
562        }
563    }
564}
565
566/// Dsp object
567pub struct Dsp {
568    dsp: *mut ffi::FMOD_DSP,
569    can_be_deleted: bool,
570    user_data: UserData
571}
572
573impl ffi::FFI<ffi::FMOD_DSP> for Dsp {
574    fn wrap(dsp: *mut ffi::FMOD_DSP) -> Dsp {
575        Dsp {
576            dsp: dsp,
577            can_be_deleted: false,
578            user_data: UserData {
579                callbacks: DspCallbacks::new(),
580                user_data: ::std::ptr::null_mut()
581            }
582        }
583    }
584
585    fn unwrap(d: &Dsp) -> *mut ffi::FMOD_DSP {
586        d.dsp
587    }
588}
589
590impl Drop for Dsp {
591    fn drop(&mut self) {
592        self.release();
593    }
594}
595
596impl Dsp {
597    pub fn get_system_object(&self) -> Result<Sys, ::Status> {
598        let mut system = ::std::ptr::null_mut();
599
600        match unsafe { ffi::FMOD_DSP_GetSystemObject(self.dsp, &mut system) } {
601            ::Status::Ok => Ok(ffi::FFI::wrap(system)),
602            e => Err(e)
603        }
604    }
605
606    pub fn release(&mut self) -> ::Status {
607        if self.can_be_deleted && !self.dsp.is_null() {
608            match unsafe { ffi::FMOD_DSP_Release(self.dsp) } {
609               ::Status::Ok => {
610                    self.dsp =::std::ptr::null_mut();
611                   ::Status::Ok
612                }
613                e => e
614            }
615        } else {
616           ::Status::Ok
617        }
618    }
619
620    pub fn play(&self) -> Result<channel::Channel, ::Status> {
621        let mut channel = ::std::ptr::null_mut();
622
623        match match self.get_system_object() {
624            Ok(s) => { 
625                unsafe { ffi::FMOD_System_PlayDSP(ffi::FFI::unwrap(&s), ::ChannelIndex::Free,
626                                                  self.dsp, 0, &mut channel) }
627            }
628            Err(e) => e
629        } {
630            ::Status::Ok => Ok(ffi::FFI::wrap(channel)),
631            e => Err(e)
632        }
633    }
634
635    pub fn play_with_parameters(&self, channel_id: ::ChannelIndex)
636                                -> Result<channel::Channel, ::Status> {
637        let mut channel = ::std::ptr::null_mut();
638        
639        match match self.get_system_object() {
640            Ok(s) => { 
641                unsafe { ffi::FMOD_System_PlayDSP(ffi::FFI::unwrap(&s), channel_id, self.dsp, 0,
642                                                  &mut channel) }
643            }
644            Err(e) => e
645        } {
646            ::Status::Ok => Ok(ffi::FFI::wrap(channel)),
647            e => Err(e)
648        }
649    }
650
651    pub fn add_input(&self, target: Dsp) -> Result<dsp_connection::DspConnection, ::Status> {
652        let mut connection = ::std::ptr::null_mut();
653
654        match unsafe { ffi::FMOD_DSP_AddInput(self.dsp, target.dsp, &mut connection) } {
655            ::Status::Ok => Ok(ffi::FFI::wrap(connection)),
656            e => Err(e)
657        }
658    }
659
660    pub fn disconnect_from(&self, target: Dsp) -> ::Status {
661        unsafe { ffi::FMOD_DSP_DisconnectFrom(self.dsp, target.dsp) }
662    }
663
664    pub fn disconnect_all(&self, inputs: bool, outputs: bool) -> ::Status {
665        let t_inputs = if inputs == true {
666            1
667        } else {
668            0
669        };
670        let t_outputs = if outputs == true {
671            1
672        } else {
673            0
674        };
675
676        unsafe { ffi::FMOD_DSP_DisconnectAll(self.dsp, t_inputs, t_outputs) }
677    }
678
679    pub fn remove(&self) -> ::Status {
680        unsafe { ffi::FMOD_DSP_Remove(self.dsp) }
681    }
682
683    pub fn get_num_inputs(&self) -> Result<i32, ::Status> {
684        let mut inputs = 0i32;
685
686        match unsafe { ffi::FMOD_DSP_GetNumInputs(self.dsp, &mut inputs) } {
687            ::Status::Ok => Ok(inputs),
688            e => Err(e)
689        }
690    }
691
692    pub fn get_num_outputs(&self) -> Result<i32, ::Status> {
693        let mut outputs = 0i32;
694
695        match unsafe { ffi::FMOD_DSP_GetNumOutputs(self.dsp, &mut outputs) } {
696            ::Status::Ok => Ok(outputs),
697            e => Err(e)
698        }
699    }
700
701    pub fn get_input(&self, index: i32) -> Result<(Dsp, dsp_connection::DspConnection), ::Status> {
702        let mut input = ::std::ptr::null_mut();
703        let mut input_connection = ::std::ptr::null_mut();
704
705        match unsafe { ffi::FMOD_DSP_GetInput(self.dsp, index, &mut input,
706                                              &mut input_connection) } {
707            ::Status::Ok => Ok((ffi::FFI::wrap(input), ffi::FFI::wrap(input_connection))),
708            e => Err(e)
709        }
710    }
711
712    pub fn get_output(&self, index: i32) -> Result<(Dsp, dsp_connection::DspConnection), ::Status> {
713        let mut output = ::std::ptr::null_mut();
714        let mut output_connection = ::std::ptr::null_mut();
715
716        match unsafe { ffi::FMOD_DSP_GetOutput(self.dsp, index, &mut output,
717                                               &mut output_connection) } {
718            ::Status::Ok => Ok((ffi::FFI::wrap(output), ffi::FFI::wrap(output_connection ))),
719            e => Err(e)
720        }
721    }
722
723    pub fn set_active(&self, active: bool) -> ::Status {
724        let t_active = if active == true {
725            1
726        } else {
727            0
728        };
729
730        unsafe { ffi::FMOD_DSP_SetActive(self.dsp, t_active) }
731    }
732
733    pub fn get_active(&self) -> Result<bool, ::Status> {
734        let mut active = 0i32;
735
736        match unsafe { ffi::FMOD_DSP_GetActive(self.dsp, &mut active) } {
737            ::Status::Ok => Ok(active != 0i32),
738            e => Err(e)
739        }
740    }
741
742    pub fn set_bypass(&self, bypass: bool) -> ::Status {
743        let t_bypass = if bypass == true {
744            1i32
745        } else {
746            0i32
747        };
748
749        unsafe { ffi::FMOD_DSP_SetBypass(self.dsp, t_bypass) }
750    }
751
752    pub fn get_bypass(&self) -> Result<bool, ::Status> {
753        let mut bypass = 0i32;
754
755        match unsafe { ffi::FMOD_DSP_GetBypass(self.dsp, &mut bypass) } {
756            ::Status::Ok => Ok(bypass == 1i32),
757            e => Err(e)
758        }
759    }
760
761    pub fn set_speaker_active(&self, speaker: ::Speaker, active: bool) -> ::Status {
762        let t_active = if active == true {
763            1
764        } else {
765            0
766        };
767
768        unsafe { ffi::FMOD_DSP_SetSpeakerActive(self.dsp, speaker, t_active) }
769    }
770
771    pub fn get_speaker_active(&self, speaker: ::Speaker) -> Result<bool, ::Status> {
772        let mut active = 0i32;
773
774        match unsafe { ffi::FMOD_DSP_GetSpeakerActive(self.dsp, speaker, &mut active) } {
775            ::Status::Ok => Ok(active == 1i32),
776            e => Err(e)
777        }
778    }
779
780    pub fn reset(&self) -> ::Status {
781        unsafe { ffi::FMOD_DSP_Reset(self.dsp) }
782    }
783
784    /// value argument depends directly on the index argument,
785    /// index argument depends on your DSP type, it is a value from one of the following enums :
786    /// 
787    /// * [`DspType`](enums/fmod/type.DspType.html)
788    /// * [`DspOscillator`](enums/fmod/type.DspOscillator.html)
789    /// * [`DspLowPass`](enums/fmod/type.DspLowPass.html)
790    /// * [`DspITLowPass`](enums/fmod/type.DspITLowPass.html)
791    /// * [`DspHighPass`](enums/fmod/type.DspHighPass.html)
792    /// * [`DspTypeEcho`](enums/fmod/type.DspTypeEcho.html)
793    /// * [`DspDelay`](enums/fmod/type.DspDelay.html)
794    /// * [`DspFlange`](enums/fmod/type.DspFlange.html)
795    /// * [`DspTremolo`](enums/fmod/type.DspTremolo.html)
796    /// * [`DspDistortion`](enums/fmod/type.DspDistortion.html)
797    /// * [`DspNormalize`](enums/fmod/type.DspNormalize.html)
798    /// * [`DspTypeParameq`](enums/fmod/type.DspTypeParameq.html)
799    /// * [`DspPitchShift`](enums/fmod/type.DspPitchShift.html)
800    /// * [`DspChorus`](enums/fmod/type.DspChorus.html)
801    /// * [`DspITEcho`](enums/fmod/type.DspITEcho.html)
802    /// * [`DspCompressor`](enums/fmod/type.DspCompressor.html)
803    /// * [`DspSfxReverb`](enums/fmod/type.DspSfxReverb.html)
804    /// * [`DspLowPassSimple`](enums/fmod/type.DspLowPassSimple.html)
805    /// * [`DspHighPassSimple`](enums/fmod/type.DspHighPassSimple.html)
806    pub fn set_parameter(&self, index: i32, value: f32) -> ::Status {
807        unsafe { ffi::FMOD_DSP_SetParameter(self.dsp, index, value) }
808    }
809
810    /// value result depends directly on the index argument,
811    /// index argument depends on your DSP type, it is a value from one of the following enums:
812    /// 
813    /// * [`DspType`](enums/fmod/type.DspType.html)
814    /// * [`DspOscillator`](enums/fmod/type.DspOscillator.html)
815    /// * [`DspLowPass`](enums/fmod/type.DspLowPass.html)
816    /// * [`DspITLowPass`](enums/fmod/type.DspITLowPass.html)
817    /// * [`DspHighPass`](enums/fmod/type.DspHighPass.html)
818    /// * [`DspTypeEcho`](enums/fmod/type.DspTypeEcho.html)
819    /// * [`DspDelay`](enums/fmod/type.DspDelay.html)
820    /// * [`DspFlange`](enums/fmod/type.DspFlange.html)
821    /// * [`DspTremolo`](enums/fmod/type.DspTremolo.html)
822    /// * [`DspDistortion`](enums/fmod/type.DspDistortion.html)
823    /// * [`DspNormalize`](enums/fmod/type.DspNormalize.html)
824    /// * [`DspTypeParameq`](enums/fmod/type.DspTypeParameq.html)
825    /// * [`DspPitchShift`](enums/fmod/type.DspPitchShift.html)
826    /// * [`DspChorus`](enums/fmod/type.DspChorus.html)
827    /// * [`DspITEcho`](enums/fmod/type.DspITEcho.html)
828    /// * [`DspCompressor`](enums/fmod/type.DspCompressor.html)
829    /// * [`DspSfxReverb`](enums/fmod/type.DspSfxReverb.html)
830    /// * [`DspLowPassSimple`](enums/fmod/type.DspLowPassSimple.html)
831    /// * [`DspHighPassSimple`](enums/fmod/type.DspHighPassSimple.html)
832    pub fn get_parameter(&self, index: i32, value_str_len: usize)
833                        -> Result<(f32, String), ::RStatus> {
834        let mut value = 0f32;
835        let mut c = Vec::with_capacity(value_str_len + 1);
836
837        for _ in 0..(value_str_len + 1) {
838            c.push(0);
839        }
840
841        match unsafe { ffi::FMOD_DSP_GetParameter(self.dsp, index, &mut value,
842                                                  c.as_mut_ptr() as *mut c_char,
843                                                  value_str_len as i32) } {
844           ::Status::Ok => {
845                let c = from_utf8!(c);
846                Ok((value, c))
847            }
848            e => Err(::RStatus::FMOD(e))
849        }
850    }
851
852    pub fn get_num_parameters(&self) -> Result<i32, ::Status> {
853        let mut num_param = 0i32;
854
855        match unsafe { ffi::FMOD_DSP_GetNumParameters(self.dsp, &mut num_param) } {
856            ::Status::Ok => Ok(num_param),
857            e => Err(e)
858        }
859    }
860
861    pub fn get_parameter_info(&self, index: i32, name: &str, label: &str,
862                              description_len: usize) -> Result<(String, f32, f32), ::RStatus> {
863        let mut min = 0f32;
864        let mut max = 0f32;
865        let t_name = name.clone();
866        let t_label = label.clone();
867        let mut description = Vec::with_capacity(description_len + 1);
868
869        for _ in 0..(description_len + 1) {
870            description.push(0);
871        }
872
873        match unsafe { ffi::FMOD_DSP_GetParameterInfo(self.dsp, index,
874                                                      t_name.as_ptr() as *mut c_char,
875                                                      t_label.as_ptr() as *mut c_char,
876                                                      description.as_mut_ptr() as *mut c_char,
877                                                      description_len as i32, &mut min,
878                                                      &mut max) } {
879            ::Status::Ok => Ok((from_utf8!(description), min, max)),
880            e => Err(::RStatus::FMOD(e)),
881        }
882    }
883
884    pub fn get_info(&self, name: &str) -> Result<(u32, i32, i32, i32), ::Status> {
885        let mut version = 0u32;
886        let mut channels = 0i32;
887        let mut config_width = 0i32;
888        let mut config_height = 0i32;
889        let tmp_n = name.clone();
890
891        match unsafe { ffi::FMOD_DSP_GetInfo(self.dsp, tmp_n.as_ptr() as *mut c_char, &mut version,
892                                             &mut channels, &mut config_width,
893            &mut config_height) } {
894            ::Status::Ok => Ok((version, channels, config_width, config_height)),
895            e => Err(e)
896        }
897    }
898
899    pub fn set_defaults(&self, frequency: f32, volume: f32, pan: f32, priority: i32) -> ::Status {
900        unsafe { ffi::FMOD_DSP_SetDefaults(self.dsp, frequency, volume, pan, priority) }
901    }
902
903    pub fn get_type(&self) -> Result<::DspType, ::Status> {
904        let mut _type = ::DspType::Unknown;
905
906        match unsafe { ffi::FMOD_DSP_GetType(self.dsp, &mut _type) } {
907            ::Status::Ok => Ok(_type),
908            e => Err(e)
909        }
910    }
911
912    pub fn get_defaults(&self) -> Result<(f32, f32, f32, i32), ::Status> {
913        let mut frequency = 0f32;
914        let mut volume = 0f32;
915        let mut pan = 0f32;
916        let mut priority = 0i32;
917
918        match unsafe { ffi::FMOD_DSP_GetDefaults(self.dsp, &mut frequency, &mut volume, &mut pan,
919                                                 &mut priority) } {
920            ::Status::Ok => Ok((frequency, volume, pan, priority)),
921            e => Err(e)
922        }
923    }
924
925    pub fn get_memory_info(&self, MemoryBits(memory_bits): MemoryBits,
926                           EventMemoryBits(event_memory_bits): EventMemoryBits)
927                           -> Result<(u32, MemoryUsageDetails), ::Status> {
928        let mut details = fmod_sys::get_memory_usage_details_ffi(Default::default());
929        let mut memory_used = 0u32;
930
931        match unsafe { ffi::FMOD_DSP_GetMemoryInfo(self.dsp, memory_bits, event_memory_bits,
932                                                   &mut memory_used, &mut details) } {
933            ::Status::Ok => Ok((memory_used, fmod_sys::from_memory_usage_details_ptr(details))),
934            e => Err(e)
935        }
936    }
937
938    pub fn set_user_data<'r, T>(&'r mut self, user_data: &'r mut T) -> ::Status {
939        let mut data: *mut c_void = ::std::ptr::null_mut();
940
941        unsafe {
942            match ffi::FMOD_DSP_GetUserData(self.dsp, &mut data) {
943               ::Status::Ok => {
944                    if data.is_null() {
945                        self.user_data.user_data = ::std::ptr::null_mut();
946
947                        ffi::FMOD_DSP_SetUserData(self.dsp, transmute(&mut self.user_data))
948                    } else {
949                        let tmp : &mut UserData = transmute::<*mut c_void, &mut UserData>(data);
950
951                        tmp.user_data = transmute::<&mut T, *mut c_void>(user_data);
952                        ffi::FMOD_DSP_SetUserData(self.dsp, transmute(tmp))
953                    }
954                }
955                _ => {
956                    self.user_data.user_data = transmute::<&mut T, *mut c_void>(user_data);
957
958                    ffi::FMOD_DSP_SetUserData(self.dsp, transmute(&mut self.user_data))
959                }
960            }
961        }
962    }
963
964    pub fn get_user_data<'r, T>(&'r self) -> Result<&'r mut T, ::Status> {
965        unsafe {
966            let mut user_data : *mut c_void = ::std::ptr::null_mut();
967
968            match ffi::FMOD_DSP_GetUserData(self.dsp, &mut user_data) {
969               ::Status::Ok => {
970                    if !user_data.is_null() {
971                        let tmp: &mut UserData = transmute::<*mut c_void, &mut UserData>(user_data);
972                        let tmp2: &mut T = transmute::<*mut c_void, &mut T>(tmp.user_data);
973
974                        Ok(tmp2)
975                    } else {
976                        Err(::Status::Ok)
977                    }
978                },
979                e => Err(e)
980            }
981        }
982    }
983}