Skip to content

Commit

Permalink
introduce delay
Browse files Browse the repository at this point in the history
  • Loading branch information
youxkei committed Jan 29, 2023
1 parent 5809617 commit 66f32c3
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Install dependencies:

```
# ubuntu
sudo apt install libgl-dev libxcursor-dev libx11-xcb-dev libxcb-icccm4-dev libxcb-dri2-0-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev
sudo apt install pkg-config libgl-dev libxcursor-dev libx11-xcb-dev libxcb-icccm4-dev libxcb-dri2-0-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev
```

Build:
Expand Down
15 changes: 12 additions & 3 deletions loudness_limiter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ struct LoudnessLimiter {

power_envelope: jimtel::envelope::Envelope,
loudness_power_envelope: jimtel::envelope::Envelope,

delay_buffer: jimtel::delay_buffer::DelayBuffer,
}

impl Plugin for LoudnessLimiter {
Expand All @@ -32,6 +34,8 @@ impl Plugin for LoudnessLimiter {

power_envelope: jimtel::envelope::Envelope::new(sample_rate_hz),
loudness_power_envelope: jimtel::envelope::Envelope::new(sample_rate_hz),

delay_buffer: jimtel::delay_buffer::DelayBuffer::new(0),
}
}

Expand Down Expand Up @@ -72,6 +76,8 @@ impl Plugin for LoudnessLimiter {

let silence_beyond_power_limit = self.params.silence_beyond_power.get();

let delay_samples = (self.params.delay.get() / 1000.0 * self.sample_rate_hz) as usize;

self.loudness.set_samples_num_per_windows(
samples_num_per_loudness_window,
samples_num_per_power_window,
Expand All @@ -81,6 +87,8 @@ impl Plugin for LoudnessLimiter {
self.loudness_power_envelope
.set_coefficients(loudness_attack_ms, loudness_release_ms);

self.delay_buffer.set_delay(delay_samples);

for (in_left, in_right, out_left, out_right) in itertools::izip!(
in_left_buffer.get(0),
in_right_buffer.get(0),
Expand All @@ -107,8 +115,9 @@ impl Plugin for LoudnessLimiter {
let gain =
input_gain * output_gain * (loudness_coefficient * power_limit_coefficient).sqrt();

*out_left = in_left * gain;
*out_right = in_right * gain;
let (delayed_in_left, delayed_in_right) = self.delay_buffer.add(*in_left, *in_right);
*out_left = delayed_in_left * gain;
*out_right = delayed_in_right * gain;
}
}

Expand All @@ -120,7 +129,7 @@ impl Plugin for LoudnessLimiter {
Some(Box::new(Editor::new(
"Jimtel Loudness Limiter".to_string(),
1280.0,
480.0,
640.0,
self.params.clone(),
)))
}
Expand Down
6 changes: 5 additions & 1 deletion loudness_limiter/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct LoudnessLimiterParams {
#[param(kind = "LKFS", min = "-80", max = "0")]
pub loudness: AtomicFloat,

#[param(kind = "ms", min = "100", max = "10000")]
#[param(kind = "ms", min = "1", max = "1000")]
pub loudness_window: AtomicFloat,

#[param(kind = "ms", min = "0", max = "1000")]
Expand All @@ -33,6 +33,9 @@ pub struct LoudnessLimiterParams {

#[param(kind = "checkbox", min = "0", max = "1")]
pub silence_beyond_power: AtomicFloat,

#[param(kind = "ms", min = "0", max = "1000")]
pub delay: AtomicFloat,
}

impl LoudnessLimiterParams {
Expand All @@ -51,6 +54,7 @@ impl LoudnessLimiterParams {
power_window: AtomicFloat::new(6.0),
power_release: AtomicFloat::new(10000.0),
silence_beyond_power: AtomicFloat::new(0.0),
delay: AtomicFloat::new(0.0),
}
}
}
62 changes: 62 additions & 0 deletions src/delay_buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
pub struct DelayBuffer {
delay: usize,
buffer: Vec<(f32, f32)>,
current_index: usize,
}

impl DelayBuffer {
pub fn new(delay: usize) -> Self {
Self {
delay,
buffer: vec![(0.0, 0.0); delay + 1],
current_index: 0,
}
}

#[inline(always)]
pub fn add(&mut self, current_left_value: f32, current_right_value: f32) -> (f32, f32) {
self.buffer[self.current_index] = (current_left_value, current_right_value);

self.current_index += 1;
if self.current_index >= self.buffer.len() {
self.current_index = 0;
}

self.buffer[self.current_index]
}

#[inline(always)]
pub fn set_delay(&mut self, delay: usize) {
if delay != self.delay {
self.current_index = 0;
self.delay = delay;
self.buffer = vec![(0.0, 0.0); delay + 1];
}
}
}

#[cfg(test)]
mod tests {
use super::DelayBuffer;

#[test]
fn no_delay() {
let mut buffer = DelayBuffer::new(0);

assert_eq!(buffer.add(1.0, 2.0), (1.0, 2.0));
assert_eq!(buffer.add(3.0, 4.0), (3.0, 4.0));
}

#[test]
fn some_delay() {
let mut buffer = DelayBuffer::new(3);

assert_eq!(buffer.add(1.0, 2.0), (0.0, 0.0));
assert_eq!(buffer.add(3.0, 4.0), (0.0, 0.0));
assert_eq!(buffer.add(5.0, 6.0), (0.0, 0.0));
assert_eq!(buffer.add(7.0, 8.0), (1.0, 2.0));
assert_eq!(buffer.add(8.0, 9.0), (3.0, 4.0));
assert_eq!(buffer.add(10.0, 11.0), (5.0, 6.0));
assert_eq!(buffer.add(12.0, 13.0), (7.0, 8.0));
}
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod delay_buffer;
pub mod editor;
pub mod envelope;
pub mod loudness;
pub mod params;
pub mod window_handle;
pub mod sum_buffer;
pub mod window_handle;

0 comments on commit 66f32c3

Please sign in to comment.