From a9202d83036dd989bac663730d565ed2877f8363 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Tue, 23 Feb 2021 22:32:34 +0100 Subject: [PATCH] Limit main loop and packet send rates LED data packets are now sent with at most 60 updates per second. The main loop tries to uniformly distribute calculation updates over time. --- src/main.rs | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1e1ccee..6249f5c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,9 @@ use crate::udpproto::UdpProto; use std::rc::Rc; use std::cell::RefCell; +use std::thread::sleep; +use std::time::{Duration, Instant}; + fn main() { let mut stdin = std::io::stdin(); @@ -41,7 +44,7 @@ fn main() println!("Loading user script..."); - let mut script = match UserScript::new(sigproc.clone(), "test.lua") { + let mut script = match UserScript::new(sigproc.clone(), "particles.lua") { Ok(script) => script, Err(e) => { println!("=== Lua Error ===\n{}\n====> Terminating.", e); @@ -61,6 +64,14 @@ fn main() println!("Done! Starting main loop…"); + // Timing setup + + let block_period = Duration::from_nanos((0.95 * (config::SAMPLES_PER_UPDATE as f32) * 1e9 / config::SAMP_RATE) as u64); + let send_period = Duration::from_nanos(1000000000 / 60); + + let mut next_block_instant = Instant::now() + block_period; + let mut next_send_instant = Instant::now() + send_period; + // array for samples directly read from stream let mut samples: VecDeque = VecDeque::with_capacity(config::BLOCK_LEN); @@ -111,16 +122,27 @@ fn main() // FIXME: only send with 60 FPS! - for i in 0..script.colorlists[0].len() { - udpproto.set_color((i / config::NUM_LEDS_PER_STRIP) as u8, - (i % config::NUM_LEDS_PER_STRIP) as u8, - (script.colorlists[0][i] * 255.0) as u8, - (script.colorlists[1][i] * 255.0) as u8, - (script.colorlists[2][i] * 255.0) as u8, - (script.colorlists[3][i] * 255.0) as u8).unwrap(); + if Instant::now() > next_send_instant { + for i in 0..script.colorlists[0].len() { + udpproto.set_color((i / config::NUM_LEDS_PER_STRIP) as u8, + (i % config::NUM_LEDS_PER_STRIP) as u8, + (script.colorlists[0][i] * 255.0) as u8, + (script.colorlists[1][i] * 255.0) as u8, + (script.colorlists[2][i] * 255.0) as u8, + (script.colorlists[3][i] * 255.0) as u8).unwrap(); + } + + udpproto.commit().unwrap(); + + next_send_instant += send_period; } - udpproto.commit().unwrap(); + let now = Instant::now(); + if now < next_block_instant { + sleep(next_block_instant - now); + } + + next_block_instant = Instant::now() + block_period; } }