From d1e2722403c94f0c253c3217bd640246364b73f1 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 22:52:59 +0000 Subject: [PATCH] Optimize DelayEffect with vectorized circular buffer --- src/intuitive_daw/audio/processor.py | 39 ++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/intuitive_daw/audio/processor.py b/src/intuitive_daw/audio/processor.py index b76078b..48b7737 100644 --- a/src/intuitive_daw/audio/processor.py +++ b/src/intuitive_daw/audio/processor.py @@ -231,6 +231,7 @@ def __init__( self.mix = mix self.sample_rate = sample_rate self.buffer = None + self.write_pos = 0 def _process_impl(self, audio: np.ndarray) -> np.ndarray: """Apply delay""" @@ -239,18 +240,40 @@ def _process_impl(self, audio: np.ndarray) -> np.ndarray: # Initialize buffer if self.buffer is None or len(self.buffer) != delay_samples: self.buffer = np.zeros((delay_samples, audio.shape[1])) + self.write_pos = 0 - result = audio.copy() + result = np.empty_like(audio) + num_samples = len(audio) + current_pos = 0 - # Process each sample - for i in range(len(result)): - # Add delayed signal - delayed = self.buffer[0] - result[i] = audio[i] * (1 - self.mix) + delayed * self.mix + while current_pos < num_samples: + # Process in chunks to handle circular buffer wrapping + chunk_size = min( + num_samples - current_pos, + delay_samples - self.write_pos + ) + + # Extract input chunk + chunk_in = audio[current_pos : current_pos + chunk_size] + + # Extract delayed signal from buffer + delayed = self.buffer[self.write_pos : self.write_pos + chunk_size] + + # Compute output + result[current_pos : current_pos + chunk_size] = ( + chunk_in * (1 - self.mix) + delayed * self.mix + ) # Update buffer - self.buffer = np.roll(self.buffer, -1, axis=0) - self.buffer[-1] = audio[i] + delayed * self.feedback + self.buffer[self.write_pos : self.write_pos + chunk_size] = ( + chunk_in + delayed * self.feedback + ) + + # Advance pointers + current_pos += chunk_size + self.write_pos += chunk_size + if self.write_pos >= delay_samples: + self.write_pos = 0 return result