rfmod/
channel_group.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 ffi;
27use channel;
28use dsp;
29use dsp_connection;
30use libc::{c_int, c_void};
31use vector;
32use fmod_sys;
33use fmod_sys::MemoryUsageDetails;
34use std::mem::transmute;
35use libc::{c_char};
36use std::default::Default;
37
38/// ChannelGroup object
39pub struct ChannelGroup {
40    channel_group: *mut ffi::FMOD_CHANNELGROUP,
41}
42
43impl Drop for ChannelGroup {
44    fn drop(&mut self) {
45        self.release();
46    }
47}
48
49impl ffi::FFI<ffi::FMOD_CHANNELGROUP> for ChannelGroup {
50    fn wrap(channel_group: *mut ffi::FMOD_CHANNELGROUP) -> ChannelGroup {
51        ChannelGroup {channel_group: channel_group}
52    }
53
54    fn unwrap(c: &ChannelGroup) -> *mut ffi::FMOD_CHANNELGROUP {
55        c.channel_group
56    }
57}
58
59impl ChannelGroup {
60    pub fn release(&mut self) -> ::Status {
61        if !self.channel_group.is_null() {
62            match unsafe { ffi::FMOD_ChannelGroup_Release(self.channel_group) } {
63               ::Status::Ok => {
64                    self.channel_group = ::std::ptr::null_mut();
65                   ::Status::Ok
66                }
67                e => e
68            }
69        } else {
70           ::Status::Ok
71        }
72    }
73
74    pub fn set_volume(&self, volume: f32) -> ::Status {
75        unsafe { ffi::FMOD_ChannelGroup_SetVolume(self.channel_group, volume) }
76    }
77
78    pub fn get_volume(&self) -> Result<f32, ::Status> {
79        let mut volume = 0f32;
80
81        match unsafe { ffi::FMOD_ChannelGroup_GetVolume(self.channel_group, &mut volume) } {
82            ::Status::Ok => Ok(volume),
83            e => Err(e)
84        }
85    }
86
87    pub fn set_pitch(&self, pitch: f32) -> ::Status {
88        unsafe { ffi::FMOD_ChannelGroup_SetPitch(self.channel_group, pitch) }
89    }
90
91    pub fn get_pitch(&self) -> Result<f32, ::Status> {
92        let mut pitch = 0f32;
93
94        match unsafe { ffi::FMOD_ChannelGroup_GetPitch(self.channel_group, &mut pitch) } {
95            ::Status::Ok => Ok(pitch),
96            e => Err(e)
97        }
98    }
99
100    pub fn set_paused(&self, paused: bool) -> ::Status {
101        let t_paused = match paused {
102            true => 1,
103            _ => 0
104        };
105
106        unsafe { ffi::FMOD_ChannelGroup_SetPaused(self.channel_group, t_paused) }
107    }
108
109    pub fn get_paused(&self) -> Result<bool, ::Status> {
110        let mut paused = 0;
111
112        match unsafe { ffi::FMOD_ChannelGroup_GetPaused(self.channel_group, &mut paused) } {
113            ::Status::Ok => Ok(match paused {
114                1 => true,
115                _ => false
116            }),
117            e => Err(e)
118        }
119    }
120
121    pub fn set_mute(&self, mute: bool) -> ::Status {
122        let t_mute = match mute {
123            true => 1,
124            _ => 0
125        };
126
127        unsafe { ffi::FMOD_ChannelGroup_SetMute(self.channel_group, t_mute) }
128    }
129
130    pub fn get_mute(&self) -> Result<bool, ::Status> {
131        let mut mute = 0;
132
133        match unsafe { ffi::FMOD_ChannelGroup_GetMute(self.channel_group, &mut mute) } {
134            ::Status::Ok => Ok(match mute {
135                1 => true,
136                _ => false
137            }),
138            e => Err(e)
139        }
140    }
141
142    pub fn set_3D_occlusion(&self, direct_occlusion: f32, reverb_occlusion: f32) -> ::Status {
143        unsafe { ffi::FMOD_ChannelGroup_Set3DOcclusion(self.channel_group, direct_occlusion,
144                                                       reverb_occlusion) }
145    }
146
147    pub fn get_3D_occlusion(&self) -> Result<(f32, f32), ::Status> {
148        let mut direct_occlusion = 0f32;
149        let mut reverb_occlusion = 0f32;
150
151        match unsafe { ffi::FMOD_ChannelGroup_Get3DOcclusion(self.channel_group,
152                                                             &mut direct_occlusion,
153                                                             &mut reverb_occlusion) } {
154            ::Status::Ok => Ok((direct_occlusion, reverb_occlusion)),
155            e => Err(e)
156        }
157    }
158
159    pub fn stop(&self) -> ::Status {
160        unsafe { ffi::FMOD_ChannelGroup_Stop(self.channel_group) }
161    }
162
163    pub fn override_volume(&self, volume: f32) -> ::Status {
164        unsafe { ffi::FMOD_ChannelGroup_OverrideVolume(self.channel_group, volume) }
165    }
166
167    pub fn override_frequency(&self, frequency: f32) -> ::Status {
168        unsafe { ffi::FMOD_ChannelGroup_OverrideFrequency(self.channel_group, frequency) }
169    }
170
171    pub fn override_pan(&self, pan: f32) -> ::Status {
172        unsafe { ffi::FMOD_ChannelGroup_OverridePan(self.channel_group, pan) }
173    }
174
175    pub fn override_reverb_properties(&self, properties: &channel::ReverbChannelProperties)
176                                      -> ::Status {
177        let prop = ffi::FMOD_REVERB_CHANNELPROPERTIES{
178            Direct: properties.direct,
179            Room: properties.room,
180            Flags: properties.flags,
181            ConnectionPoint: ffi::FFI::unwrap(&properties.connection_point)
182        };
183
184        unsafe { ffi::FMOD_ChannelGroup_OverrideReverbProperties(self.channel_group, &prop) }
185    }
186
187    pub fn override_3D_attributes(&self, pos: &vector::Vector, vel: &vector::Vector) -> ::Status {
188        let mut t_pos = vector::get_ffi(pos);
189        let mut t_vel = vector::get_ffi(vel);
190
191        unsafe { ffi::FMOD_ChannelGroup_Override3DAttributes(self.channel_group, &mut t_pos,
192                                                             &mut t_vel) }
193    }
194
195    pub fn override_speaker_mix(&self, front_left: f32, front_right: f32, center: f32, lfe: f32,
196                                back_left: f32, back_right: f32, side_left: f32,
197                                side_right: f32) -> ::Status {
198        unsafe { ffi::FMOD_ChannelGroup_OverrideSpeakerMix(self.channel_group, front_left,
199                                                           front_right, center, lfe, back_left,
200                                                           back_right, side_left, side_right) }
201    }
202
203    pub fn add_group(&self, group: &ChannelGroup) -> ::Status {
204        unsafe { ffi::FMOD_ChannelGroup_AddGroup(self.channel_group, group.channel_group) }
205    }
206
207    pub fn get_num_groups(&self) -> Result<i32, ::Status> {
208        let mut index = 0i32;
209
210        match unsafe { ffi::FMOD_ChannelGroup_GetNumGroups(self.channel_group, &mut index) } {
211            ::Status::Ok => Ok(index),
212            e => Err(e)
213        }
214    }
215
216    pub fn get_group(&self, index: i32) -> Result<ChannelGroup, ::Status> {
217        let mut group = ::std::ptr::null_mut();
218
219        match unsafe { ffi::FMOD_ChannelGroup_GetGroup(self.channel_group, index, &mut group) } {
220            ::Status::Ok => Ok(ChannelGroup{channel_group: group}),
221            e => Err(e)
222        }
223    }
224
225    pub fn get_parent_group(&self) -> Result<ChannelGroup, ::Status> {
226        let mut parent_group = ::std::ptr::null_mut();
227
228        match unsafe { ffi::FMOD_ChannelGroup_GetParentGroup(self.channel_group,
229                                                             &mut parent_group) } {
230            ::Status::Ok => Ok(ChannelGroup{channel_group: parent_group}),
231            e => Err(e)
232        }
233    }
234
235    pub fn get_DSP_head(&self) -> Result<dsp::Dsp, ::Status> {
236        let mut dsp = ::std::ptr::null_mut();
237
238        match unsafe { ffi::FMOD_ChannelGroup_GetDSPHead(self.channel_group, &mut dsp) } {
239            ::Status::Ok => Ok(ffi::FFI::wrap(dsp)),
240            e => Err(e)
241        }
242    }
243
244    pub fn add_DSP(&self, dsp: &dsp::Dsp) -> Result<dsp_connection::DspConnection, ::Status> {
245        let mut dsp_connection = ::std::ptr::null_mut();
246
247        match unsafe { ffi::FMOD_ChannelGroup_AddDSP(self.channel_group, ffi::FFI::unwrap(dsp),
248                                                     &mut dsp_connection) } {
249            ::Status::Ok => Ok(ffi::FFI::wrap(dsp_connection)),
250            e => Err(e)
251        }
252    }
253
254    pub fn get_name(&self, name_len: usize) -> Result<String, ::RStatus> {
255        let mut c = Vec::with_capacity(name_len + 1);
256
257        for _ in 0..(name_len + 1) {
258            c.push(0);
259        }
260
261        match unsafe { ffi::FMOD_ChannelGroup_GetName(self.channel_group,
262                                                      c.as_mut_ptr() as *mut c_char,
263                                                      name_len as i32) } {
264            ::Status::Ok => Ok(from_utf8!(c)),
265            e => Err(::RStatus::FMOD(e)),
266        }
267    }
268
269    pub fn get_num_channels(&self) -> Result<u32, ::Status> {
270        let mut num_channels = 0i32;
271
272        match unsafe { ffi::FMOD_ChannelGroup_GetNumChannels(self.channel_group,
273                                                             &mut num_channels) } {
274            ::Status::Ok => Ok(num_channels as u32),
275            e => Err(e)
276        }
277    }
278
279    pub fn get_channel(&self, index: i32) -> Result<channel::Channel, ::Status> {
280        let mut channel = ::std::ptr::null_mut();
281
282        match unsafe { ffi::FMOD_ChannelGroup_GetChannel(self.channel_group, index,
283                                                         &mut channel) } {
284            ::Status::Ok => Ok(ffi::FFI::wrap(channel)),
285            e => Err(e)
286        }
287    }
288
289    pub fn get_spectrum(&self, spectrum_size: usize, channel_offset: Option<i32>,
290                        window_type: Option<::DspFftWindow>) -> Result<Vec<f32>, ::Status> {
291        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(spectrum_size).collect();
292        let c_window_type = match window_type {
293            Some(wt) => wt,
294            None => ::DspFftWindow::Rect
295        };
296        let c_channel_offset = channel_offset.unwrap_or(0);
297
298        match unsafe { ffi::FMOD_ChannelGroup_GetSpectrum(self.channel_group, ptr.as_mut_ptr(),
299                                                          spectrum_size as c_int, c_channel_offset,
300                                                          c_window_type) } {
301            ::Status::Ok => Ok(ptr),
302            e => Err(e),
303        }
304    }
305
306    pub fn get_wave_data(&self, wave_size: usize,
307                         channel_offset: i32) -> Result<Vec<f32>, ::Status> {
308        let mut ptr : Vec<f32> = ::std::iter::repeat(0f32).take(wave_size).collect();
309
310        match unsafe { ffi::FMOD_ChannelGroup_GetWaveData(self.channel_group, ptr.as_mut_ptr(),
311                                                          wave_size as c_int, channel_offset) } {
312            ::Status::Ok => Ok(ptr),
313            e => Err(e)
314        }
315    }
316
317    pub fn get_memory_info(&self, MemoryBits(memory_bits): MemoryBits,
318                           EventMemoryBits(event_memory_bits): EventMemoryBits)
319                           -> Result<(u32, MemoryUsageDetails), ::Status> {
320        let mut details = fmod_sys::get_memory_usage_details_ffi(Default::default());
321        let mut memory_used = 0u32;
322
323        match unsafe { ffi::FMOD_ChannelGroup_GetMemoryInfo(self.channel_group, memory_bits,
324                                                            event_memory_bits, &mut memory_used,
325                                                            &mut details) } {
326            ::Status::Ok => Ok((memory_used, fmod_sys::from_memory_usage_details_ptr(details))),
327            e => Err(e)
328        }
329    }
330
331    pub fn set_user_data<'r, T>(&'r self, user_data: &'r mut T) -> ::Status {
332        unsafe { ffi::FMOD_ChannelGroup_SetUserData(self.channel_group, transmute(user_data)) }
333    }
334
335    pub fn get_user_data<'r, T>(&'r self) -> Result<&'r mut T, ::Status> {
336        unsafe {
337            let mut user_data : *mut c_void = ::std::ptr::null_mut();
338
339            match ffi::FMOD_ChannelGroup_GetUserData(self.channel_group, &mut user_data) {
340               ::Status::Ok => {
341                    let tmp : &mut T = transmute::<*mut c_void, &mut T>(user_data);
342                    Ok(tmp)
343                },
344                e => Err(e)
345            }
346        }
347    }
348}