1use std;
2use num_derive::FromPrimitive;
3use crate::{ll, fmod_result, vector, ChannelControl, ChannelGroup,
4 ChannelGroupRef, Dsp, DspRef, Delay, Error, Mode, SoundRef, Timeunit};
5
6#[derive(Clone, Debug, PartialEq)]
22pub struct Channel {
23 inner : Inner,
24 sound_ref : SoundRef
25}
26
27#[derive(Clone, PartialEq)]
29struct Inner (*mut ll::FMOD_CHANNEL);
30
31bitflags!{
32 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
33 pub struct Channelmask : u32 {
34 const FRONTLEFT = ll::FMOD_CHANNELMASK_FRONT_LEFT;
35 const FRONTRIGHT = ll::FMOD_CHANNELMASK_FRONT_RIGHT;
36 const FRONTCENTER = ll::FMOD_CHANNELMASK_FRONT_CENTER;
37 const LOWFREQUENCY = ll::FMOD_CHANNELMASK_LOW_FREQUENCY;
38 const SURROUNDLEFT = ll::FMOD_CHANNELMASK_SURROUND_LEFT;
39 const SURROUNDRIGHT = ll::FMOD_CHANNELMASK_SURROUND_RIGHT;
40 const BACKLEFT = ll::FMOD_CHANNELMASK_BACK_LEFT;
41 const BACKRIGHT = ll::FMOD_CHANNELMASK_BACK_RIGHT;
42 const BACKCENTER = ll::FMOD_CHANNELMASK_BACK_CENTER;
43 const MONO = ll::FMOD_CHANNELMASK_MONO;
44 const STEREO = ll::FMOD_CHANNELMASK_STEREO;
45 const LRC = ll::FMOD_CHANNELMASK_LRC;
46 const QUAD = ll::FMOD_CHANNELMASK_QUAD;
47 const SURROUND = ll::FMOD_CHANNELMASK_SURROUND;
48 const _5POINT1 = ll::FMOD_CHANNELMASK_5POINT1;
49 const _5POINT1REARS = ll::FMOD_CHANNELMASK_5POINT1_REARS;
50 const _7POINT0 = ll::FMOD_CHANNELMASK_7POINT0;
51 const _7POINT1 = ll::FMOD_CHANNELMASK_7POINT1;
52 }
53}
54
55#[derive(Copy, Clone, Debug, Eq, PartialEq, FromPrimitive)]
56#[derive(Default)]
57pub enum Channelorder {
58 #[default]
59 Default = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_DEFAULT as isize,
60 Waveformat = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_WAVEFORMAT as isize,
61 Protools = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_PROTOOLS as isize,
62 Allmono = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_ALLMONO as isize,
63 Allstereo = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_ALLSTEREO as isize,
64 Alsa = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_ALSA as isize,
65 MAX = ll::FMOD_CHANNELORDER_FMOD_CHANNELORDER_MAX as isize
66}
67
68impl Channel {
69 #[inline]
70 pub const fn from_raw_parts (raw : *mut ll::FMOD_CHANNEL, sound_ref : SoundRef)
71 -> Self
72 {
73 let inner = Inner (raw);
74 Channel { inner, sound_ref }
75 }
76
77 #[inline]
79 pub fn sound_ref (&self) -> SoundRef {
80 self.sound_ref.clone()
81 }
82
83 #[inline]
85 pub fn get_channel_group (&self) -> Result <ChannelGroupRef, Error> {
86 let mut raw = std::ptr::null_mut();
87 unsafe {
88 fmod_result!(ll::FMOD_Channel_GetChannelGroup (self.inner.0, &mut raw))?;
89 }
90 let channel_group = ChannelGroup::from_raw_parts (raw, false,
91 self.sound_ref.sound.system.clone());
92 Ok (ChannelGroupRef { channel_group })
93 }
94
95 #[inline]
96 pub fn get_frequency (&self) -> Result <f32, Error> {
97 let mut frequency = 0.0;
98 unsafe {
99 fmod_result!(
100 ll::FMOD_Channel_GetFrequency (self.inner.0, &mut frequency)
101 )?;
102 }
103 Ok (frequency)
104 }
105
106 #[inline]
111 pub fn get_index (&self) -> Result <i32, Error> {
112 let mut index = 0;
113 unsafe {
114 fmod_result!(ll::FMOD_Channel_GetIndex (self.inner.0, &mut index))?;
115 }
116 Ok (index)
117 }
118
119 #[inline]
120 pub fn get_loop_count (&self) -> Result <i32, Error> {
121 let mut loopcount = 0;
122 unsafe {
123 fmod_result!(ll::FMOD_Channel_GetLoopCount (self.inner.0, &mut loopcount))?;
124 }
125 Ok (loopcount)
126 }
127
128 #[inline]
129 pub fn get_loop_points (&self,
130 loopstarttype : Timeunit, loopendtype : Timeunit
131 ) -> Result <(u32, u32), Error> {
132 let mut loopstart = 0;
133 let mut loopend = 0;
134 unsafe {
135 fmod_result!(ll::FMOD_Channel_GetLoopPoints (self.inner.0,
136 &mut loopstart, loopstarttype.bits(),
137 &mut loopend, loopendtype.bits())
138 )?;
139 }
140 Ok ((loopstart, loopend))
141 }
142
143 #[inline]
144 pub fn get_position (&self, timeunit : Timeunit) -> Result <u32, Error> {
145 let mut position = 0;
146 unsafe {
147 fmod_result!(ll::FMOD_Channel_GetPosition (self.inner.0,
148 &mut position, timeunit.bits())
149 )?;
150 }
151 Ok (position)
152 }
153
154 #[inline]
155 pub fn get_priority (&self) -> Result <i32, Error> {
156 let mut priority = 0;
157 unsafe {
158 fmod_result!(ll::FMOD_Channel_GetPriority (self.inner.0, &mut priority))?;
159 }
160 Ok (priority)
161 }
162
163 #[inline]
164 pub fn is_virtual (&self) -> Result <bool, Error> {
165 let mut isvirtual = 0;
166 unsafe {
167 fmod_result!(ll::FMOD_Channel_IsVirtual (self.inner.0, &mut isvirtual))?;
168 }
169 Ok (isvirtual != 0)
170 }
171
172 #[inline]
173 pub fn set_frequency (&mut self, frequency : f32) -> Result <(), Error> {
174 unsafe {
175 fmod_result!(ll::FMOD_Channel_SetFrequency (self.inner.0, frequency))
176 }
177 }
178
179 #[inline]
180 pub fn set_position (&mut self, position : u32, postype : Timeunit)
181 -> Result <(), Error>
182 {
183 unsafe {
184 fmod_result!(
185 ll::FMOD_Channel_SetPosition (self.inner.0, position, postype.bits())
186 )
187 }
188 }
189
190}
191
192impl ChannelControl for Channel {
193 #[inline]
204 fn add_dsp (&mut self, index : i32, dsp : &mut Dsp) -> Result <(), Error> {
205 unsafe {
206 fmod_result!(ll::FMOD_Channel_AddDSP (self.inner.0, index, dsp.raw()))?;
207 }
208 Ok (())
209 }
210
211 #[inline]
212 fn add_fade_point (&mut self, dspclock : u64, volume : f32)
213 -> Result <(), Error>
214 {
215 unsafe {
216 fmod_result!(ll::FMOD_Channel_AddFadePoint (
217 self.inner.0, dspclock, volume))
218 }
219 }
220
221 #[inline]
222 fn get_3d_attributes (&self) -> Result <([f32; 3], [f32; 3]), Error> {
223 let mut pos = vector::to_ll ([0.0; 3]);
224 let mut vel = vector::to_ll ([0.0; 3]);
225 let mut alt_pan_pos = vector::to_ll ([0.0; 3]); unsafe {
227 fmod_result!(ll::FMOD_Channel_Get3DAttributes (self.inner.0,
228 &mut pos, &mut vel, &mut alt_pan_pos)
229 )?;
230 }
231 Ok ((vector::from_ll (pos), vector::from_ll (vel)))
232 }
233
234 #[inline]
235 fn get_3d_cone_orientation (&self) -> Result <[f32; 3], Error> {
236 let mut orientation = vector::to_ll ([0.0; 3]);
237 unsafe {
238 fmod_result!(
239 ll::FMOD_Channel_Get3DConeOrientation (self.inner.0, &mut orientation)
240 )?;
241 }
242 Ok (vector::from_ll (orientation))
243 }
244
245 #[inline]
250 fn get_3d_cone_settings (&self) -> Result <(f32, f32, f32), Error> {
251 let mut insideconeangle = 0.0;
252 let mut outsideconeangle = 0.0;
253 let mut outsidevolume = 0.0;
254 unsafe {
255 fmod_result!(ll::FMOD_Channel_Get3DConeSettings (self.inner.0,
256 &mut insideconeangle, &mut outsideconeangle, &mut outsidevolume
257 ))?;
258 }
259 Ok ((insideconeangle, outsideconeangle, outsidevolume))
260 }
261
262 fn get_3d_custom_rolloff (&self) -> Result <Vec <[f32; 3]>, Error> {
263 let mut points = std::ptr::null_mut();
264 let mut numpoints = 0;
265 unsafe {
266 fmod_result!(
267 ll::FMOD_Channel_Get3DCustomRolloff (self.inner.0,
268 &mut points, &mut numpoints)
269 )?;
270 }
271 debug_assert!(numpoints >= 0);
272 #[expect(clippy::cast_sign_loss)]
273 let mut curve = Vec::with_capacity (numpoints as usize);
274 for i in 0..numpoints as isize {
275 let point = unsafe {
276 std::ptr::read (points.offset (i) as *const ll::FMOD_VECTOR)
277 };
278 curve.push (vector::from_ll (point));
279 }
280 Ok (curve)
281 }
282
283 #[inline]
288 fn get_3d_distance_filter (&self) -> Result <(bool, f32, f32), Error> {
289 let mut custom = 0;
290 let mut customlevel = 0.0;
291 let mut centerfreq = 0.0;
292 unsafe {
293 fmod_result!(ll::FMOD_Channel_Get3DDistanceFilter (self.inner.0,
294 &mut custom, &mut customlevel, &mut centerfreq)
295 )?;
296 }
297 let custom = custom != 0;
298 Ok ((custom, customlevel, centerfreq))
299 }
300
301 #[inline]
302 fn get_3d_doppler_level (&self) -> Result <f32, Error> {
303 let mut level = 0.0;
304 unsafe {
305 fmod_result!(ll::FMOD_Channel_Get3DDopplerLevel (self.inner.0, &mut level))?;
306 }
307 Ok (level)
308 }
309
310 #[inline]
312 fn get_3d_min_max_distance (&self) -> Result <(f32, f32), Error> {
313 let mut mindistance = 0.0;
314 let mut maxdistance = 0.0;
315 unsafe {
316 fmod_result!(ll::FMOD_Channel_Get3DMinMaxDistance (self.inner.0,
317 &mut mindistance, &mut maxdistance)
318 )?;
319 }
320 Ok ((mindistance, maxdistance))
321 }
322
323 #[inline]
327 fn get_3d_occlusion (&self) -> Result <(f32, f32), Error> {
328 let mut directocclusion = 0.0;
329 let mut reverbocclusion = 0.0;
330 unsafe {
331 fmod_result!(ll::FMOD_Channel_Get3DOcclusion (self.inner.0,
332 &mut directocclusion, &mut reverbocclusion)
333 )?;
334 }
335 Ok ((directocclusion, reverbocclusion))
336 }
337
338 #[inline]
342 fn get_3d_spread (&self) -> Result <f32, Error> {
343 let mut angle = 0.0;
344 unsafe {
345 fmod_result!(ll::FMOD_Channel_Get3DSpread (self.inner.0, &mut angle))?;
346 }
347 Ok (angle)
348 }
349
350 #[inline]
351 fn get_audibility (&self) -> Result <f32, Error> {
352 let mut audibility = 0.0;
353 unsafe {
354 fmod_result!(
355 ll::FMOD_Channel_GetAudibility (self.inner.0, &mut audibility)
356 )?;
357 }
358 Ok (audibility)
359 }
360
361 #[inline]
362 fn get_delay (&self) -> Result <Delay, Error> {
363 let mut dspclock_start = 0;
364 let mut dspclock_end = 0;
365 let mut stopchannels = 0;
366 unsafe {
367 fmod_result!(ll::FMOD_Channel_GetDelay (self.inner.0,
368 &mut dspclock_start,
369 &mut dspclock_end,
370 &mut stopchannels
371 ))?;
372 }
373 let stopchannels = stopchannels != 0;
374 Ok (Delay { dspclock_start, dspclock_end, stopchannels })
375 }
376
377 #[inline]
379 fn get_dsp (&self, index : i32) -> Result <DspRef, Error> {
380 let mut raw = std::ptr::null_mut();
381 unsafe {
382 fmod_result!(ll::FMOD_Channel_GetDSP (self.inner.0, index, &mut raw))?;
383 }
384 let dsp =
385 Dsp::from_raw_parts (raw, false, self.sound_ref.sound.system.clone());
386 Ok (DspRef { dsp })
387 }
388
389 #[inline]
391 fn get_dsp_clock (&self) -> Result <u64, Error> {
392 let mut dspclock = 0;
393 let parentclock = std::ptr::null_mut();
394 unsafe {
395 fmod_result!(
396 ll::FMOD_Channel_GetDSPClock (self.inner.0, &mut dspclock, parentclock)
397 )?;
398 }
399 Ok (dspclock)
400 }
401
402 #[inline]
404 fn get_dsp_clock_parent (&self) -> Result <u64, Error> {
405 let dspclock = std::ptr::null_mut();
406 let mut parentclock = 0;
407 unsafe {
408 fmod_result!(
409 ll::FMOD_Channel_GetDSPClock (self.inner.0, dspclock, &mut parentclock)
410 )?;
411 }
412 Ok (parentclock)
413 }
414
415 #[inline]
417 fn get_dsp_index (&self, dsp : &Dsp) -> Result <i32, Error> {
418 let mut index = 0;
419 unsafe {
420 fmod_result!(
421 ll::FMOD_Channel_GetDSPIndex (self.inner.0, dsp.raw(), &mut index)
422 )?;
423 }
424 Ok (index)
425 }
426
427 #[inline]
428 fn get_low_pass_gain (&self) -> Result <f32, Error> {
429 let mut gain = 0.0;
430 unsafe {
431 fmod_result!(ll::FMOD_Channel_GetLowPassGain (self.inner.0, &mut gain))?;
432 }
433 Ok (gain)
434 }
435
436 #[inline]
437 fn get_mode (&self) -> Result <Mode, Error> {
438 let mut mode = 0;
439 unsafe {
440 fmod_result!(ll::FMOD_Channel_GetMode (self.inner.0, &mut mode))?;
441 }
442 Ok (Mode::from_bits (mode).unwrap())
443 }
444
445 #[inline]
446 fn get_mute (&self) -> Result <bool, Error> {
447 let mut mute = 0;
448 unsafe {
449 fmod_result!(ll::FMOD_Channel_GetMute (self.inner.0, &mut mute))?;
450 }
451 Ok (mute != 0)
452 }
453
454 #[inline]
456 fn get_num_dsps (&self) -> Result <u32, Error> {
457 let mut num = 0;
458 unsafe {
459 fmod_result!(ll::FMOD_Channel_GetNumDSPs (self.inner.0, &mut num))?;
460 }
461 debug_assert!(num >= 0);
462 #[expect(clippy::cast_sign_loss)]
463 Ok (num as u32)
464 }
465
466 #[inline]
467 fn get_paused (&self) -> Result <bool, Error> {
468 let mut paused = 0;
469 unsafe {
470 fmod_result!(ll::FMOD_Channel_GetPaused (self.inner.0, &mut paused))?;
471 }
472 Ok (paused != 0)
473 }
474
475 #[inline]
483 fn get_reverb_properties (&self, instance : i32) -> Result <f32, Error> {
484 let mut wet = 0.0;
485 unsafe {
486 fmod_result!(
487 ll::FMOD_Channel_GetReverbProperties (self.inner.0, instance, &mut wet)
488 )?;
489 }
490 Ok (wet)
491 }
492
493 #[inline]
494 fn get_volume (&self) -> Result <f32, Error> {
495 let mut volume = 0.0;
496 unsafe {
497 fmod_result!(ll::FMOD_Channel_GetVolume (self.inner.0, &mut volume))?;
498 }
499 Ok (volume)
500 }
501
502 #[inline]
503 fn is_playing (&self) -> Result <bool, Error> {
504 let mut isplaying = 0;
505 unsafe {
506 fmod_result!(ll::FMOD_Channel_IsPlaying (self.inner.0, &mut isplaying))?;
507 }
508 Ok (isplaying != 0)
509 }
510
511 #[inline]
512 fn remove_dsp (&mut self, dsp : &mut Dsp) -> Result <(), Error> {
513 unsafe {
514 fmod_result!(ll::FMOD_Channel_RemoveDSP (self.inner.0, dsp.raw()))?;
515 }
516 Ok (())
517 }
518
519 #[inline]
520 fn set_3d_attributes (&mut self, pos : [f32; 3], vel : [f32; 3])
521 -> Result <(), Error>
522 {
523 let pos = vector::to_ll (pos);
524 let vel = vector::to_ll (vel);
525 const ALT_PAN_POS : ll::FMOD_VECTOR = vector::to_ll ([0.0; 3]);
527 unsafe {
528 fmod_result!(
529 ll::FMOD_Channel_Set3DAttributes (self.inner.0, &pos, &vel, &ALT_PAN_POS)
530 )?;
531 };
532 Ok (())
533 }
534
535 #[inline]
536 fn set_delay (&mut self,
537 dspclock_start : u64, dspclock_end : u64, stopchannels : bool
538 ) -> Result <(), Error> {
539 unsafe {
540 fmod_result!(
541 ll::FMOD_Channel_SetDelay (self.inner.0, dspclock_start, dspclock_end,
542 stopchannels as i32))
543 }
544 }
545
546 #[inline]
547 fn set_fade_point_ramp (&mut self, dspclock : u64, volume : f32)
548 -> Result <(), Error>
549 {
550 unsafe {
551 fmod_result!(
552 ll::FMOD_Channel_SetFadePointRamp (self.inner.0, dspclock, volume))
553 }
554 }
555
556 #[inline]
557 fn set_mute (&mut self, mute : bool) -> Result <(), Error> {
558 unsafe {
559 fmod_result!(ll::FMOD_Channel_SetMute (self.inner.0, mute as i32))
560 }
561 }
562
563 #[inline]
564 fn set_paused (&mut self, paused : bool) -> Result <(), Error> {
565 unsafe {
566 fmod_result!(ll::FMOD_Channel_SetPaused (self.inner.0, paused as i32))
567 }
568 }
569
570 #[inline]
571 fn set_reverb_properties (&mut self, instance : i32, wet : f32)
572 -> Result <(), Error>
573 {
574 unsafe {
575 fmod_result!(
576 ll::FMOD_Channel_SetReverbProperties (self.inner.0, instance, wet))
577 }
578 }
579
580 #[inline]
581 fn set_volume (&mut self, volume : f32) -> Result <(), Error> {
582 unsafe {
583 fmod_result!(ll::FMOD_Channel_SetVolume (self.inner.0, volume))
584 }
585 }
586
587 #[inline]
588 fn stop (&mut self) -> Result <(), Error> {
589 unsafe {
590 fmod_result!(ll::FMOD_Channel_Stop (self.inner.0))
591 }
592 }
593
594}
595
596
597impl Default for Channelmask {
598 fn default() -> Self {
599 Channelmask::empty()
600 }
601}
602
603impl std::fmt::Debug for Inner {
604 fn fmt (&self, f : &mut std::fmt::Formatter) -> std::fmt::Result {
605 write!(f, "{:p}", self.0)
606 }
607}