rfmod/
channel.rs

1/*
2* Rust-FMOD - Copyright (c) 2014 Gomez Guillaume.
3*
4* The Original software, FmodEx 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 types::*;
26use libc::{c_int, c_void};
27use ffi;
28use dsp::Dsp;
29use dsp_connection::DspConnection;
30use channel_group::ChannelGroup;
31use fmod_sys;
32use fmod_sys::{MemoryUsageDetails, Sys};
33use vector;
34use sound::Sound;
35use std::mem::transmute;
36use std::default::Default;
37
38/// Structure which contains data for
39/// [`Channel::set_speaker_mix`](struct.Channel.html#method.set_speaker_mix) and
40/// [`Channel::get_speaker_mix`](struct.Channel.html#method.get_speaker_mix)
41#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)]
42pub struct SpeakerMixOptions {
43    pub front_left : f32,
44    pub front_right: f32,
45    pub center     : f32,
46    pub lfe        : f32,
47    pub back_left  : f32,
48    pub back_right : f32,
49    pub side_left  : f32,
50    pub side_right : f32
51}
52
53impl Default for SpeakerMixOptions {
54    fn default() -> SpeakerMixOptions {
55        SpeakerMixOptions {
56            front_left: 0f32,
57            front_right: 0f32,
58            center: 0f32,
59            lfe: 0f32,
60            back_left: 0f32,
61            back_right: 0f32,
62            side_left: 0f32,
63            side_right: 0f32
64        }
65    }
66}
67
68/// Structure defining the properties for a reverb source, related to a FMOD channel.
69pub struct ReverbChannelProperties {
70    /// [r/w] MIN: -10000 MAX: 1000 DEFAULT: 0
71    /// Direct path level
72    pub direct          : i32,
73    /// [r/w] MIN: -10000 MAX: 1000 DEFAULT: 0
74    /// Room effect level
75    pub room            : i32,
76    /// [r/w] FMOD_REVERB_CHANNELFLAGS
77    /// modifies the behavior of properties
78    pub flags           : u32,
79    /// [r/w] See remarks.
80    /// DSP network location to connect reverb for this channel.
81    pub connection_point: Dsp
82}
83
84/// Channel Object
85pub struct Channel {
86    channel: *mut ffi::FMOD_CHANNEL
87}
88
89impl Drop for Channel {
90    fn drop(&mut self) {
91        self.release();
92    }
93}
94
95impl ffi::FFI<ffi::FMOD_CHANNEL> for Channel {
96    fn wrap(channel: *mut ffi::FMOD_CHANNEL) -> Channel {
97        Channel {channel: channel}
98    }
99
100    fn unwrap(c: &Channel) -> *mut ffi::FMOD_CHANNEL {
101        c.channel
102    }
103}
104
105impl Channel {
106    pub fn new() -> Channel {
107        Channel {channel: ::std::ptr::null_mut()}
108    }
109
110    pub fn release(&mut self) {
111        self.channel = ::std::ptr::null_mut();
112    }
113
114    pub fn get_system_object(&self) -> Result<Sys, ::Status> {
115        let mut system = ::std::ptr::null_mut();
116
117        match unsafe { ffi::FMOD_Channel_GetSystemObject(self.channel, &mut system) } {
118            ::Status::Ok => Ok(ffi::FFI::wrap(system)),
119            e => Err(e)
120        }
121    }
122
123    pub fn stop(&self) -> ::Status {
124        unsafe { ffi::FMOD_Channel_Stop(self.channel) }
125    }
126
127    /// channel_offset:  0/1 -> left channel/right channel
128    pub fn get_spectrum(&self, spectrum_size: usize, channel_offset: Option<i32>, window_type: Option<::DspFftWindow>) -> Result<Vec<f32>, ::Status> {
129        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(spectrum_size).collect();
130        let c_window_type = match window_type {
131            Some(wt) => wt,
132            None => ::DspFftWindow::Rect
133        };
134        let c_channel_offset = match channel_offset {
135            Some(co) => co,
136            None => 0i32
137        };
138
139        match unsafe { ffi::FMOD_Channel_GetSpectrum(self.channel, ptr.as_mut_ptr(), spectrum_size as c_int, c_channel_offset, c_window_type) } {
140            ::Status::Ok => Ok(ptr),
141            e => Err(e),
142        }
143    }
144
145    pub fn get_wave_data(&self, wave_size: usize, channel_offset: i32) -> Result<Vec<f32>, ::Status> {
146        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(wave_size).collect();
147
148        match unsafe { ffi::FMOD_Channel_GetWaveData(self.channel, ptr.as_mut_ptr(), wave_size as c_int, channel_offset) } {
149            ::Status::Ok => Ok(ptr),
150            e => Err(e)
151        }
152    }
153
154    pub fn is_init(&self) -> bool {
155        !self.channel.is_null()
156    }
157
158    pub fn is_playing(&self) -> Result<bool, ::Status> {
159        let mut is_playing = 0;
160
161        match unsafe { ffi::FMOD_Channel_IsPlaying(self.channel, &mut is_playing) } {
162            ::Status::Ok => Ok(is_playing == 1),
163            err => Err(err),
164        }
165    }
166
167    pub fn is_virtual(&self) -> Result<bool, ::Status> {
168        let mut is_virtual = 0i32;
169
170        match unsafe { ffi::FMOD_Channel_IsVirtual(self.channel, &mut is_virtual) } {
171            ::Status::Ok => Ok(is_virtual == 1),
172            e => Err(e)
173        }
174    }
175
176    pub fn get_audibility(&self) -> Result<f32, ::Status> {
177        let mut audibility = 0f32;
178
179        match unsafe { ffi::FMOD_Channel_GetAudibility(self.channel, &mut audibility) } {
180            ::Status::Ok => Ok(audibility),
181            e => Err(e)
182        }
183    }
184
185    pub fn get_current_sound(&self) -> Result<Sound, ::Status> {
186        let mut sound = ::std::ptr::null_mut();
187
188        match unsafe { ffi::FMOD_Channel_GetCurrentSound(self.channel, &mut sound) } {
189            ::Status::Ok => Ok(ffi::FFI::wrap(sound)),
190            e => Err(e)
191        }
192    }
193
194    pub fn get_index(&self) -> Result<i32, ::Status> {
195        let mut index = 0i32;
196
197        match unsafe { ffi::FMOD_Channel_GetIndex(self.channel, &mut index) } {
198            ::Status::Ok => Ok(index),
199            e => Err(e)
200        }
201    }
202
203    pub fn set_volume(&self, volume: f32) -> ::Status {
204        unsafe { ffi::FMOD_Channel_SetVolume(self.channel, volume) }
205    }
206
207    pub fn get_volume(&self) -> Result<f32, ::Status> {
208        let mut volume = 0f32;
209
210        match unsafe { ffi::FMOD_Channel_GetVolume(self.channel, &mut volume) } {
211            ::Status::Ok => Ok(volume),
212            e => Err(e),
213        }
214    }
215
216    pub fn set_frequency(&self, frequency: f32) -> ::Status {
217        unsafe { ffi::FMOD_Channel_SetFrequency(self.channel, frequency) }
218    }
219
220    pub fn get_frequency(&self) -> Result<f32, ::Status> {
221        let mut frequency = 0f32;
222
223        match unsafe { ffi::FMOD_Channel_GetFrequency(self.channel, &mut frequency) } {
224            ::Status::Ok => Ok(frequency),
225            e => Err(e),
226        }
227    }
228
229    pub fn set_pan(&self, pan: f32) -> ::Status {
230        unsafe { ffi::FMOD_Channel_SetPan(self.channel, pan) }
231    }
232
233    pub fn get_pan(&self) -> Result<f32, ::Status> {
234        let mut pan = 0f32;
235
236        match unsafe { ffi::FMOD_Channel_GetPan(self.channel, &mut pan) } {
237            ::Status::Ok => Ok(pan),
238            e => Err(e),
239        }
240    }
241
242    pub fn set_mute(&self, mute: bool) -> ::Status {
243        let t = match mute {
244            true => 1,
245            false => 0,
246        };
247        unsafe { ffi::FMOD_Channel_SetMute(self.channel, t) }
248    }
249
250    pub fn get_mute(&self) -> Result<bool, ::Status> {
251        let mut mute = 0;
252
253        match unsafe { ffi::FMOD_Channel_GetMute(self.channel, &mut mute) } {
254            ::Status::Ok => Ok(match mute {
255                1 => true,
256                _ => false,
257            }),
258            e => Err(e),
259        }
260    }
261
262    pub fn set_paused(&self, paused: bool) -> ::Status {
263        let t: ffi::FMOD_BOOL = match paused {
264            true => 1,
265            false => 0,
266        };
267        unsafe { ffi::FMOD_Channel_SetPaused(self.channel, t) }
268    }
269
270    pub fn get_paused(&self) -> Result<bool, ::Status> {
271        let mut t = 0;
272
273        match unsafe { ffi::FMOD_Channel_GetPaused(self.channel, &mut t) } {
274            ::Status::Ok => Ok(match t {
275                1 => true,
276                _ => false,
277            }),
278            e => Err(e),
279        }
280    }
281
282    pub fn set_delay(&self, delay_type: ::DelayType, delay_hi: usize,
283                     delay_lo: usize) -> ::Status {
284        unsafe { ffi::FMOD_Channel_SetDelay(self.channel, delay_type, delay_hi as u32,
285                                            delay_lo as u32) }
286    }
287
288    pub fn get_delay(&self, delay_type: ::DelayType)
289                    -> Result<(::DelayType, usize, usize), ::Status> {
290        let mut delaylo = 0u32;
291        let mut delayhi = 0u32;
292
293        match unsafe { ffi::FMOD_Channel_GetDelay(self.channel, delay_type, &mut delayhi,
294                                                  &mut delaylo) } {
295            ::Status::Ok => Ok((delay_type, delayhi as usize, delaylo as usize)),
296            e => Err(e),
297        }
298    }
299
300    pub fn set_speaker_mix(&self, smo: &SpeakerMixOptions) -> ::Status {
301        unsafe { ffi::FMOD_Channel_SetSpeakerMix(self.channel, smo.front_left, smo.front_right,
302                                                 smo.center, smo.lfe, smo.back_left, smo.back_right,
303                                                 smo.side_left, smo.side_right) }
304    }
305
306    pub fn get_speaker_mix(&self) -> Result<SpeakerMixOptions, ::Status> {
307        let mut smo = SpeakerMixOptions{
308                          front_left: 0f32,
309                          front_right: 0f32,
310                          center: 0f32,
311                          lfe: 0f32,
312                          back_left: 0f32,
313                          back_right: 0f32,
314                          side_left: 0f32,
315                          side_right: 0f32
316                      };
317
318        match unsafe { ffi::FMOD_Channel_GetSpeakerMix(self.channel, &mut smo.front_left,
319                                                       &mut smo.front_right, &mut smo.center,
320                                                       &mut smo.lfe, &mut smo.back_left,
321                                                       &mut smo.back_right, &mut smo.side_left,
322                                                       &mut smo.side_right) } {
323            ::Status::Ok => Ok(smo),
324            e => Err(e),
325        }
326    }
327
328    pub fn set_speaker_level(&self, speaker: ::Speaker, levels: &mut Vec<f32>) -> ::Status {
329        unsafe { ffi::FMOD_Channel_SetSpeakerLevels(self.channel, speaker, levels.as_mut_ptr(),
330                                                    levels.len() as i32) }
331    }
332
333    pub fn get_speaker_level(&self, speaker: ::Speaker,
334                             num_levels: usize) -> Result<Vec<f32>, ::Status> {
335        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(num_levels).collect();
336
337        match unsafe { ffi::FMOD_Channel_GetSpeakerLevels(self.channel, speaker, ptr.as_mut_ptr(),
338                                                          num_levels as i32) } {
339            ::Status::Ok => Ok(ptr),
340            e => Err(e),
341        }
342    }
343
344    pub fn set_input_channel_mix(&self, levels: &mut Vec<f32>) -> ::Status {
345        unsafe { ffi::FMOD_Channel_SetInputChannelMix(self.channel, levels.as_mut_ptr(),
346                                                      levels.len() as i32) }
347    }
348
349    pub fn get_input_channel_mix(&self, num_levels: usize) -> Result<Vec<f32>, ::Status> {
350        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(num_levels).collect();
351
352        match unsafe { ffi::FMOD_Channel_GetInputChannelMix(self.channel, ptr.as_mut_ptr(),
353                                                            num_levels as i32) } {
354            ::Status::Ok => Ok(ptr),
355            e => Err(e),
356        }
357    }
358
359    pub fn set_priority(&self, priority: i32) -> ::Status {
360        unsafe { ffi::FMOD_Channel_SetPriority(self.channel, priority) }
361    }
362
363    pub fn get_priority(&self) -> Result<i32, ::Status> {
364        let mut t = 0i32;
365
366        match unsafe { ffi::FMOD_Channel_GetPriority(self.channel, &mut t) } {
367            ::Status::Ok => Ok(t),
368            e => Err(e),
369        }
370    }
371
372    pub fn set_position(&self, position: usize, TimeUnit(postype): TimeUnit) -> ::Status {
373        unsafe { ffi::FMOD_Channel_SetPosition(self.channel, position as u32, postype) }
374    }
375
376    pub fn get_position(&self, TimeUnit(postype): TimeUnit) -> Result<usize, ::Status> {
377        let mut t = 0u32;
378
379        match unsafe { ffi::FMOD_Channel_GetPosition(self.channel, &mut t, postype) } {
380            ::Status::Ok => Ok(t as usize),
381            e => Err(e),
382        }
383    }
384
385    pub fn set_reverb_properties(&self, prop: &ReverbChannelProperties) -> ::Status {
386        let t = ffi::FMOD_REVERB_CHANNELPROPERTIES{
387                    Direct: prop.direct,
388                    Room: prop.room,
389                    Flags: prop.flags,
390                    ConnectionPoint: ::std::ptr::null_mut()
391                };
392
393        unsafe { ffi::FMOD_Channel_SetReverbProperties(self.channel, &t) }
394    }
395
396    pub fn get_reverb_properties(&self) -> Result<ReverbChannelProperties, ::Status> {
397        let mut t = ffi::FMOD_REVERB_CHANNELPROPERTIES{
398                        Direct: 0,
399                        Room: 0,
400                        Flags: 0,
401                        ConnectionPoint: ::std::ptr::null_mut()
402                    };
403
404        match unsafe { ffi::FMOD_Channel_GetReverbProperties(self.channel, &mut t) } {
405            ::Status::Ok => Ok(ReverbChannelProperties{
406                direct: t.Direct,
407                room: t.Room,
408                flags: t.Flags,
409                connection_point: ffi::FFI::wrap(t.ConnectionPoint)}),
410            e => Err(e),
411        }
412    }
413
414    pub fn set_low_pass_gain(&self, gain: f32) -> ::Status {
415        unsafe { ffi::FMOD_Channel_SetLowPassGain(self.channel, gain) }
416    }
417
418    pub fn get_low_pass_gain(&self) -> Result<f32, ::Status> {
419        let mut t = 0f32;
420
421        match unsafe { ffi::FMOD_Channel_GetLowPassGain(self.channel, &mut t) } {
422            ::Status::Ok => Ok(t),
423            e => Err(e),
424        }
425    }
426
427    pub fn set_channel_group(&mut self, channel_group: &ChannelGroup) -> ::Status {
428        unsafe { ffi::FMOD_Channel_SetChannelGroup(self.channel, ffi::FFI::unwrap(channel_group)) }
429    }
430
431    pub fn get_channel_group(&self) -> Result<ChannelGroup, ::Status> {
432        let mut channel_group = ::std::ptr::null_mut();
433
434        match unsafe { ffi::FMOD_Channel_GetChannelGroup(self.channel, &mut channel_group) } {
435            ::Status::Ok => Ok(ffi::FFI::wrap(channel_group)),
436            e => Err(e)
437        }
438    }
439
440    pub fn set_3D_attributes(&self, position: &vector::Vector,
441                             velocity: &vector::Vector) -> ::Status {
442        let mut t_position = vector::get_ffi(position);
443        let mut t_velocity = vector::get_ffi(velocity);
444
445        unsafe { ffi::FMOD_Channel_Set3DAttributes(self.channel, &mut t_position, &mut t_velocity) }
446    }
447
448    pub fn get_3D_attributes(&self) -> Result<(vector::Vector, vector::Vector), ::Status> {
449        let mut position = vector::get_ffi(&vector::Vector::new());
450        let mut velocity = vector::get_ffi(&vector::Vector::new());
451
452        match unsafe { ffi::FMOD_Channel_Get3DAttributes(self.channel, &mut position,
453                                                         &mut velocity) } {
454            ::Status::Ok => Ok((vector::from_ptr(position), vector::from_ptr(velocity))),
455            e => Err(e)
456        }
457    }
458
459    pub fn set_3D_min_max_distance(&self, min_distance: f32, max_distance: f32) -> ::Status {
460        unsafe { ffi::FMOD_Channel_Set3DMinMaxDistance(self.channel, min_distance, max_distance) }
461    }
462
463    pub fn get_3D_min_max_distance(&self) -> Result<(f32, f32), ::Status> {
464        let mut min_distance = 0f32;
465        let mut max_distance = 0f32;
466
467        match unsafe { ffi::FMOD_Channel_Get3DMinMaxDistance(self.channel, &mut min_distance,
468                                                             &mut max_distance) } {
469            ::Status::Ok => Ok((min_distance, max_distance)),
470            e => Err(e)
471        }
472    }
473
474    pub fn set_3D_cone_settings(&self, inside_cone_angle: f32, outside_cone_angle: f32,
475                                outside_volume: f32) -> ::Status {
476        unsafe { ffi::FMOD_Channel_Set3DConeSettings(self.channel, inside_cone_angle,
477                                                     outside_cone_angle, outside_volume) }
478    }
479
480    pub fn get_3D_cone_settings(&self) -> Result<(f32, f32, f32), ::Status> {
481        let mut inside_cone_angle = 0f32;
482        let mut outside_cone_angle = 0f32;
483        let mut outside_volume = 0f32;
484
485        match unsafe { ffi::FMOD_Channel_Get3DConeSettings(self.channel, &mut inside_cone_angle,
486                                                           &mut outside_cone_angle,
487                                                           &mut outside_volume) } {
488            ::Status::Ok => Ok((inside_cone_angle, outside_cone_angle, outside_volume)),
489            e => Err(e)
490        }
491    }
492
493    pub fn set_3D_cone_orientation(&self, orientation: &vector::Vector) -> ::Status {
494        let mut t_orientation = vector::get_ffi(orientation);
495
496        unsafe { ffi::FMOD_Channel_Set3DConeOrientation(self.channel, &mut t_orientation) }
497    }
498
499    pub fn get_3D_cone_orientation(&self) -> Result<vector::Vector, ::Status> {
500        let mut orientation = vector::get_ffi(&vector::Vector::new());
501
502        match unsafe { ffi::FMOD_Channel_Get3DConeOrientation(self.channel, &mut orientation) } {
503            ::Status::Ok => Ok(vector::from_ptr(orientation)),
504            e => Err(e)
505        }
506    }
507
508    pub fn set_3D_custom_rolloff(&self, points: &Vec<vector::Vector>) -> ::Status {
509        let mut t_points = Vec::new();
510
511        for tmp in points.iter() {
512            t_points.push(vector::get_ffi(tmp));
513        }
514        unsafe { ffi::FMOD_Channel_Set3DCustomRolloff(self.channel, t_points.as_mut_ptr(),
515                                                      points.len() as c_int) }
516    }
517
518    pub fn get_3D_custom_rolloff(&self) -> Result<Vec<vector::Vector>, ::Status> {
519        let mut points = ::std::ptr::null_mut();
520        let mut num_points = 0i32;
521
522        unsafe {
523            match ffi::FMOD_Channel_Get3DCustomRolloff(self.channel, &mut points, &mut num_points) {
524               ::Status::Ok => {
525                    let mut ret_points = Vec::new();
526
527                    for it in 0i32..num_points {
528                        ret_points.push(vector::from_ptr(::std::ptr::read(
529                            points.offset(it as isize) as *const ffi::FMOD_VECTOR)));
530                    }
531                    Ok(ret_points)
532                }
533                e => Err(e)
534            }
535        }
536    }
537
538    pub fn set_3D_occlusion(&self, direct_occlusion: f32, reverb_occlusion: f32) -> ::Status {
539        unsafe { ffi::FMOD_Channel_Set3DOcclusion(self.channel, direct_occlusion,
540                                                  reverb_occlusion) }
541    }
542
543    pub fn get_3D_occlusion(&self) -> Result<(f32, f32), ::Status> {
544        let mut direct_occlusion = 0f32;
545        let mut reverb_occlusion = 0f32;
546
547        match unsafe { ffi::FMOD_Channel_Get3DOcclusion(self.channel, &mut direct_occlusion,
548                                                        &mut reverb_occlusion) } {
549            ::Status::Ok => Ok((direct_occlusion, reverb_occlusion)),
550            e => Err(e)
551        }
552    }
553
554    pub fn set_3D_spread(&self, angle: f32) -> ::Status {
555        unsafe { ffi::FMOD_Channel_Set3DSpread(self.channel, angle) }
556    }
557
558    pub fn get_3D_spread(&self) -> Result<f32, ::Status> {
559        let mut angle = 0f32;
560
561        match unsafe { ffi::FMOD_Channel_Get3DSpread(self.channel, &mut angle) } {
562            ::Status::Ok => Ok(angle),
563            e => Err(e)
564        }
565    }
566
567    pub fn set_3D_pan_level(&self, level: f32) -> ::Status {
568        unsafe { ffi::FMOD_Channel_Set3DPanLevel(self.channel, level) }
569    }
570
571    pub fn get_3D_pan_level(&self) -> Result<f32, ::Status> {
572        let mut level = 0f32;
573
574        match unsafe { ffi::FMOD_Channel_Get3DPanLevel(self.channel, &mut level) } {
575            ::Status::Ok => Ok(level),
576            e => Err(e)
577        }
578    }
579
580    pub fn set_3D_doppler_level(&self, level: f32) -> ::Status {
581        unsafe { ffi::FMOD_Channel_Set3DDopplerLevel(self.channel, level) }
582    }
583
584    pub fn get_3D_doppler_level(&self) -> Result<f32, ::Status> {
585        let mut level = 0f32;
586
587        match unsafe { ffi::FMOD_Channel_Get3DDopplerLevel(self.channel, &mut level) } {
588            ::Status::Ok => Ok(level),
589            e => Err(e)
590        }
591    }
592
593    pub fn set_3D_distance_filter(&self, custom: bool, custom_level: f32,
594                                  center_freq: f32) -> ::Status {
595        unsafe { ffi::FMOD_Channel_Set3DDistanceFilter(self.channel, if custom {
596                1
597            } else {
598                0
599            }, custom_level, center_freq) }
600    }
601
602    pub fn get_3D_distance_filter(&self) -> Result<(bool, f32, f32), ::Status> {
603        let mut custom = 0i32;
604        let mut custom_level = 0f32;
605        let mut center_freq = 0f32;
606
607        match unsafe { ffi::FMOD_Channel_Get3DDistanceFilter(self.channel, &mut custom,
608                                                             &mut custom_level,
609                                                             &mut center_freq) } {
610            ::Status::Ok => Ok((custom == 1, custom_level, center_freq)),
611            e => Err(e)
612        }
613    }
614
615    pub fn get_DSP_head(&self) -> Result<Dsp, ::Status> {
616        let mut dsp = ::std::ptr::null_mut();
617
618        match unsafe { ffi::FMOD_Channel_GetDSPHead(self.channel, &mut dsp) } {
619            ::Status::Ok => Ok(ffi::FFI::wrap(dsp)),
620            e => Err(e)
621        }
622    }
623
624    pub fn add_DSP(&self, dsp: &Dsp) -> Result<DspConnection, ::Status> {
625        let mut connection = ::std::ptr::null_mut();
626
627        match unsafe { ffi::FMOD_Channel_AddDSP(self.channel, ffi::FFI::unwrap(dsp),
628                                                &mut connection) } {
629            ::Status::Ok => Ok(ffi::FFI::wrap(connection)),
630            e => Err(e)
631        }
632    }
633
634    pub fn set_mode(&self, Mode(mode): Mode) -> ::Status {
635        unsafe { ffi::FMOD_Channel_SetMode(self.channel, mode) }
636    }
637
638    pub fn get_mode(&self) -> Result<Mode, ::Status> {
639        let mut mode = 0u32;
640
641        match unsafe { ffi::FMOD_Channel_GetMode(self.channel, &mut mode) } {
642            ::Status::Ok => Ok(Mode(mode)),
643            e => Err(e)
644        }
645    }
646
647    pub fn set_loop_count(&self, loop_count: i32) -> ::Status {
648        unsafe { ffi::FMOD_Channel_SetLoopCount(self.channel, loop_count) }
649    }
650
651    pub fn get_loop_count(&self) -> Result<i32, ::Status> {
652        let mut loop_count = 0i32;
653
654        match unsafe { ffi::FMOD_Channel_GetLoopCount(self.channel, &mut loop_count) } {
655            ::Status::Ok => Ok(loop_count),
656            e => Err(e)
657        }
658    }
659
660    pub fn set_loop_points(&self, loop_start: u32, TimeUnit(loop_start_type): TimeUnit,
661        loop_end: u32, TimeUnit(loop_end_type): TimeUnit) -> ::Status {
662            unsafe { ffi::FMOD_Channel_SetLoopPoints(self.channel, loop_start, loop_start_type,
663                                                     loop_end, loop_end_type) }
664    }
665
666    pub fn get_loop_points(&self, TimeUnit(loop_start_type): TimeUnit,
667                           TimeUnit(loop_end_type): TimeUnit) -> Result<(u32, u32), ::Status> {
668        let mut loop_start = 0u32;
669        let mut loop_end = 0u32;
670
671        match unsafe { ffi::FMOD_Channel_GetLoopPoints(self.channel, &mut loop_start,
672                                                       loop_start_type, &mut loop_end,
673                                                       loop_end_type) } {
674            ::Status::Ok => Ok((loop_start, loop_end)),
675            e => Err(e)
676        }
677    }
678
679    pub fn set_user_data<'r, T>(&'r self, user_data: &'r mut T) -> ::Status {
680        unsafe { ffi::FMOD_Channel_SetUserData(self.channel, transmute(user_data)) }
681    }
682
683    pub fn get_user_data<'r, T>(&'r self) -> Result<&'r mut T, ::Status> {
684        unsafe {
685            let mut user_data : *mut c_void = ::std::ptr::null_mut();
686
687            match ffi::FMOD_Channel_GetUserData(self.channel, &mut user_data) {
688               ::Status::Ok => {
689                    let tmp : &mut T = transmute::<*mut c_void, &mut T>(user_data);
690                    
691                    Ok(tmp)
692                },
693                e => Err(e)
694            }
695        }
696    }
697
698    pub fn get_memory_info(&self, MemoryBits(memory_bits): MemoryBits,
699                           EventMemoryBits(event_memory_bits): EventMemoryBits)
700                           -> Result<(u32, MemoryUsageDetails), ::Status> {
701        let mut details = fmod_sys::get_memory_usage_details_ffi(Default::default());
702        let mut memory_used = 0u32;
703
704        match unsafe { ffi::FMOD_Channel_GetMemoryInfo(self.channel, memory_bits, event_memory_bits,
705                                                       &mut memory_used, &mut details) } {
706            ::Status::Ok => Ok((memory_used, fmod_sys::from_memory_usage_details_ptr(details))),
707            e => Err(e)
708        }
709    }
710}