1use 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
38pub 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}