From 603e13efa8a01d75b4a35896f0f94ab94507ade0 Mon Sep 17 00:00:00 2001 From: Bart Brouns Date: Sat, 2 Nov 2024 13:25:29 +0100 Subject: [PATCH] try again, buf_sizes --- src/delay_tap.rs | 6 +-- src/lib.rs | 123 +++++++++++++++++++++-------------------------- 2 files changed, 57 insertions(+), 72 deletions(-) diff --git a/src/delay_tap.rs b/src/delay_tap.rs index c3a63ef..bc50919 100644 --- a/src/delay_tap.rs +++ b/src/delay_tap.rs @@ -1,4 +1,4 @@ -use crate::DSP_BLOCK_SIZE; +use crate::MAX_BLOCK_SIZE; use nih_plug::prelude::*; #[derive(Debug, Clone)] @@ -32,6 +32,6 @@ pub struct DelayTap { pub tap_index: usize, /// The delayed audio of this tap. /// Used to apply the envelopes and filters, and other DSP to. - pub delayed_audio_l: [f32; DSP_BLOCK_SIZE], - pub delayed_audio_r: [f32; DSP_BLOCK_SIZE], + pub delayed_audio_l: Vec, + pub delayed_audio_r: Vec, } diff --git a/src/lib.rs b/src/lib.rs index 5b9f8ab..9575978 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,8 +36,9 @@ const TOTAL_DELAY_SAMPLES: usize = TOTAL_DELAY_SECONDS * MAX_SAMPLE_RATE; const VELOCITY_LOW_NAME_PREFIX: &str = "low velocity"; const VELOCITY_HIGH_NAME_PREFIX: &str = "high velocity"; // this seems to be the number JUCE is using -const MAX_BLOCK_SIZE: usize = 32768; -const DSP_BLOCK_SIZE: usize = 1024; +// const MAX_BLOCK_SIZE: usize = 32768; +const MAX_BLOCK_SIZE: usize = 2048; +const DSP_BLOCK_SIZE: usize = 512; const PEAK_METER_DECAY_MS: f64 = 150.0; const MAX_LEARNED_NOTES: usize = 8; // abuse the difference in range between u8 and midi notes for special meaning @@ -71,7 +72,7 @@ struct Del2 { // delay write buffer delay_buffer: [BMRingBuf; 2], mute_in_delay_buffer: BMRingBuf, - mute_in_delayed: [[bool; DSP_BLOCK_SIZE]; NUM_TAPS], + mute_in_delayed: [[bool; MAX_BLOCK_SIZE]; NUM_TAPS], delay_data: SharedDelayData, delay_data_input: SharedDelayDataInput, @@ -461,7 +462,7 @@ impl Default for Del2 { BMRingBuf::::from_len(TOTAL_DELAY_SAMPLES), ], mute_in_delay_buffer: BMRingBuf::::from_len(TOTAL_DELAY_SAMPLES), - mute_in_delayed: [[false; DSP_BLOCK_SIZE]; NUM_TAPS], + mute_in_delayed: [[false; MAX_BLOCK_SIZE]; NUM_TAPS], delay_data: initial_delay_data, delay_data_input, @@ -599,7 +600,7 @@ impl Plugin for Del2 { for i in 0..MAX_LEARNED_NOTES { self.learned_notes.store(i, NO_LEARNED_NOTE); } - + self.initialize_delay_taps(); true } @@ -692,6 +693,7 @@ impl Plugin for Del2 { } let delay_tap = self.start_delay_tap(context, timing, channel, note); + println!("tap_index: {}", tap_index); delay_tap.velocity = velocity; delay_tap.amp_envelope = amp_envelope; delay_tap.tap_index = tap_index; @@ -840,7 +842,7 @@ impl Plugin for Del2 { } // write the audio buffer and mute in state into the delay - self.write_into_mute_in_delay(block_end - block_start); + // self.write_into_mute_in_delay(block_end - block_start); self.prepare_for_delay(block_end - block_start); @@ -1018,6 +1020,25 @@ impl Plugin for Del2 { } impl Del2 { + fn initialize_delay_taps(&mut self) { + self.delay_taps = array_init(|_| { + Some(DelayTap { + delay_tap_id: 0, + internal_delay_tap_id: 0, + channel: 0, + note: 0, + velocity: 1.0, + releasing: false, + amp_envelope: Smoother::none(), + delay_tap_gain: None, + is_muted: false, + tap_index: NUM_TAPS, + delayed_audio_l: vec![0.0; MAX_BLOCK_SIZE], // Pre-allocate + delayed_audio_r: vec![0.0; MAX_BLOCK_SIZE], // Pre-allocate + }) + }); + } + fn update_min_max_tap_samples(&mut self) { let sample_rate = self.sample_rate; self.delay_data.max_tap_samples = @@ -1048,7 +1069,7 @@ impl Del2 { } else { !self.is_playing_action(MUTE_IN) || self.enabled_actions.load(MUTE_OUT) }; - let mute_buffer = [mute_in_value; DSP_BLOCK_SIZE]; + let mute_buffer = [mute_in_value; MAX_BLOCK_SIZE]; self.mute_in_delay_buffer .write_latest(&mute_buffer[..block_len], write_index); @@ -1062,7 +1083,7 @@ impl Del2 { let write_index = self.delay_write_index; let mute_in_value = self.enabled_actions.load(MUTE_IN); - let mute_buffer = [mute_in_value; DSP_BLOCK_SIZE]; + let mute_buffer = [mute_in_value; MAX_BLOCK_SIZE]; self.mute_in_delay_buffer .write_latest(&mute_buffer[..block_len], write_index); @@ -1468,67 +1489,30 @@ impl Del2 { channel: u8, note: u8, ) -> &mut DelayTap { - let new_delay_tap = DelayTap { - delay_tap_id: 0, - internal_delay_tap_id: self.next_internal_delay_tap_id, - channel, - note, - velocity: 1.0, - - releasing: false, - amp_envelope: Smoother::none(), - - delay_tap_gain: None, - is_muted: false, - tap_index: NUM_TAPS, // start with tap_index out of bounds, to make sure it gets set. - delayed_audio_l: [0.0; DSP_BLOCK_SIZE], - delayed_audio_r: [0.0; DSP_BLOCK_SIZE], - }; - self.next_internal_delay_tap_id = self.next_internal_delay_tap_id.wrapping_add(1); - - if self.params.global.mute_is_toggle.value() { - self.enabled_actions.store(MUTE_OUT, false); - } - - // Can't use `.iter_mut().find()` here because nonlexical lifetimes don't apply to return - // values - match self - .delay_taps - .iter() - .position(|delay_tap| delay_tap.is_none()) - { - Some(free_delay_tap_idx) => { - self.delay_taps[free_delay_tap_idx] = Some(new_delay_tap); - self.delay_taps[free_delay_tap_idx].as_mut().unwrap() - } - None => { - // If there is no free delay tap, find and steal the oldest one - // SAFETY: We can skip a lot of checked unwraps here since we already know all delay_taps are in - // use - let oldest_delay_tap = unsafe { - self.delay_taps - .iter_mut() - .min_by_key(|delay_tap| { - delay_tap.as_ref().unwrap_unchecked().internal_delay_tap_id - }) - .unwrap_unchecked() - }; - - // The stolen delay tap needs to be terminated so the host can reuse its modulation - // resources - { - let oldest_delay_tap = oldest_delay_tap.as_ref().unwrap(); - context.send_event(NoteEvent::VoiceTerminated { - timing: sample_offset, - voice_id: Some(oldest_delay_tap.delay_tap_id), - channel: oldest_delay_tap.channel, - note: oldest_delay_tap.note, - }); - } - - *oldest_delay_tap = Some(new_delay_tap); - oldest_delay_tap.as_mut().unwrap() - } + if let Some(index) = self.delay_taps.iter_mut().position(|tap| tap.is_none()) { + // Find the position for the new tap + let delay_tap = self.delay_taps[index].get_or_insert(DelayTap { + delay_tap_id: 0, + internal_delay_tap_id: self.next_internal_delay_tap_id, + channel, + note, + velocity: 1.0, + releasing: false, + amp_envelope: Smoother::none(), + delay_tap_gain: None, + is_muted: false, + tap_index: index, // Make sure this is set correctly + delayed_audio_l: vec![0.0; MAX_BLOCK_SIZE], + delayed_audio_r: vec![0.0; MAX_BLOCK_SIZE], + }); + + // Increment for the next insertion + self.next_internal_delay_tap_id = self.next_internal_delay_tap_id.wrapping_add(1); + + delay_tap.tap_index = index; // Set/confirm tap_index here explicitly + delay_tap + } else { + panic!("Failed to find or allocate delay tap.") } } @@ -1548,6 +1532,7 @@ impl Del2 { for delay_tap in self.delay_taps.iter_mut().flatten() { let is_toggle = self.params.global.mute_is_toggle.value(); + println!("delay_tap.tap_index: {}", delay_tap.tap_index); let mute_in_delayed = self.mute_in_delayed[delay_tap.tap_index][0]; let mute_out = self.enabled_actions.load(MUTE_OUT);