fmod/core/sound/
synchronization.rs1use std::{
8 ffi::{c_int, c_uint},
9 ptr::NonNull,
10};
11
12use crate::{FmodResultExt, Result};
13use fmod_sys::*;
14use lanyard::{Utf8CStr, Utf8CString};
15
16use crate::{Sound, TimeUnit, get_string};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20#[repr(transparent)] pub struct SyncPoint {
22 pub(crate) inner: NonNull<FMOD_SYNCPOINT>,
23}
24
25#[cfg(not(feature = "thread-unsafe"))]
26unsafe impl Send for SyncPoint {}
27#[cfg(not(feature = "thread-unsafe"))]
28unsafe impl Sync for SyncPoint {}
29
30impl SyncPoint {
31 pub unsafe fn from_ffi(value: *mut FMOD_SYNCPOINT) -> Self {
39 let inner = NonNull::new(value).unwrap();
40 SyncPoint { inner }
41 }
42
43 pub fn as_ptr(self) -> *mut FMOD_SYNCPOINT {
45 self.inner.as_ptr()
46 }
47}
48
49impl From<SyncPoint> for *mut FMOD_SYNCPOINT {
50 fn from(value: SyncPoint) -> Self {
51 value.inner.as_ptr()
52 }
53}
54
55impl Sound {
56 pub fn get_sync_point(&self, index: i32) -> Result<SyncPoint> {
60 let mut sync_point = std::ptr::null_mut();
61 unsafe {
62 FMOD_Sound_GetSyncPoint(self.inner.as_ptr(), index, &raw mut sync_point).to_result()?;
63 Ok(SyncPoint::from_ffi(sync_point))
64 }
65 }
66
67 pub fn get_sync_point_info(
71 &self,
72 point: SyncPoint,
73 offset_type: TimeUnit,
74 ) -> Result<(Utf8CString, c_uint)> {
75 let mut offset = 0;
76 let name = get_string(|name| unsafe {
77 FMOD_Sound_GetSyncPointInfo(
78 self.inner.as_ptr(),
79 point.into(),
80 name.as_mut_ptr().cast(),
81 name.len() as c_int,
82 &raw mut offset,
83 offset_type.into(),
84 )
85 })?;
86 Ok((name, offset))
87 }
88
89 pub fn get_sync_point_count(&self) -> Result<i32> {
93 let mut count = 0;
94 unsafe {
95 FMOD_Sound_GetNumSyncPoints(self.inner.as_ptr(), &raw mut count).to_result()?;
96 }
97 Ok(count)
98 }
99
100 pub fn add_sync_point(
104 &self,
105 offset: c_uint,
106 offset_type: TimeUnit,
107 name: &Utf8CStr,
108 ) -> Result<SyncPoint> {
109 let mut sync_point = std::ptr::null_mut();
110 unsafe {
111 FMOD_Sound_AddSyncPoint(
112 self.inner.as_ptr(),
113 offset,
114 offset_type.into(),
115 name.as_ptr(),
116 &raw mut sync_point,
117 )
118 .to_result()?;
119 Ok(SyncPoint::from_ffi(sync_point))
120 }
121 }
122
123 pub fn delete_sync_point(&self, point: SyncPoint) -> Result<()> {
127 unsafe {
128 FMOD_Sound_DeleteSyncPoint(self.inner.as_ptr(), point.into()).to_result()?;
129 }
130 Ok(())
131 }
132}