1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
// Copyright (c) 2024 Lily Lyons
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::ffi::c_ulonglong;
use fmod_sys::*;
use crate::ChannelControl;
impl ChannelControl {
/// Retrieves the DSP clock values at this point in time.
///
/// To perform sample accurate scheduling in conjunction with ChannelControl::setDelay and ChannelControl::addFadePoint query the parentclock value.
pub fn get_dsp_clock(&self) -> Result<(c_ulonglong, c_ulonglong)> {
let mut dsp_clock = 0;
let mut parent_clock = 0;
unsafe {
FMOD_ChannelControl_GetDSPClock(self.inner, &mut dsp_clock, &mut parent_clock)
.to_result()?;
}
Ok((dsp_clock, parent_clock))
}
/// Sets a sample accurate start (and/or stop) time relative to the parent ChannelGroup DSP clock.
///
/// To perform sample accurate scheduling use ChannelControl::getDSPClock to query the parent clock value.
/// If a parent ChannelGroup changes its pitch, the start and stop times will still be correct as the parent clock rate is adjusted by that pitch.
pub fn set_delay(
&self,
start: c_ulonglong,
end: c_ulonglong,
stop_channels: bool,
) -> Result<()> {
unsafe { FMOD_ChannelControl_SetDelay(self.inner, start, end, stop_channels).to_result() }
}
/// Retrieves a sample accurate start (and/or stop) time relative to the parent ChannelGroup DSP clock.
pub fn get_delay(&self) -> Result<(c_ulonglong, c_ulonglong, bool)> {
let mut dsp_start = 0;
let mut dsp_end = 0;
let mut stop_channels = false;
unsafe {
FMOD_ChannelControl_GetDelay(
self.inner,
&mut dsp_start,
&mut dsp_end,
&mut stop_channels,
)
.to_result()?;
}
Ok((dsp_start, dsp_end, stop_channels))
}
/// Adds a sample accurate fade point at a time relative to the parent ChannelGroup DSP clock.
///
/// Fade points are scaled against other volume settings and in-between each fade point the volume will be linearly ramped.
///
/// To perform sample accurate fading use ChannelControl::getDSPClock to query the parent clock value.
/// If a parent ChannelGroup changes its pitch, the fade points will still be correct as the parent clock rate is adjusted by that pitch.
///
/// ```rs
/// // Example. Ramp from full volume to half volume over the next 4096 samples
/// let (_, parent) = target.get_dsp_clock();
/// target.add_fade_point(parent, 1.0);
/// target.add_fade_point(parent + 4096, 0.5);
/// ```
pub fn add_fade_point(&self, dsp_clock: c_ulonglong, volume: f32) -> Result<()> {
unsafe { FMOD_ChannelControl_AddFadePoint(self.inner, dsp_clock, volume).to_result() }
}
/// Adds a volume ramp at the specified time in the future using fade points.
///
/// This is a convenience function that creates a scheduled 64 sample fade point ramp from the current volume level to volume arriving at `dsp_clock` time.
///
/// Can be use in conjunction with ChannelControl::SetDelay.
///
/// All fade points after `dsp_clock` will be removed.
pub fn set_fade_point_ramp(&self, dsp_clock: c_ulonglong, volume: f32) -> Result<()> {
unsafe { FMOD_ChannelControl_SetFadePointRamp(self.inner, dsp_clock, volume).to_result() }
}
/// Removes all fade points between the two specified clock values (inclusive).
pub fn remove_fade_points(
&self,
dsp_clock_start: c_ulonglong,
dsp_clock_end: c_ulonglong,
) -> Result<()> {
unsafe {
FMOD_ChannelControl_RemoveFadePoints(self.inner, dsp_clock_start, dsp_clock_end)
.to_result()
}
}
/// Retrieves information about stored fade points.
pub fn get_fade_points(&self) -> Result<(Vec<c_ulonglong>, Vec<f32>)> {
let mut num_points = 0;
unsafe {
FMOD_ChannelControl_GetFadePoints(
self.inner,
&mut num_points,
std::ptr::null_mut(),
std::ptr::null_mut(),
)
.to_result()?;
}
let mut dsp_clocks = vec![0; num_points as usize];
let mut volumes = vec![0.0; num_points as usize];
unsafe {
FMOD_ChannelControl_GetFadePoints(
self.inner,
&mut num_points,
dsp_clocks.as_mut_ptr(),
volumes.as_mut_ptr(),
)
.to_result()?;
}
Ok((dsp_clocks, volumes))
}
}