1use crate::output::DutyMode;
2
3pub const DEFAULT_SAMPLE_RATE_HZ: u32 = 16_000;
5
6pub const DEFAULT_PWM_CARRIER_HZ: u32 = 32_000;
8
9pub const DEFAULT_PWM_PERIOD: u16 = 1000;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct AudioConfig {
16 pub sample_rate_hz: u32,
17 pub pwm_period: u16,
18 pub duty_mode: DutyMode,
19 pub master_gain_q8: u8,
20}
21
22impl AudioConfig {
23 pub const fn new(sample_rate_hz: u32, pwm_period: u16, duty_mode: DutyMode) -> Self {
24 Self {
25 sample_rate_hz,
26 pwm_period,
27 duty_mode,
28 master_gain_q8: 255,
29 }
30 }
31
32 pub const fn default_duty() -> Self {
33 Self::new(
34 DEFAULT_SAMPLE_RATE_HZ,
35 DEFAULT_PWM_PERIOD,
36 DutyMode::SigmaDelta,
37 )
38 }
39
40 pub const fn master_gain_q8(mut self, gain: u8) -> Self {
41 self.master_gain_q8 = gain;
42 self
43 }
44}
45
46impl Default for AudioConfig {
47 fn default() -> Self {
48 Self::default_duty()
49 }
50}
51
52#[inline]
54pub const fn crossfade_step_q8(duration_ms: u16, sample_rate_hz: u32) -> u8 {
55 if duration_ms == 0 || sample_rate_hz == 0 {
56 return 255;
57 }
58 let samples = (duration_ms as u32 * sample_rate_hz) / 1000;
59 if samples == 0 {
60 return 255;
61 }
62 let step = 255u32.div_ceil(samples);
63
64 if step > 255 { 255 } else { step as u8 }
65}