diff --git a/j314.conf b/j314.conf index ec9465f..ac6480d 100644 --- a/j314.conf +++ b/j314.conf @@ -8,7 +8,7 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 1 -is_chan = 2 +is_chan = 0 [Right Tweeter] r_shunt = 1 @@ -20,7 +20,7 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 3 -is_chan = 4 +is_chan = 2 [Left Woofer 1] r_shunt = 1 @@ -32,7 +32,7 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 5 -is_chan = 6 +is_chan = 4 [Right Woofer 1] r_shunt = 1 @@ -44,7 +44,7 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 7 -is_chan = 8 +is_chan = 6 [Left Woofer 2] r_shunt = 1 @@ -56,7 +56,7 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 9 -is_chan = 10 +is_chan = 8 [Right Woofer 2] r_shunt = 1 @@ -68,4 +68,4 @@ tr_coil = 6 ramp_factor = 7 temp_limit = 100 vs_chan = 11 -is_chan = 12 +is_chan = 10 diff --git a/src/helpers.rs b/src/helpers.rs index ae00528..597a345 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -15,6 +15,18 @@ pub fn fail() { 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 { let ctldev: alsa::ctl::Ctl = match alsa::ctl::Ctl::new(card, false) { 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(); 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_access(alsa::pcm::Access::RWNonInterleaved).unwrap(); + params.set_access(alsa::pcm::Access::RWInterleaved).unwrap(); pcm.hw_params(¶ms).unwrap(); } diff --git a/src/main.rs b/src/main.rs index f63d3de..7483b28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ */ use std::io; use std::fs::read_to_string; +use std::{thread::sleep, time}; use configparser::ini::Ini; @@ -78,7 +79,7 @@ fn main() { loop { // 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 { i.run(&card, &buf); } diff --git a/src/types.rs b/src/types.rs index 8312967..bbffc92 100644 --- a/src/types.rs +++ b/src/types.rs @@ -172,8 +172,8 @@ impl SafetyMonitor for Speaker { } fn power_now(&mut self, vs: &[i16], is: &[i16]) -> f32 { - let v_avg: f32 = (vs.iter().sum::() as f32 / vs.len() as f32) * (14 / (2 ^ 15)) as f32; - let i_avg: f32 = (is.iter().sum::() as f32 / is.len() as f32) * (14 / (2 ^ 15)) as f32; + let v_avg: f32 = helpers::average(vs) * (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; } @@ -181,8 +181,8 @@ impl SafetyMonitor for Speaker { // 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]) { 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 isense = &buf[(128 * self.is_chan as usize - 1) .. (128 * self.is_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 .. (128 * (self.is_chan + 1) - 1) as usize]; // Estimate temperature of VC and magnet let temp0: f32 = 35f32; @@ -193,34 +193,30 @@ impl SafetyMonitor for Speaker { // Power through the voice coil (average of most recent 128 samples) 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; 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; 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 { println!("Voice coil for {} below temp limit, ramping back up.", self.name); // 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); } if temp_vc > (self.temp_limit - 15f32) { 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 - 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); } - 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)); } }