Feat: clean the codebase as much as possible

This commit is contained in:
2026-02-21 14:46:53 +01:00
parent ab353edc0b
commit 7a95207c58
17 changed files with 233 additions and 368 deletions

View File

@@ -1,5 +1,4 @@
mod editor;
mod input_egui;
mod params;
use std::collections::HashMap;
@@ -51,6 +50,8 @@ pub struct CagirePlugin {
rng: Rng,
cmd_buffer: String,
audio_buffer: Vec<f32>,
output_channels: usize,
scope_extract_buffer: Vec<f32>,
fft_producer: Option<ringbuf::HeapProd<f32>>,
_analysis: Option<AnalysisHandle>,
pending_note_offs: Vec<PendingNoteOff>,
@@ -88,6 +89,8 @@ impl Default for CagirePlugin {
rng,
cmd_buffer: String::with_capacity(256),
audio_buffer: Vec::new(),
output_channels: 2,
scope_extract_buffer: Vec::new(),
fft_producer: None,
_analysis: None,
pending_note_offs: Vec::new(),
@@ -105,19 +108,36 @@ impl Plugin for CagirePlugin {
const EMAIL: &'static str = "raphael.forment@gmail.com";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[AudioIOLayout {
main_input_channels: None,
main_output_channels: Some(new_nonzero_u32(2)),
aux_input_ports: &[],
aux_output_ports: &[],
names: PortNames {
layout: Some("Stereo"),
main_input: None,
main_output: Some("Output"),
aux_inputs: &[],
aux_outputs: &[],
const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[
AudioIOLayout {
main_input_channels: None,
main_output_channels: Some(new_nonzero_u32(2)),
aux_input_ports: &[],
aux_output_ports: &[new_nonzero_u32(2); 7],
names: PortNames {
layout: Some("Multi-output"),
main_input: None,
main_output: Some("Orbit 0"),
aux_inputs: &[],
aux_outputs: &[
"Orbit 1", "Orbit 2", "Orbit 3", "Orbit 4", "Orbit 5", "Orbit 6", "Orbit 7",
],
},
},
}];
AudioIOLayout {
main_input_channels: None,
main_output_channels: Some(new_nonzero_u32(2)),
aux_input_ports: &[],
aux_output_ports: &[],
names: PortNames {
layout: Some("Stereo"),
main_input: None,
main_output: Some("Output"),
aux_inputs: &[],
aux_outputs: &[],
},
},
];
const MIDI_INPUT: MidiConfig = MidiConfig::MidiCCs;
const MIDI_OUTPUT: MidiConfig = MidiConfig::MidiCCs;
@@ -139,7 +159,7 @@ impl Plugin for CagirePlugin {
fn initialize(
&mut self,
_audio_io_layout: &AudioIOLayout,
audio_io_layout: &AudioIOLayout,
buffer_config: &BufferConfig,
_context: &mut impl InitContext<Self>,
) -> bool {
@@ -147,6 +167,9 @@ impl Plugin for CagirePlugin {
self.sample_pos = 0;
self.prev_beat = -1.0;
let num_aux = audio_io_layout.aux_output_ports.len();
self.output_channels = 2 + num_aux * 2;
self.seq_state = Some(SequencerState::new(
Arc::clone(&self.variables),
Arc::clone(&self.dict),
@@ -156,7 +179,7 @@ impl Plugin for CagirePlugin {
let engine = doux::Engine::new_with_channels(
self.sample_rate,
2,
self.output_channels,
64,
);
self.bridge
@@ -217,7 +240,7 @@ impl Plugin for CagirePlugin {
fn process(
&mut self,
buffer: &mut Buffer,
_aux: &mut AuxiliaryBuffers,
aux: &mut AuxiliaryBuffers,
context: &mut impl ProcessContext<Self>,
) -> ProcessStatus {
let Some(seq_state) = &mut self.seq_state else {
@@ -399,34 +422,45 @@ impl Plugin for CagirePlugin {
engine.evaluate(cmd_ref);
}
// Process audio block — doux writes interleaved stereo into our buffer
let num_samples = buffer_len * 2;
self.audio_buffer.resize(num_samples, 0.0);
// Process audio block — doux writes interleaved into our buffer
let total_samples = buffer_len * self.output_channels;
self.audio_buffer.resize(total_samples, 0.0);
self.audio_buffer.fill(0.0);
engine.process_block(&mut self.audio_buffer, &[], &[]);
// Feed scope and spectrum analysis
self.bridge.scope_buffer.write(&self.audio_buffer);
// Feed scope and spectrum analysis (orbit 0 only)
if self.output_channels == 2 {
self.bridge.scope_buffer.write(&self.audio_buffer);
} else {
self.scope_extract_buffer.resize(buffer_len * 2, 0.0);
for i in 0..buffer_len {
self.scope_extract_buffer[i * 2] =
self.audio_buffer[i * self.output_channels];
self.scope_extract_buffer[i * 2 + 1] =
self.audio_buffer[i * self.output_channels + 1];
}
self.bridge.scope_buffer.write(&self.scope_extract_buffer);
}
if let Some(producer) = &mut self.fft_producer {
for chunk in self.audio_buffer.chunks(2) {
let mono = (chunk[0] + chunk.get(1).copied().unwrap_or(0.0)) * 0.5;
let _ = producer.try_push(mono);
let stride = self.output_channels;
for i in 0..buffer_len {
let left = self.audio_buffer[i * stride];
let right = self.audio_buffer[i * stride + 1];
let _ = producer.try_push((left + right) * 0.5);
}
}
// Copy interleaved doux output nih-plug channel slices
let mut channel_iter = buffer.iter_samples();
for frame_idx in 0..buffer_len {
if let Some(mut frame) = channel_iter.next() {
let left = self.audio_buffer[frame_idx * 2];
let right = self.audio_buffer[frame_idx * 2 + 1];
if let Some(sample) = frame.get_mut(0) {
*sample = left;
}
if let Some(sample) = frame.get_mut(1) {
*sample = right;
}
}
// De-interleave doux output into nih-plug channel buffers
let stride = self.output_channels;
deinterleave_stereo(&self.audio_buffer, buffer.as_slice(), stride, 0, buffer_len);
for (aux_idx, aux_buf) in aux.outputs.iter_mut().enumerate() {
deinterleave_stereo(
&self.audio_buffer,
aux_buf.as_slice(),
stride,
(aux_idx + 1) * 2,
buffer_len,
);
}
self.sample_pos += buffer_len as u64;
@@ -445,6 +479,7 @@ impl ClapPlugin for CagirePlugin {
ClapFeature::Instrument,
ClapFeature::Synthesizer,
ClapFeature::Stereo,
ClapFeature::Surround,
];
}
@@ -454,8 +489,23 @@ impl Vst3Plugin for CagirePlugin {
Vst3SubCategory::Instrument,
Vst3SubCategory::Synth,
Vst3SubCategory::Stereo,
Vst3SubCategory::Surround,
];
}
fn deinterleave_stereo(
interleaved: &[f32],
out: &mut [&mut [f32]],
stride: usize,
ch_offset: usize,
len: usize,
) {
let (left, right) = out.split_at_mut(1);
for (i, (l, r)) in left[0][..len].iter_mut().zip(right[0][..len].iter_mut()).enumerate() {
*l = interleaved[i * stride + ch_offset];
*r = interleaved[i * stride + ch_offset + 1];
}
}
nih_export_clap!(CagirePlugin);
nih_export_vst3!(CagirePlugin);