use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[must_use]
pub struct FatigueState {
fatigue: f32,
alarm_habituation: f32,
bout_calling_time: f32,
alarm_count: u32,
alarm_reinforced: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[must_use]
pub struct FatigueModifiers {
pub pitch_offset: f32,
pub breathiness_delta: f32,
pub amplitude_scale: f32,
pub jitter_scale: f32,
}
impl FatigueState {
pub fn new() -> Self {
Self {
fatigue: 0.0,
alarm_habituation: 0.0,
bout_calling_time: 0.0,
alarm_count: 0,
alarm_reinforced: false,
}
}
#[must_use]
pub fn fatigue(&self) -> f32 {
self.fatigue
}
#[must_use]
pub fn alarm_habituation(&self) -> f32 {
self.alarm_habituation
}
pub fn record_call(&mut self, duration: f32, is_alarm: bool) {
self.bout_calling_time += duration;
let fatigue_rate = 0.015; self.fatigue = (self.fatigue + duration * fatigue_rate).clamp(0.0, 1.0);
if is_alarm {
self.alarm_count += 1;
if !self.alarm_reinforced {
self.alarm_habituation = (self.alarm_habituation + 0.1).clamp(0.0, 1.0);
}
}
}
pub fn rest(&mut self, duration: f32) {
let recovery_rate = 0.07; self.fatigue = (self.fatigue - duration * recovery_rate).max(0.0);
let habituation_decay = 0.023; self.alarm_habituation = (self.alarm_habituation - duration * habituation_decay).max(0.0);
if duration > 5.0 {
self.bout_calling_time = 0.0;
}
}
pub fn reinforce_alarm(&mut self) {
self.alarm_reinforced = true;
self.alarm_habituation = (self.alarm_habituation - 0.3).max(0.0);
self.alarm_count = 0;
}
pub fn clear_reinforcement(&mut self) {
self.alarm_reinforced = false;
}
#[must_use = "returns fatigue modifiers that should be applied to synthesis"]
pub fn modifiers(&self) -> FatigueModifiers {
let pitch_offset = -self.fatigue * 20.0;
let breathiness_delta = self.fatigue * 0.2;
let fatigue_amp = 1.0 - self.fatigue * 0.4;
let habituation_amp = 1.0 - self.alarm_habituation * 0.5;
let amplitude_scale = fatigue_amp * habituation_amp;
let jitter_scale = 1.0 + self.fatigue * 1.5;
FatigueModifiers {
pitch_offset,
breathiness_delta,
amplitude_scale,
jitter_scale,
}
}
pub fn reset(&mut self) {
*self = Self::new();
}
}
impl Default for FatigueState {
fn default() -> Self {
Self::new()
}
}