Implement catchup/skipping the model forward

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2023-10-12 17:18:31 +09:00
parent 7ab0fed6d3
commit fa4f763d05
2 changed files with 37 additions and 0 deletions

View file

@ -10,6 +10,7 @@ use std::collections::BTreeMap;
use std::fs::read_to_string; use std::fs::read_to_string;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::{Duration, Instant};
use std::{thread::sleep, time}; use std::{thread::sleep, time};
use clap::Parser; use clap::Parser;
@ -167,6 +168,8 @@ fn main() {
group.gain = 0.0; group.gain = 0.0;
} }
let mut last_update = Instant::now();
loop { loop {
// Block while we're reading into the buffer // Block while we're reading into the buffer
io.readi(&mut buf).unwrap(); io.readi(&mut buf).unwrap();
@ -184,6 +187,22 @@ fn main() {
panic!("Invalid sample rate"); panic!("Invalid sample rate");
} }
let now = Instant::now();
let dt = (now - last_update).as_secs_f64();
assert!(dt > 0f64);
let pt = globals.period as f64 / sample_rate as f64;
/* If we skipped at least 4 periods, run catchup for that minus one */
if dt > (4f64 * pt) {
let skip = dt - pt;
debug!("Skipping {:.2} seconds", skip);
for (_, group) in groups.iter_mut() {
group.speakers.iter_mut().for_each(|s| s.skip_model(skip));
}
}
last_update = now;
for (idx, group) in groups.iter_mut() { for (idx, group) in groups.iter_mut() {
let gain = group let gain = group
.speakers .speakers

View file

@ -354,6 +354,24 @@ impl Speaker {
s.gain s.gain
} }
pub fn skip_model(&mut self, time: f64) {
let s = &mut self.s;
let t_coil = s.t_coil - self.g.t_ambient as f64;
let t_magnet = s.t_magnet - self.g.t_ambient as f64;
let eta = 1f64 / (1f64 - (self.tau_coil / self.tau_magnet) as f64);
let a = (-time / self.tau_coil as f64).exp() * (t_coil - eta * t_magnet);
let b = (-time / self.tau_magnet as f64).exp() * t_magnet;
s.t_coil = self.g.t_ambient as f64 + a + b * eta;
s.t_magnet = self.g.t_ambient as f64 + b;
debug!(
"{}: SKIP: Coil {:.2} °C Magnet {:.2} °C ({:.2} seconds)",
self.name, s.t_coil, s.t_magnet, time
);
}
pub fn update(&mut self, ctl: &Ctl, gain: f32) { pub fn update(&mut self, ctl: &Ctl, gain: f32) {
self.alsa_iface.set_lvl(ctl, gain); self.alsa_iface.set_lvl(ctl, gain);
} }