autd3_driver/datagram/
silencer.rs1use std::{convert::Infallible, num::NonZeroU16};
2
3use autd3_core::{
4 common::{SILENCER_STEPS_INTENSITY_DEFAULT, SILENCER_STEPS_PHASE_DEFAULT, ULTRASOUND_PERIOD},
5 datagram::{Datagram, DeviceFilter},
6 derive::FirmwareLimits,
7 geometry::Geometry,
8};
9
10pub trait SilencerConfig: std::fmt::Debug + Clone + Copy {}
11impl SilencerConfig for () {}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct FixedCompletionTime {
16 pub intensity: std::time::Duration,
20 pub phase: std::time::Duration,
24 pub strict_mode: bool,
32}
33impl SilencerConfig for FixedCompletionTime {}
34
35impl Default for FixedCompletionTime {
36 fn default() -> Self {
37 FixedCompletionTime {
38 intensity: SILENCER_STEPS_INTENSITY_DEFAULT as u32 * ULTRASOUND_PERIOD,
39 phase: SILENCER_STEPS_PHASE_DEFAULT as u32 * ULTRASOUND_PERIOD,
40 strict_mode: true,
41 }
42 }
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47#[repr(C)]
48pub struct FixedCompletionSteps {
49 pub intensity: NonZeroU16,
53 pub phase: NonZeroU16,
57 pub strict_mode: bool,
65}
66impl SilencerConfig for FixedCompletionSteps {}
67
68impl Default for FixedCompletionSteps {
69 fn default() -> Self {
70 FixedCompletionSteps {
71 intensity: NonZeroU16::new(SILENCER_STEPS_INTENSITY_DEFAULT).unwrap(),
72 phase: NonZeroU16::new(SILENCER_STEPS_PHASE_DEFAULT).unwrap(),
73 strict_mode: true,
74 }
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80#[repr(C)]
81pub struct FixedUpdateRate {
82 pub intensity: NonZeroU16,
86 pub phase: NonZeroU16,
90}
91impl SilencerConfig for FixedUpdateRate {}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95pub struct Silencer<T: SilencerConfig> {
96 pub config: T,
98}
99
100impl<T: SilencerConfig> Silencer<T> {
101 #[must_use]
103 pub const fn new(config: T) -> Self {
104 Self { config }
105 }
106}
107
108impl Silencer<()> {
109 #[must_use]
111 pub const fn disable() -> Silencer<FixedCompletionSteps> {
112 Silencer {
113 config: FixedCompletionSteps {
114 intensity: NonZeroU16::MIN,
115 phase: NonZeroU16::MIN,
116 strict_mode: true,
117 },
118 }
119 }
120}
121
122impl Default for Silencer<FixedCompletionSteps> {
123 fn default() -> Self {
124 Silencer {
125 config: Default::default(),
126 }
127 }
128}
129
130impl<T: SilencerConfig> Datagram for Silencer<T> {
131 type G = T;
132 type Error = Infallible;
133
134 fn operation_generator(
135 self,
136 _: &Geometry,
137 _: &DeviceFilter,
138 _: &FirmwareLimits,
139 ) -> Result<Self::G, Self::Error> {
140 Ok(self.config)
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn disable() {
150 let s = Silencer::disable();
151 assert_eq!(1, s.config.intensity.get());
152 assert_eq!(1, s.config.phase.get());
153 assert!(s.config.strict_mode);
154 }
155
156 #[test]
157 fn fixed_completion_steps_default() {
158 let s: Silencer<FixedCompletionSteps> = Silencer::default();
159 assert_eq!(10, s.config.intensity.get());
160 assert_eq!(40, s.config.phase.get());
161 assert!(s.config.strict_mode);
162 }
163
164 #[test]
165 fn fixed_completion_time_default() {
166 let s: Silencer<FixedCompletionTime> = Silencer::new(Default::default());
167 assert_eq!(std::time::Duration::from_micros(250), s.config.intensity);
168 assert_eq!(std::time::Duration::from_micros(1000), s.config.phase);
169 assert!(s.config.strict_mode);
170 }
171}