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