pub use wavecraft_protocol::MeterFrame;
pub struct MeterProducer {
producer: rtrb::Producer<MeterFrame>,
}
impl MeterProducer {
#[inline]
pub fn push(&mut self, frame: MeterFrame) {
let _ = self.producer.push(frame);
}
#[inline]
pub fn available_write(&self) -> usize {
self.producer.slots()
}
}
pub struct MeterConsumer {
consumer: rtrb::Consumer<MeterFrame>,
}
impl MeterConsumer {
pub fn read_latest(&mut self) -> Option<MeterFrame> {
let mut latest = None;
while let Ok(frame) = self.consumer.pop() {
latest = Some(frame);
}
latest
}
pub fn pop(&mut self) -> Option<MeterFrame> {
self.consumer.pop().ok()
}
pub fn available_read(&self) -> usize {
self.consumer.slots()
}
}
pub fn create_meter_channel(capacity: usize) -> (MeterProducer, MeterConsumer) {
let (producer, consumer) = rtrb::RingBuffer::new(capacity);
(MeterProducer { producer }, MeterConsumer { consumer })
}
#[cfg(test)]
mod tests {
use super::*;
fn empty_frame() -> MeterFrame {
MeterFrame {
peak_l: 0.0,
peak_r: 0.0,
rms_l: 0.0,
rms_r: 0.0,
timestamp: 0,
}
}
#[test]
fn meter_ring_push_pop() {
let (mut producer, mut consumer) = create_meter_channel(4);
let frame = MeterFrame {
peak_l: 0.5,
peak_r: 0.6,
rms_l: 0.3,
rms_r: 0.4,
timestamp: 1000,
};
producer.push(frame);
let read = consumer.pop().expect("should read frame");
assert_eq!(read.peak_l, 0.5);
assert_eq!(read.peak_r, 0.6);
assert_eq!(read.rms_l, 0.3);
assert_eq!(read.rms_r, 0.4);
assert_eq!(read.timestamp, 1000);
}
#[test]
fn meter_ring_overflow() {
let (mut producer, mut consumer) = create_meter_channel(2);
producer.push(MeterFrame {
peak_l: 1.0,
..empty_frame()
});
producer.push(MeterFrame {
peak_l: 2.0,
..empty_frame()
});
producer.push(MeterFrame {
peak_l: 3.0,
..empty_frame()
});
assert_eq!(consumer.pop().unwrap().peak_l, 1.0);
assert_eq!(consumer.pop().unwrap().peak_l, 2.0);
assert!(consumer.pop().is_none());
}
#[test]
fn read_latest_discards_old() {
let (mut producer, mut consumer) = create_meter_channel(8);
for i in 0..5 {
producer.push(MeterFrame {
peak_l: i as f32,
..empty_frame()
});
}
let latest = consumer.read_latest().expect("should have frame");
assert_eq!(latest.peak_l, 4.0);
assert!(consumer.pop().is_none());
}
#[test]
fn empty_buffer_returns_none() {
let (_, mut consumer) = create_meter_channel(4);
assert!(consumer.pop().is_none());
assert!(consumer.read_latest().is_none());
}
#[test]
fn available_counts() {
let (mut producer, mut consumer) = create_meter_channel(4);
assert_eq!(consumer.available_read(), 0);
producer.push(empty_frame());
producer.push(empty_frame());
assert_eq!(consumer.available_read(), 2);
consumer.pop();
assert_eq!(consumer.available_read(), 1);
}
}