Skip to content

Commit

Permalink
try again, buf_sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
magnetophon committed Nov 2, 2024
1 parent 5e7456b commit 603e13e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 72 deletions.
6 changes: 3 additions & 3 deletions src/delay_tap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::DSP_BLOCK_SIZE;
use crate::MAX_BLOCK_SIZE;
use nih_plug::prelude::*;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -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<f32>,
pub delayed_audio_r: Vec<f32>,
}
123 changes: 54 additions & 69 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -71,7 +72,7 @@ struct Del2 {
// delay write buffer
delay_buffer: [BMRingBuf<f32>; 2],
mute_in_delay_buffer: BMRingBuf<bool>,
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,
Expand Down Expand Up @@ -461,7 +462,7 @@ impl Default for Del2 {
BMRingBuf::<f32>::from_len(TOTAL_DELAY_SAMPLES),
],
mute_in_delay_buffer: BMRingBuf::<bool>::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,
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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.")
}
}

Expand All @@ -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);

Expand Down

0 comments on commit 603e13e

Please sign in to comment.