#![allow(unused)]
use std::time::Duration;
use crate::utils::buffer::scale_buffer;
#[derive(PartialEq, Clone, Copy)]
pub enum FaderState {
Stopped,
IsRunning,
Finished,
}
#[derive(Clone, Copy)]
pub struct VolumeFader {
state: FaderState,
current_volume: f32,
target_volume: f32,
inertia: f32,
channel_count: usize,
sample_rate: u32,
}
impl VolumeFader {
pub fn new(channel_count: usize, sample_rate: u32) -> Self {
Self {
state: FaderState::Stopped,
current_volume: 1.0,
target_volume: 1.0,
inertia: 1.0,
channel_count,
sample_rate,
}
}
pub fn state(&self) -> FaderState {
self.state
}
pub fn target_volume(&self) -> f32 {
self.target_volume
}
pub fn start_fade_in(&mut self, duration: Duration) {
if self.state == FaderState::IsRunning {
self.start(self.current_volume, 1.0, duration)
} else {
self.start(0.0, 1.0, duration)
}
}
pub fn start_fade_out(&mut self, duration: Duration) {
if self.state == FaderState::IsRunning {
self.start(self.current_volume, 0.0, duration)
} else {
self.start(1.0, 0.0, duration)
}
}
pub fn start(&mut self, from: f32, to: f32, duration: Duration) {
if duration.is_zero() {
self.current_volume = to;
self.target_volume = to;
self.state = FaderState::Finished;
} else {
self.state = FaderState::IsRunning;
self.current_volume = from;
self.target_volume = to;
const LN100: f32 = 4.605;
let samples_duration = self.sample_rate as f32 * duration.as_secs_f32() / LN100;
self.inertia = 1.0 - (-1.0 / samples_duration).exp();
}
}
#[inline]
pub fn reset(&mut self) {
self.state = FaderState::Stopped;
self.current_volume = 1.0;
self.target_volume = 1.0;
}
pub fn process(&mut self, output: &mut [f32]) {
if self.state != FaderState::IsRunning {
if self.target_volume != 1.0 {
scale_buffer(output, self.target_volume);
}
} else {
for f in output.chunks_exact_mut(self.channel_count) {
self.current_volume += (self.target_volume - self.current_volume) * self.inertia;
for s in f.iter_mut() {
*s *= self.current_volume;
}
}
if (self.current_volume - self.target_volume).abs() < 0.0001 {
self.state = FaderState::Finished;
}
}
}
}