1
0
Fork 0

Use AtomicRef instead of Mutexes for block smooth

This commit is contained in:
Robbert van der Helm 2022-03-01 19:52:56 +01:00
parent 3bd83ca55a
commit 3e8b2b3759
3 changed files with 15 additions and 13 deletions

1
Cargo.lock generated
View file

@ -534,6 +534,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"assert_no_alloc", "assert_no_alloc",
"atomic_float", "atomic_float",
"atomic_refcell",
"cfg-if", "cfg-if",
"clap-sys", "clap-sys",
"crossbeam", "crossbeam",

View file

@ -32,6 +32,7 @@ assert_process_allocs = ["assert_no_alloc"]
nih_plug_derive = { path = "nih_plug_derive" } nih_plug_derive = { path = "nih_plug_derive" }
atomic_float = "0.1" atomic_float = "0.1"
atomic_refcell = "0.1"
cfg-if = "1.0" cfg-if = "1.0"
# For CLAP 0.18 # For CLAP 0.18
clap-sys = { git = "https://github.com/glowcoil/clap-sys", rev = "3ef7048e1d3b426a7c6b02b5d3ae18f14874d4e5" } clap-sys = { git = "https://github.com/glowcoil/clap-sys", rev = "3ef7048e1d3b426a7c6b02b5d3ae18f14874d4e5" }

View file

@ -1,5 +1,5 @@
use atomic_float::AtomicF32; use atomic_float::AtomicF32;
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::atomic::{AtomicI32, Ordering};
use crate::buffer::Block; use crate::buffer::Block;
@ -43,7 +43,7 @@ pub struct Smoother<T> {
/// A dense buffer containing smoothed values for an entire block of audio. Useful when using /// A dense buffer containing smoothed values for an entire block of audio. Useful when using
/// [crate::Buffer::iter_blocks()] to process small blocks of audio multiple times. /// [crate::Buffer::iter_blocks()] to process small blocks of audio multiple times.
block_values: Mutex<Vec<T>>, block_values: AtomicRefCell<Vec<T>>,
} }
impl<T: Default> Default for Smoother<T> { impl<T: Default> Default for Smoother<T> {
@ -55,7 +55,7 @@ impl<T: Default> Default for Smoother<T> {
current: AtomicF32::new(0.0), current: AtomicF32::new(0.0),
target: Default::default(), target: Default::default(),
block_values: Mutex::new(Vec::new()), block_values: AtomicRefCell::new(Vec::new()),
} }
} }
} }
@ -85,7 +85,7 @@ impl<T: Default> Smoother<T> {
/// [crate::Buffer::iter_blocks()]. /// [crate::Buffer::iter_blocks()].
pub fn initialize_block_smoother(&mut self, max_block_size: usize) { pub fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.block_values self.block_values
.lock() .borrow_mut()
.resize_with(max_block_size, || T::default()); .resize_with(max_block_size, || T::default());
} }
} }
@ -142,8 +142,8 @@ impl Smoother<f32> {
/// ///
/// Returns a `None` value if the block length exceed's the allocated capacity. /// Returns a `None` value if the block length exceed's the allocated capacity.
#[inline] #[inline]
pub fn next_block(&self, block: &Block) -> Option<MappedMutexGuard<[f32]>> { pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[f32]>> {
let mut block_values = self.block_values.lock(); let mut block_values = self.block_values.borrow_mut();
if block_values.len() < block.len() { if block_values.len() < block.len() {
return None; return None;
} }
@ -154,7 +154,7 @@ impl Smoother<f32> {
// In that case we wouldn't need to do anything ehre. // In that case we wouldn't need to do anything ehre.
(&mut block_values[..block.len()]).fill_with(|| self.next()); (&mut block_values[..block.len()]).fill_with(|| self.next());
Some(MutexGuard::map(block_values, |values| { Some(AtomicRefMut::map(block_values, |values| {
&mut values[..block.len()] &mut values[..block.len()]
})) }))
} }
@ -239,16 +239,16 @@ impl Smoother<i32> {
/// ///
/// Returns a `None` value if the block length exceed's the allocated capacity. /// Returns a `None` value if the block length exceed's the allocated capacity.
#[inline] #[inline]
pub fn next_block(&self, block_len: usize) -> Option<MappedMutexGuard<[i32]>> { pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[i32]>> {
let mut block_values = self.block_values.lock(); let mut block_values = self.block_values.borrow_mut();
if block_values.len() < block_len { if block_values.len() < block.len() {
return None; return None;
} }
(&mut block_values[..block_len]).fill_with(|| self.next()); (&mut block_values[..block.len()]).fill_with(|| self.next());
Some(MutexGuard::map(block_values, |values| { Some(AtomicRefMut::map(block_values, |values| {
&mut values[..block_len] &mut values[..block.len()]
})) }))
} }