wavecraft_metering/
lib.rs1pub use wavecraft_protocol::MeterFrame;
7
8pub struct MeterProducer {
12 producer: rtrb::Producer<MeterFrame>,
13}
14
15impl MeterProducer {
16 #[inline]
21 pub fn push(&mut self, frame: MeterFrame) {
22 let _ = self.producer.push(frame);
24 }
25
26 #[inline]
28 pub fn available_write(&self) -> usize {
29 self.producer.slots()
30 }
31}
32
33pub struct MeterConsumer {
37 consumer: rtrb::Consumer<MeterFrame>,
38}
39
40impl MeterConsumer {
41 pub fn read_latest(&mut self) -> Option<MeterFrame> {
46 let mut latest = None;
47 while let Ok(frame) = self.consumer.pop() {
48 latest = Some(frame);
49 }
50 latest
51 }
52
53 pub fn pop(&mut self) -> Option<MeterFrame> {
57 self.consumer.pop().ok()
58 }
59
60 pub fn available_read(&self) -> usize {
62 self.consumer.slots()
63 }
64}
65
66pub fn create_meter_channel(capacity: usize) -> (MeterProducer, MeterConsumer) {
73 let (producer, consumer) = rtrb::RingBuffer::new(capacity);
74 (MeterProducer { producer }, MeterConsumer { consumer })
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 fn empty_frame() -> MeterFrame {
82 MeterFrame {
83 peak_l: 0.0,
84 peak_r: 0.0,
85 rms_l: 0.0,
86 rms_r: 0.0,
87 timestamp: 0,
88 }
89 }
90
91 #[test]
92 fn meter_ring_push_pop() {
93 let (mut producer, mut consumer) = create_meter_channel(4);
94
95 let frame = MeterFrame {
96 peak_l: 0.5,
97 peak_r: 0.6,
98 rms_l: 0.3,
99 rms_r: 0.4,
100 timestamp: 1000,
101 };
102
103 producer.push(frame);
104 let read = consumer.pop().expect("should read frame");
105
106 assert_eq!(read.peak_l, 0.5);
107 assert_eq!(read.peak_r, 0.6);
108 assert_eq!(read.rms_l, 0.3);
109 assert_eq!(read.rms_r, 0.4);
110 assert_eq!(read.timestamp, 1000);
111 }
112
113 #[test]
114 fn meter_ring_overflow() {
115 let (mut producer, mut consumer) = create_meter_channel(2);
116
117 producer.push(MeterFrame {
119 peak_l: 1.0,
120 ..empty_frame()
121 });
122 producer.push(MeterFrame {
123 peak_l: 2.0,
124 ..empty_frame()
125 });
126
127 producer.push(MeterFrame {
129 peak_l: 3.0,
130 ..empty_frame()
131 });
132
133 assert_eq!(consumer.pop().unwrap().peak_l, 1.0);
135 assert_eq!(consumer.pop().unwrap().peak_l, 2.0);
136
137 assert!(consumer.pop().is_none());
139 }
140
141 #[test]
142 fn read_latest_discards_old() {
143 let (mut producer, mut consumer) = create_meter_channel(8);
144
145 for i in 0..5 {
147 producer.push(MeterFrame {
148 peak_l: i as f32,
149 ..empty_frame()
150 });
151 }
152
153 let latest = consumer.read_latest().expect("should have frame");
155 assert_eq!(latest.peak_l, 4.0);
156
157 assert!(consumer.pop().is_none());
159 }
160
161 #[test]
162 fn empty_buffer_returns_none() {
163 let (_, mut consumer) = create_meter_channel(4);
164 assert!(consumer.pop().is_none());
165 assert!(consumer.read_latest().is_none());
166 }
167
168 #[test]
169 fn available_counts() {
170 let (mut producer, mut consumer) = create_meter_channel(4);
171
172 assert_eq!(consumer.available_read(), 0);
173
174 producer.push(empty_frame());
175 producer.push(empty_frame());
176
177 assert_eq!(consumer.available_read(), 2);
178
179 consumer.pop();
180 assert_eq!(consumer.available_read(), 1);
181 }
182}