From d8b84a2e63d64679bfa73c23cadbad754854b237 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sat, 16 Dec 2023 20:18:37 +0100 Subject: [PATCH 1/8] Remove needless check for capture_samplerate --- CHANGELOG.md | 4 ++++ src/audiodevice.rs | 3 ++- src/config.rs | 8 -------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7a418f..185b0d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.0.1 +Changes: +- Ignore campture_samplerate when resampling is disabled. + ## v2.0.0 New features: - Add dynamic range compressor. diff --git a/src/audiodevice.rs b/src/audiodevice.rs index d8346ce..c3a2756 100644 --- a/src/audiodevice.rs +++ b/src/audiodevice.rs @@ -505,7 +505,8 @@ pub fn new_resampler( /// Create a capture device. pub fn new_capture_device(conf: config::Devices) -> Box { - //let resampler = new_resampler(&conf); + // Use `capture_samplerate` from config if given, and resampling is enabled. + // Else, use `samplerate`. let capture_samplerate = if conf.capture_samplerate.is_some() && conf.resampler.is_some() { conf.capture_samplerate.unwrap() } else { diff --git a/src/config.rs b/src/config.rs index f838621..9e117f6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1683,14 +1683,6 @@ pub fn validate_config(conf: &mut Configuration, filename: Option<&str>) -> Res< return Err(ConfigError::new("silence_timeout cannot be negative").into()); } } - if let Some(rate) = conf.devices.capture_samplerate { - if rate != conf.devices.samplerate && conf.devices.resampler.is_none() { - return Err(ConfigError::new( - "capture_samplerate must match samplerate when resampling is disabled", - ) - .into()); - } - } if conf.devices.ramp_time() < 0.0 { return Err(ConfigError::new("Volume ramp time cannot be negative").into()); } From 6eac88f402740eaf35fc145f91a7e25db00f7b53 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sun, 17 Dec 2023 12:02:11 +0100 Subject: [PATCH 2/8] Warn when capture_samplerate is different than samplerate if resampling is disabled --- CHANGELOG.md | 2 +- src/audiodevice.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 185b0d6..2e17f5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## v2.0.1 Changes: -- Ignore campture_samplerate when resampling is disabled. +- Ignore capture_samplerate when resampling is disabled. ## v2.0.0 New features: diff --git a/src/audiodevice.rs b/src/audiodevice.rs index c3a2756..e94bd70 100644 --- a/src/audiodevice.rs +++ b/src/audiodevice.rs @@ -512,6 +512,11 @@ pub fn new_capture_device(conf: config::Devices) -> Box { } else { conf.samplerate }; + if let Some(cr) = conf.capture_samplerate { + if cr != conf.samplerate && conf.resampler.is_none() { + warn!("Resampling is disabled and capture_samplerate is different than samplerate, ignoring capture_samplerate."); + } + } let diff_rates = capture_samplerate != conf.samplerate; // Check for non-optimal resampling settings if !diff_rates && conf.resampler.is_some() && !conf.rate_adjust() { From aa0326d0fd5ec7b4a59199824483c8be3f710a56 Mon Sep 17 00:00:00 2001 From: Henrik Enquist Date: Tue, 19 Dec 2023 21:16:12 +0100 Subject: [PATCH 3/8] Make sure the Alsa device buffer size is at least 4 periods --- src/alsadevice_buffermanager.rs | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/alsadevice_buffermanager.rs b/src/alsadevice_buffermanager.rs index 503d34b..d1db853 100644 --- a/src/alsadevice_buffermanager.rs +++ b/src/alsadevice_buffermanager.rs @@ -15,30 +15,44 @@ pub trait DeviceBufferManager { fn apply_start_threshold(&mut self, swp: &SwParams) -> Res<()>; - // Calculate a power-of-two buffer size that is large enough to accommodate any changes due to resampling. - fn calculate_buffer_size(&self) -> Frames { + // Calculate a power-of-two buffer size that is large enough to accommodate any changes due to resampling, + // and at least 4 times the minimum period size to avoid random broken pipes. + fn calculate_buffer_size(&self, min_period: Frames) -> Frames { let data = self.data(); - 2.0f32.powi( - (1.2 * data.chunksize as f32 / data.resampling_ratio) - .log2() - .ceil() as i32, - ) as Frames + let mut frames_needed = 1.2 * data.chunksize as f32 / data.resampling_ratio; + if frames_needed < 4.0 * min_period as f32 { + frames_needed = 4.0 * min_period as f32; + debug!( + "Minimum period is {} frames, buffer size is minimum {} frames", + min_period, frames_needed + ); + } + 2.0f32.powi(frames_needed.log2().ceil() as i32) as Frames } - // Calculate an alternative buffer size that is 3 multiplied by a power-of-two. - // This is for some devices that cannot wotk with the default setting, + // Calculate an alternative buffer size that is 3 multiplied by a power-of-two, + // and at least 4 times the minimum period size to avoid random broken pipes. + // This is for some devices that cannot work with the default setting, // and when set_buffer_size_near() does not return a working alternative near the requested one. // Caused by driver bugs? - fn calculate_buffer_size_alt(&self) -> Frames { + fn calculate_buffer_size_alt(&self, min_period: Frames) -> Frames { let data = self.data(); - let frames_needed = 1.2 * data.chunksize as f32 / data.resampling_ratio; + let mut frames_needed = 1.2 * data.chunksize as f32 / data.resampling_ratio; + if frames_needed < 4.0 * min_period as f32 { + frames_needed = 4.0 * min_period as f32; + debug!( + "Minimum period is {} frames, alternate buffer size is minimum {} frames", + min_period, frames_needed + ); + } 3 * 2.0f32.powi((frames_needed / 3.0).log2().ceil() as i32) as Frames } // Calculate a buffer size and apply it to a hwp container. Only for use when opening a device. fn apply_buffer_size(&mut self, hwp: &HwParams) -> Res<()> { - let buffer_frames = self.calculate_buffer_size(); - let alt_buffer_frames = self.calculate_buffer_size_alt(); + let min_period = hwp.get_period_size_min().unwrap_or(0); + let buffer_frames = self.calculate_buffer_size(min_period); + let alt_buffer_frames = self.calculate_buffer_size_alt(min_period); let data = self.data_mut(); debug!("Setting buffer size to {} frames", buffer_frames); match hwp.set_buffer_size_near(buffer_frames) { @@ -53,7 +67,6 @@ pub trait DeviceBufferManager { data.bufsize = hwp.set_buffer_size_near(alt_buffer_frames)?; } } - //data.bufsize = hwp.set_buffer_size_near(buffer_frames)?; debug!("Device is using a buffer size of {} frames", data.bufsize); Ok(()) } From 442ca856359f3bb763524e6e375fa19988add437 Mon Sep 17 00:00:00 2001 From: Henrik Enquist Date: Sat, 30 Dec 2023 21:48:12 +0100 Subject: [PATCH 4/8] Increase the Alsa device buffers --- src/alsadevice_buffermanager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alsadevice_buffermanager.rs b/src/alsadevice_buffermanager.rs index d1db853..33258e2 100644 --- a/src/alsadevice_buffermanager.rs +++ b/src/alsadevice_buffermanager.rs @@ -19,7 +19,7 @@ pub trait DeviceBufferManager { // and at least 4 times the minimum period size to avoid random broken pipes. fn calculate_buffer_size(&self, min_period: Frames) -> Frames { let data = self.data(); - let mut frames_needed = 1.2 * data.chunksize as f32 / data.resampling_ratio; + let mut frames_needed = 3.0 * data.chunksize as f32 / data.resampling_ratio; if frames_needed < 4.0 * min_period as f32 { frames_needed = 4.0 * min_period as f32; debug!( @@ -37,7 +37,7 @@ pub trait DeviceBufferManager { // Caused by driver bugs? fn calculate_buffer_size_alt(&self, min_period: Frames) -> Frames { let data = self.data(); - let mut frames_needed = 1.2 * data.chunksize as f32 / data.resampling_ratio; + let mut frames_needed = 3.0 * data.chunksize as f32 / data.resampling_ratio; if frames_needed < 4.0 * min_period as f32 { frames_needed = 4.0 * min_period as f32; debug!( From a54a634f8c76a66edd2b08e7f2856fad2e1f2958 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sat, 30 Dec 2023 22:23:57 +0100 Subject: [PATCH 5/8] Use .front() instead og .get(0) --- src/countertimer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/countertimer.rs b/src/countertimer.rs index 676ef27..175e1b5 100644 --- a/src/countertimer.rs +++ b/src/countertimer.rs @@ -351,11 +351,11 @@ impl ValueHistory { } pub fn last(&self) -> Option { - self.buffer.get(0).cloned() + self.buffer.front().cloned() } pub fn last_sqrt(&self) -> Option { - let mut result = self.buffer.get(0).cloned(); + let mut result = self.buffer.front().cloned(); if let Some(ref mut record) = result { record.values.iter_mut().for_each(|val| *val = val.sqrt()) }; From 28759b9ebcd27e6f80f24185ade458b10ad3d244 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sat, 30 Dec 2023 22:59:40 +0100 Subject: [PATCH 6/8] Update websocket library --- Cargo.toml | 2 +- src/socketserver.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 582a232..f208721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ lazy_static = "1.4.0" log = "0.4.14" flexi_logger = { version = "0.27.2", features = ["async", "colors"] } chrono = "0.4" -tungstenite = { version = "0.16.0", optional = true, default-features = false } +tungstenite = { version = "0.21.0", optional = true } native-tls = { version = "0.2.7", optional = true } libpulse-binding = { version = "2.0", optional = true } libpulse-simple-binding = { version = "2.0", optional = true } diff --git a/src/socketserver.rs b/src/socketserver.rs index c54c5f5..2a08e4f 100644 --- a/src/socketserver.rs +++ b/src/socketserver.rs @@ -480,7 +480,7 @@ macro_rules! make_handler { ) { match websocket_res { Ok(mut websocket) => loop { - let msg_res = websocket.read_message(); + let msg_res = websocket.read(); match msg_res { Ok(msg) => { trace!("received: {:?}", msg); @@ -493,7 +493,7 @@ macro_rules! make_handler { }), }; if let Some(rep) = reply { - let write_result = websocket.write_message(Message::text( + let write_result = websocket.send(Message::text( serde_json::to_string(&rep).unwrap(), )); if let Err(err) = write_result { From bbc973a69bc672942300d561f0d0779c05326627 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sat, 30 Dec 2023 23:10:21 +0100 Subject: [PATCH 7/8] Format --- src/socketserver.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/socketserver.rs b/src/socketserver.rs index 2a08e4f..145661d 100644 --- a/src/socketserver.rs +++ b/src/socketserver.rs @@ -493,9 +493,8 @@ macro_rules! make_handler { }), }; if let Some(rep) = reply { - let write_result = websocket.send(Message::text( - serde_json::to_string(&rep).unwrap(), - )); + let write_result = websocket + .send(Message::text(serde_json::to_string(&rep).unwrap())); if let Err(err) = write_result { warn!("Failed to write: {}", err); break; From df9b0b647bb072f5d4dad0fd56aa5059483bded7 Mon Sep 17 00:00:00 2001 From: Henrik Date: Wed, 3 Jan 2024 10:35:15 +0100 Subject: [PATCH 8/8] Update changelog, bump version to 2.0.1 --- CHANGELOG.md | 3 ++- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e17f5c..bb557a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## v2.0.1 -Changes: +Bugfixes: - Ignore capture_samplerate when resampling is disabled. +- Increase Alsa device buffer sizes to avoid errors. ## v2.0.0 New features: diff --git a/Cargo.toml b/Cargo.toml index 582a232..b094bdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "camilladsp" -version = "2.0.0" +version = "2.0.1" authors = ["Henrik Enquist "] edition = "2021" description = "A flexible tool for processing audio"