atmos/kernel/
audio_stream_fmt.rs1use alloc::collections::VecDeque;
9
10pub const PWM_STREAM_CLOCK_HZ: u32 = 250_000_000;
12
13pub fn pwm_range(clock_hz: u32, sample_rate: u32) -> u32 {
15 if sample_rate == 0 {
16 return 0;
17 }
18 (clock_hz + sample_rate / 2) / sample_rate
19}
20
21pub fn sample_to_pwm(s: i16, range: u32) -> u32 {
23 let u = (s as i32 + 32768) as u64; ((u * range as u64) >> 16) as u32
25}
26
27pub struct PcmQueue {
29 samples: VecDeque<i16>,
30 pub channels: u32,
32 pub sample_rate: u32,
34}
35
36impl PcmQueue {
37 pub fn new(sample_rate: u32, channels: u32) -> Self {
38 PcmQueue { samples: VecDeque::new(), channels: channels.clamp(1, 2), sample_rate }
39 }
40
41 pub fn push(&mut self, pcm: &[i16]) {
43 self.samples.extend(pcm.iter().copied());
44 }
45
46 pub fn buffered_ms(&self) -> u64 {
48 let frames = self.samples.len() as u64 / self.channels as u64;
49 if self.sample_rate == 0 {
50 0
51 } else {
52 frames * 1000 / self.sample_rate as u64
53 }
54 }
55
56 pub fn clear(&mut self) {
57 self.samples.clear();
58 }
59
60 pub fn frames(&self) -> usize {
62 self.samples.len() / self.channels as usize
63 }
64
65 pub fn fill_words(&mut self, out: &mut [u32], range: u32) -> usize {
68 let silence = range / 2;
69 let mut filled = 0;
70 for pair in out.chunks_mut(2) {
71 let (l, r) = if self.channels >= 2 {
72 if self.samples.len() >= 2 {
73 let l = self.samples.pop_front().unwrap_or(0);
74 let r = self.samples.pop_front().unwrap_or(0);
75 filled += 1;
76 (sample_to_pwm(l, range), sample_to_pwm(r, range))
77 } else {
78 (silence, silence)
79 }
80 } else if let Some(m) = self.samples.pop_front() {
81 filled += 1;
82 let v = sample_to_pwm(m, range);
83 (v, v)
84 } else {
85 (silence, silence)
86 };
87 pair[0] = l;
88 if pair.len() > 1 {
89 pair[1] = r;
90 }
91 }
92 filled
93 }
94
95 pub fn drain_frames(&mut self, frames: usize) {
97 let n = (frames * self.channels as usize).min(self.samples.len());
98 self.samples.drain(..n);
99 }
100}