some fixes

Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
This commit is contained in:
James Calligeros 2023-02-14 22:02:30 +10:00
parent a7ca735707
commit bc49ea2887
No known key found for this signature in database
GPG key ID: D43632D151F77960
4 changed files with 31 additions and 22 deletions

View file

@ -8,7 +8,7 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 1 vs_chan = 1
is_chan = 2 is_chan = 0
[Right Tweeter] [Right Tweeter]
r_shunt = 1 r_shunt = 1
@ -20,7 +20,7 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 3 vs_chan = 3
is_chan = 4 is_chan = 2
[Left Woofer 1] [Left Woofer 1]
r_shunt = 1 r_shunt = 1
@ -32,7 +32,7 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 5 vs_chan = 5
is_chan = 6 is_chan = 4
[Right Woofer 1] [Right Woofer 1]
r_shunt = 1 r_shunt = 1
@ -44,7 +44,7 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 7 vs_chan = 7
is_chan = 8 is_chan = 6
[Left Woofer 2] [Left Woofer 2]
r_shunt = 1 r_shunt = 1
@ -56,7 +56,7 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 9 vs_chan = 9
is_chan = 10 is_chan = 8
[Right Woofer 2] [Right Woofer 2]
r_shunt = 1 r_shunt = 1
@ -68,4 +68,4 @@ tr_coil = 6
ramp_factor = 7 ramp_factor = 7
temp_limit = 100 temp_limit = 100
vs_chan = 11 vs_chan = 11
is_chan = 12 is_chan = 10

View file

@ -15,6 +15,18 @@ pub fn fail() {
std::process::exit(1); std::process::exit(1);
} }
pub fn average(a: &[i16]) -> f32 {
let mut sum: f32 = 0.0;
let mut avg: f32 = 0.0;
for i in a {
sum = sum + *i as f32;
}
avg = sum / (a.len() as f32);
return avg;
}
pub fn open_card(card: &str) -> alsa::ctl::Ctl { pub fn open_card(card: &str) -> alsa::ctl::Ctl {
let ctldev: alsa::ctl::Ctl = match alsa::ctl::Ctl::new(card, false) { let ctldev: alsa::ctl::Ctl = match alsa::ctl::Ctl::new(card, false) {
Ok(ctldev) => ctldev, Ok(ctldev) => ctldev,
@ -35,9 +47,9 @@ pub fn open_pcm(dev: &str, chans: &u32) -> alsa::pcm::PCM {
let params = alsa::pcm::HwParams::any(&pcm).unwrap(); let params = alsa::pcm::HwParams::any(&pcm).unwrap();
params.set_channels(*chans).unwrap(); params.set_channels(*chans).unwrap();
params.set_rate(44100, alsa::ValueOr::Nearest).unwrap(); params.set_rate(48000, alsa::ValueOr::Nearest).unwrap();
params.set_format(alsa::pcm::Format::s16()).unwrap(); params.set_format(alsa::pcm::Format::s16()).unwrap();
params.set_access(alsa::pcm::Access::RWNonInterleaved).unwrap(); params.set_access(alsa::pcm::Access::RWInterleaved).unwrap();
pcm.hw_params(&params).unwrap(); pcm.hw_params(&params).unwrap();
} }

View file

@ -8,6 +8,7 @@
*/ */
use std::io; use std::io;
use std::fs::read_to_string; use std::fs::read_to_string;
use std::{thread::sleep, time};
use configparser::ini::Ini; use configparser::ini::Ini;
@ -78,7 +79,7 @@ fn main() {
loop { loop {
// Block while we're reading into the buffer // Block while we're reading into the buffer
assert_eq!(io.readi(&mut buf).unwrap(), buf.len()); io.readi(&mut buf).unwrap();
for i in &mut speakers { for i in &mut speakers {
i.run(&card, &buf); i.run(&card, &buf);
} }

View file

@ -172,8 +172,8 @@ impl SafetyMonitor for Speaker {
} }
fn power_now(&mut self, vs: &[i16], is: &[i16]) -> f32 { fn power_now(&mut self, vs: &[i16], is: &[i16]) -> f32 {
let v_avg: f32 = (vs.iter().sum::<i16>() as f32 / vs.len() as f32) * (14 / (2 ^ 15)) as f32; let v_avg: f32 = helpers::average(vs) * (14 / (2 ^ 15)) as f32;
let i_avg: f32 = (is.iter().sum::<i16>() as f32 / is.len() as f32) * (14 / (2 ^ 15)) as f32; let i_avg: f32 = helpers::average(is) * (3.75 / (2 ^ 15) as f32) as f32;
return v_avg * i_avg; return v_avg * i_avg;
} }
@ -181,8 +181,8 @@ impl SafetyMonitor for Speaker {
// I'm not sure on the maths here for determining when to start dropping the volume. // I'm not sure on the maths here for determining when to start dropping the volume.
fn run(&mut self, card: &Ctl, buf: &[i16; 128 * 6 * 2]) { fn run(&mut self, card: &Ctl, buf: &[i16; 128 * 6 * 2]) {
let lvl: f32 = self.alsa_iface.get_lvl(card); let lvl: f32 = self.alsa_iface.get_lvl(card);
let vsense = &buf[(128 * self.vs_chan as usize - 1) .. (128 * self.vs_chan as usize - 1) + 128]; let vsense = &buf[(128 * self.vs_chan) as usize .. (128 * (self.vs_chan + 1) - 1) as usize];
let isense = &buf[(128 * self.is_chan as usize - 1) .. (128 * self.is_chan as usize - 1) + 128]; let isense = &buf[(128 * self.is_chan) as usize .. (128 * (self.is_chan + 1) - 1) as usize];
// Estimate temperature of VC and magnet // Estimate temperature of VC and magnet
let temp0: f32 = 35f32; let temp0: f32 = 35f32;
@ -193,34 +193,30 @@ impl SafetyMonitor for Speaker {
// Power through the voice coil (average of most recent 128 samples) // Power through the voice coil (average of most recent 128 samples)
let pwr: f32 = self.power_now(&vsense, &isense); let pwr: f32 = self.power_now(&vsense, &isense);
println!("Power now is {:.2} mW", pwr);
let vc_target: f32 = temp_magnet + pwr * self.tau_coil; let vc_target: f32 = temp_magnet + pwr * self.tau_coil;
temp_vc = vc_target * alpha_vc + temp_vc * (1.0 - alpha_vc); temp_vc = vc_target * alpha_vc + temp_vc * (1.0 - alpha_vc);
println!("Current voice coil temp: {:.2}*C", temp_vc); println!("Current voice coil temp: {:.2} *C", temp_vc);
let magnet_target: f32 = temp0 + pwr * self.tau_magnet; let magnet_target: f32 = temp0 + pwr * self.tau_magnet;
temp_magnet = magnet_target * alpha_magnet + temp_magnet * (1.0 - alpha_magnet); temp_magnet = magnet_target * alpha_magnet + temp_magnet * (1.0 - alpha_magnet);
println!("Current magnet temp: {:.2}*C", temp_magnet); println!("Current magnet temp: {:.2} *C", temp_magnet);
if temp_vc < self.temp_limit { if temp_vc < self.temp_limit {
println!("Voice coil for {} below temp limit, ramping back up.", self.name); println!("Voice coil for {} below temp limit, ramping back up.", self.name);
// For every degree below temp_limit, raise level by 0.5 dB // For every degree below temp_limit, raise level by 0.5 dB
let new_lvl: f32 = lvl + ((self.temp_limit - temp_vc) as f32 * 0.5); let new_lvl: f32 = lvl + ((self.temp_limit - temp_vc) * 0.5);
self.alsa_iface.set_lvl(card, new_lvl); self.alsa_iface.set_lvl(card, new_lvl);
} }
if temp_vc > (self.temp_limit - 15f32) { if temp_vc > (self.temp_limit - 15f32) {
println!("Voice coil at {}*C on {}! Dropping volume!", temp_vc, self.name); println!("Voice coil at {}*C on {}! Dropping volume!", temp_vc, self.name);
// For every degree above temp_limit, drop the level by 1.5 dB // For every degree above temp_limit, drop the level by 1.5 dB
let new_lvl: f32 = lvl - ((temp_vc - self.temp_limit) as f32 * 1.5); let new_lvl: f32 = lvl - ((temp_vc - (self.temp_limit - 15f32)) * 1.5);
self.alsa_iface.set_lvl(card, new_lvl); self.alsa_iface.set_lvl(card, new_lvl);
} }
println!("Volume on {} is currently {} dB. Setting to -18 dB.", self.name, lvl);
let new_lvl: f32 = -18.0;
self.alsa_iface.set_lvl(card, new_lvl);
println!("Volume on {} is now {} dB", self.name, self.alsa_iface.get_lvl(card)); println!("Volume on {} is now {} dB", self.name, self.alsa_iface.get_lvl(card));
} }
} }