collective

Browse / github.com/storytold/soundcraft / patch

Enforce Rust coding standards via Clippy

Enforce Rust coding standards via Clippy Denies `clippy::cognitive_complexity` with threshold 30 (matches Sonar rust:S3776), `too_many_arguments` and `wildcard_imports` workspace-wide and in crates with their own clippy tables. This PR lands with clippy failing on existing code: 3 functions over the complexity limit, 3 functions with too many arguments, and 1 wildcard import. Follow-up commits fix them. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Chores** * Stricter code-quality checks are now applied consistently across the workspac

Status
open
Score
0.00
Adopters
0 other operators
Author
dylanmtaylor (imported from pull request #1129, open)
Base
1e6310f85ba4e289d9078b52202948c9d398ff44
Size
+419 −270 in 23 files
Review
pending
Shared
2026-10-28
Id
fd46f555a7cc5027fe93c743

How it went

No other operator has reported using it yet.

Diff

raw · CLAUDE.md Cargo.toml clippy.toml crates/au-host/Cargo.toml crates/clap-host/Cargo.toml crates/clap-host/src/ffi.rs crates/clap-host/src/ffi/bundle.rs crates/clap-host/src/ffi/events.rs crates/clap-host/src/ffi/gui.rs crates/clap-host/src/ffi/host.rs crates/clap-host/src/ffi/instance.rs crates/clap-host/src/plugin.rs crates/video/src/h264/deblock.rs crates/video/src/h264/intra.rs crates/video/src/h264/slice.rs crates/vst3-host/Cargo.toml crates/vst3-host/src/ffi.rs crates/vst3-host/src/ffi/editor.rs crates/vst3-host/src/ffi/host.rs crates/vst3-host/src/ffi/instance.rs crates/vst3-host/src/ffi/module.rs crates/vst3-host/src/ffi/process.rs crates/vst3-host/src/plugin.rs

diff --git a/CLAUDE.md b/CLAUDE.md--- a/CLAUDE.md+++ b/CLAUDE.md@@ -1 +1,5 @@ Read `AGENTS.md`: it is the entry point for agents in this repo.++New workspace crates must include `[lints] workspace = true` in `Cargo.toml` to inherit+`[workspace.lints]`. Production crate roots must declare the required crate-level lint attributes+before modules or other crate items; crate-level `//!` documentation may precede them.diff --git a/Cargo.toml b/Cargo.toml--- a/Cargo.toml+++ b/Cargo.toml@@ -65,9 +65,11 @@ image = { version = "0.25", default-features = false, features = ["png"] } unsafe_code = "forbid"  [workspace.lints.clippy]+cognitive_complexity = "deny"+wildcard_imports = "deny" dbg_macro = "warn" todo = "warn"-too_many_arguments = "allow"+too_many_arguments = "deny" type_complexity = "allow"  [profile.dev.package."*"]diff --git a/clippy.toml b/clippy.toml--- a/clippy.toml+++ b/clippy.toml@@ -6,3 +6,4 @@ allow-indexing-slicing-in-tests = true disallowed-types = [     { path = "egui::ComboBox", reason = "use craft_ui::ComboBox: egui's combo box menu can't grow back while open (egui#5225)" }, ]+cognitive-complexity-threshold = 30diff --git a/crates/au-host/Cargo.toml b/crates/au-host/Cargo.toml--- a/crates/au-host/Cargo.toml+++ b/crates/au-host/Cargo.toml@@ -20,7 +20,9 @@ log.workspace = true unsafe_code = "deny"  [lints.clippy]+cognitive_complexity = "deny"+wildcard_imports = "deny" dbg_macro = "warn" todo = "warn"-too_many_arguments = "allow"+too_many_arguments = "deny" type_complexity = "allow"diff --git a/crates/clap-host/Cargo.toml b/crates/clap-host/Cargo.toml--- a/crates/clap-host/Cargo.toml+++ b/crates/clap-host/Cargo.toml@@ -32,7 +32,9 @@ libloading = "0.9" unsafe_code = "deny"  [lints.clippy]+cognitive_complexity = "deny"+wildcard_imports = "deny" dbg_macro = "warn" todo = "warn"-too_many_arguments = "allow"+too_many_arguments = "deny" type_complexity = "allow"diff --git a/crates/clap-host/src/ffi.rs b/crates/clap-host/src/ffi.rs--- a/crates/clap-host/src/ffi.rs+++ b/crates/clap-host/src/ffi.rs@@ -54,7 +54,7 @@ pub(crate) use events::Event; #[cfg(test)] use events::transport_event; pub(crate) use gui::GuiLink;-pub(crate) use instance::{Instance, NotePort, PortBuffers, PortInfo, RawParam};+pub(crate) use instance::{Instance, NotePort, PortBuffers, PortInfo, ProcessInput, RawParam};  /// Most plugins one factory may report (hostile-input cap). const MAX_PLUGINS_PER_FACTORY: u32 = 1024;diff --git a/crates/clap-host/src/ffi/bundle.rs b/crates/clap-host/src/ffi/bundle.rs--- a/crates/clap-host/src/ffi/bundle.rs+++ b/crates/clap-host/src/ffi/bundle.rs@@ -1,7 +1,12 @@ use super::gui::{GuiInner, GuiLink}; use super::host::{HostState, host_get_extension, host_request_callback, host_request_process, host_request_restart}; use super::instance::Instance;-use super::*;+use super::{+    Arc, CLAP_EXT_AUDIO_PORTS, CLAP_EXT_GUI, CLAP_EXT_LATENCY, CLAP_EXT_NOTE_PORTS, CLAP_EXT_PARAMS, CLAP_EXT_STATE, CLAP_PLUGIN_FACTORY_ID,+    CLAP_VERSION, CString, ClapError, EVENT_CAP, HashMap, MAX_FEATURES, MAX_PLUGINS_PER_FACTORY, Mutex, OnceLock, Path, PathBuf, PoisonError, c_void,+    clap_host, clap_plugin_audio_ports, clap_plugin_entry, clap_plugin_factory, clap_plugin_gui, clap_plugin_latency, clap_plugin_note_ports,+    clap_plugin_params, clap_plugin_state, clap_version_is_compatible, read_cstr, scan,+};  // ---- loaded binaries ----------------------------------------------------------------------- diff --git a/crates/clap-host/src/ffi/events.rs b/crates/clap-host/src/ffi/events.rs--- a/crates/clap-host/src/ffi/events.rs+++ b/crates/clap-host/src/ffi/events.rs@@ -1,4 +1,10 @@-use super::*;+use super::{+    CLAP_BEATTIME_FACTOR, CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_MIDI, CLAP_EVENT_NOTE_OFF, CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_VALUE,+    CLAP_EVENT_TRANSPORT, CLAP_SECTIME_FACTOR, CLAP_TRANSPORT_HAS_BEATS_TIMELINE, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE, CLAP_TRANSPORT_HAS_TEMPO,+    CLAP_TRANSPORT_HAS_TIME_SIGNATURE, CLAP_TRANSPORT_IS_PLAYING, CLAP_TRANSPORT_IS_RECORDING, MAX_STATE_BYTES, Transport, c_void, clap_event_header,+    clap_event_midi, clap_event_note, clap_event_param_value, clap_event_transport, clap_input_events, clap_istream, clap_ostream,+    clap_output_events,+};  // ---- events -------------------------------------------------------------------------------- diff --git a/crates/clap-host/src/ffi/gui.rs b/crates/clap-host/src/ffi/gui.rs--- a/crates/clap-host/src/ffi/gui.rs+++ b/crates/clap-host/src/ffi/gui.rs@@ -1,6 +1,9 @@ use super::events::ostream_write; use super::host::HostState;-use super::*;+use super::{+    Arc, CStr, CString, Mutex, Ordering, PoisonError, c_void, clap_ostream, clap_plugin, clap_plugin_gui, clap_plugin_state, clap_window,+    clap_window_handle, hostwin,+};  // ---- editor (clap.gui) --------------------------------------------------------------------- diff --git a/crates/clap-host/src/ffi/host.rs b/crates/clap-host/src/ffi/host.rs--- a/crates/clap-host/src/ffi/host.rs+++ b/crates/clap-host/src/ffi/host.rs@@ -1,4 +1,8 @@-use super::*;+use super::{+    AtomicBool, AtomicU64, CLAP_EXT_GUI, CLAP_EXT_LATENCY, CLAP_EXT_LOG, CLAP_EXT_PARAMS, CLAP_EXT_STATE, CLAP_LOG_ERROR, CLAP_LOG_FATAL,+    CLAP_LOG_WARNING, CStr, EDIT_CAP, Mutex, Ordering, c_char, c_void, clap_host, clap_host_gui, clap_host_latency, clap_host_log, clap_host_params,+    clap_host_state, clap_id, clap_log_severity, clap_param_clear_flags, clap_param_rescan_flags, read_cstr,+};  // ---- host side ----------------------------------------------------------------------------- diff --git a/crates/clap-host/src/ffi/instance.rs b/crates/clap-host/src/ffi/instance.rs--- a/crates/clap-host/src/ffi/instance.rs+++ b/crates/clap-host/src/ffi/instance.rs@@ -2,7 +2,12 @@ use super::bundle::Bundle; use super::events::{Event, RawEvent, ReadCursor, in_events_get, in_events_size, istream_read, out_events_try_push, transport_event}; use super::gui::GuiLink; use super::host::HostState;-use super::*;+use super::{+    Arc, CLAP_AUDIO_PORT_IS_MAIN, CLAP_PROCESS_ERROR, CStr, ClapError, MAX_PARAMS, MAX_PORT_CHANNELS, MAX_PORTS, Ordering, Transport, c_char, c_void,+    clap_audio_buffer, clap_audio_port_info, clap_host, clap_input_events, clap_istream, clap_note_port_info, clap_output_events, clap_param_info,+    clap_plugin, clap_plugin_audio_ports, clap_plugin_latency, clap_plugin_note_ports, clap_plugin_params, clap_plugin_state, clap_process,+    read_name,+};  // ---- audio buffers ------------------------------------------------------------------------- @@ -312,16 +317,8 @@ impl Instance {      /// Runs one `clap_process` call over `frames` frames. Events must be sorted by time; their     /// times are made relative to `offset`. Returns the CLAP process status.-    pub fn process(-        &mut self,-        frames: usize,-        steady_time: i64,-        inputs: &mut PortBuffers,-        outputs: &mut PortBuffers,-        events: &[Event],-        offset: u32,-        transport: Option<&Transport>,-    ) -> Result<i32, ClapError> {+    pub fn process(&mut self, input: ProcessInput<'_>) -> Result<i32, ClapError> {+        let ProcessInput { frames, steady_time, inputs, outputs, events, offset, transport } = input;         if !self.active {             return Err(ClapError::Process("not active".into()));         }@@ -386,6 +383,16 @@ impl Instance {     } } +pub(crate) struct ProcessInput<'a> {+    pub frames: usize,+    pub steady_time: i64,+    pub inputs: &'a mut PortBuffers,+    pub outputs: &'a mut PortBuffers,+    pub events: &'a [Event],+    pub offset: u32,+    pub transport: Option<&'a Transport>,+}+ impl Drop for Instance {     fn drop(&mut self) {         // Editors first (CLAP: destroy the GUI before the plugin), and no handle may call in after.diff --git a/crates/clap-host/src/plugin.rs b/crates/clap-host/src/plugin.rs--- a/crates/clap-host/src/plugin.rs+++ b/crates/clap-host/src/plugin.rs@@ -1,6 +1,6 @@ //! `ClapPlugin`: a loaded CLAP instance behind the safe `soundcraft_dsp::Plugin` trait. -use crate::ffi::{EVENT_CAP, Event, GuiLink, Instance, NotePort, PortBuffers};+use crate::ffi::{EVENT_CAP, Event, GuiLink, Instance, NotePort, PortBuffers, ProcessInput}; use clap_sys::ext::note_ports::{CLAP_NOTE_DIALECT_CLAP, CLAP_NOTE_DIALECT_MIDI}; use soundcraft_dsp::{Plugin, PluginEditor, PluginInfo, Transport}; use std::sync::Arc;@@ -231,7 +231,15 @@ impl Plugin for ClapPlugin {             let k = self.queue.iter().position(|e| e.time() >= end).unwrap_or(self.queue.len());             let offset = u32::try_from(start).unwrap_or(u32::MAX);             let events = self.queue.get(..k).unwrap_or(&[]);-            let r = self.inst.process(n, self.steady, &mut self.inputs, &mut self.outputs, events, offset, self.transport.as_ref());+            let r = self.inst.process(ProcessInput {+                frames: n,+                steady_time: self.steady,+                inputs: &mut self.inputs,+                outputs: &mut self.outputs,+                events,+                offset,+                transport: self.transport.as_ref(),+            });             self.queue.drain(..k);             self.steady = self.steady.saturating_add(i64::try_from(n).unwrap_or(0));             match (r, self.out_main) {diff --git a/crates/video/src/h264/deblock.rs b/crates/video/src/h264/deblock.rs--- a/crates/video/src/h264/deblock.rs+++ b/crates/video/src/h264/deblock.rs@@ -279,7 +279,6 @@ fn filter_horizontal<const N: usize>(pix: &mut [u8], stride: usize, x: usize, y: }  /// Deblock one macroblock (macroblocks must be processed in raster order).-#[allow(clippy::needless_range_loop)] pub fn deblock_mb(pic: &mut PicState, addr: usize, mb_w: usize) {     let q = &pic.mbs[addr];     if q.slice_num == u32::MAX {@@ -303,6 +302,23 @@ pub fn deblock_mb(pic: &mut PicState, addr: usize, mb_w: usize) {     let alpha_off = sq.alpha_offset;     let beta_off = sq.beta_offset;     let t8 = q.transform_8x8;+    let bs = boundary_strengths(pic, q, sq, left, top, t8);+    let qp_of = |st: &MbState| if st.kind == MbKind::IPcm { 0 } else { st.qp as i32 };+    let q_qp = qp_of(q);+    let q_qpc = q.qpc;+    let p_qp = [left.map(|n| (qp_of(&pic.mbs[n]), pic.mbs[n].qpc)), top.map(|n| (qp_of(&pic.mbs[n]), pic.mbs[n].qpc))];+    let params = |qpp: i32, qpq: i32, b: [u8; 4]| {+        let qpav = (qpp + qpq + 1) >> 1;+        let index_a = (qpav + alpha_off).clamp(0, 51) as usize;+        let index_b = (qpav + beta_off).clamp(0, 51) as usize;+        let tc = |b: u8| if (1..4).contains(&b) { TC0[index_a][b as usize - 1] as i32 } else { 0 };+        EdgeParams { bs: b, tc0: [tc(b[0]), tc(b[1]), tc(b[2]), tc(b[3])], alpha: ALPHA[index_a] as i32, beta: BETA[index_b] as i32 }+    };+    filter_luma(pic, (mx, my), &bs, q_qp, p_qp, &params);+    filter_chroma(pic, (mx, my), &bs, q_qpc, p_qp, &params);+}++fn boundary_strengths(pic: &PicState, q: &MbState, sq: &SliceInfo, left: Option<usize>, top: Option<usize>, t8: bool) -> [[[u8; 4]; 4]; 2] {     // bS[dir][edge][segment]; dir 0 = vertical edges (x), 1 = horizontal edges (y)     let mut bs = [[[0u8; 4]; 4]; 2];     if q.kind.is_intra() {@@ -356,20 +372,18 @@ pub fn deblock_mb(pic: &mut PicState, addr: usize, mb_w: usize) {             }         }     }-    let qp_of = |st: &MbState| if st.kind == MbKind::IPcm { 0 } else { st.qp as i32 };-    let q_qp = qp_of(q);-    let q_qpc = q.qpc;-    let p_qp = [left.map(|n| (qp_of(&pic.mbs[n]), pic.mbs[n].qpc)), top.map(|n| (qp_of(&pic.mbs[n]), pic.mbs[n].qpc))];-    let params = |qpp: i32, qpq: i32, b: [u8; 4]| {-        let qpav = (qpp + qpq + 1) >> 1;-        let index_a = (qpav + alpha_off).clamp(0, 51) as usize;-        let index_b = (qpav + beta_off).clamp(0, 51) as usize;-        let tc = |b: u8| if (1..4).contains(&b) { TC0[index_a][b as usize - 1] as i32 } else { 0 };-        EdgeParams { bs: b, tc0: [tc(b[0]), tc(b[1]), tc(b[2]), tc(b[3])], alpha: ALPHA[index_a] as i32, beta: BETA[index_b] as i32 }-    };+    bs+}++fn filter_luma(+    pic: &mut PicState,+    (mx, my): (usize, usize),+    bs: &[[[u8; 4]; 4]; 2],+    q_qp: i32,+    p_qp: [Option<(i32, [u8; 2])>; 2],+    params: &impl Fn(i32, i32, [u8; 4]) -> EdgeParams,+) {     let width = pic.planes.width;-    let cwidth = pic.planes.cwidth;-    // luma     for dir in 0..2 {         for e in 0..4 {             if bs[dir][e] == [0; 4] {@@ -389,6 +403,17 @@ pub fn deblock_mb(pic: &mut PicState, addr: usize, mb_w: usize) {             }         }     }+}++fn filter_chroma(+    pic: &mut PicState,+    (mx, my): (usize, usize),+    bs: &[[[u8; 4]; 4]; 2],+    q_qpc: [u8; 2],+    p_qp: [Option<(i32, [u8; 2])>; 2],+    params: &impl Fn(i32, i32, [u8; 4]) -> EdgeParams,+) {+    let cwidth = pic.planes.cwidth;     // chroma (4:2:0): edges at chroma samples 0 and 4 use the bS of luma edges 0 and 2     for c in 0..2 {         for dir in 0..2 {diff --git a/crates/video/src/h264/intra.rs b/crates/video/src/h264/intra.rs--- a/crates/video/src/h264/intra.rs+++ b/crates/video/src/h264/intra.rs@@ -61,125 +61,146 @@ fn load_edge(plane: &[u8], stride: usize, x: usize, y: usize, n: usize, a: Avail  /// Directional / DC prediction shared by Intra_4x4 and Intra_8x8 (8.3.1.2.x, 8.3.2.2.x). fn pred_nxn(mode: u8, e: &Edge, n: i32, a: Avail, out: &mut [u8], stride: usize) {-    let mut put = |x: i32, y: i32, v: i32| out[y as usize * stride + x as usize] = v as u8;     match mode {-        0 => {-            for y in 0..n {-                for x in 0..n {-                    put(x, y, e.t(x));-                }-            }+        0 => pred_vertical(e, n, out, stride),+        1 => pred_horizontal(e, n, out, stride),+        2 => pred_dc(e, n, a, out, stride),+        3 => pred_down_left(e, n, out, stride),+        4 => pred_down_right(e, n, out, stride),+        5 => pred_vertical_right(e, n, out, stride),+        6 => pred_horizontal_down(e, n, out, stride),+        7 => pred_vertical_left(e, n, out, stride),+        _ => pred_horizontal_up(e, n, out, stride),+    }+}++fn put(out: &mut [u8], stride: usize, x: i32, y: i32, value: i32) {+    out[y as usize * stride + x as usize] = value as u8;+}++fn pred_vertical(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            put(out, stride, x, y, e.t(x));         }-        1 => {-            for y in 0..n {-                for x in 0..n {-                    put(x, y, e.l(y));-                }-            }+    }+}++fn pred_horizontal(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            put(out, stride, x, y, e.l(y));         }-        2 => {-            let shift = if n == 4 { 2 } else { 3 };-            let st: i32 = (0..n).map(|x| e.t(x)).sum();-            let sl: i32 = (0..n).map(|y| e.l(y)).sum();-            let dc = match (a.top, a.left) {-                (true, true) => (st + sl + n) >> (shift + 1),-                (false, true) => (sl + (n >> 1)) >> shift,-                (true, false) => (st + (n >> 1)) >> shift,-                _ => 128,-            };-            for y in 0..n {-                for x in 0..n {-                    put(x, y, dc);-                }-            }+    }+}++fn pred_dc(e: &Edge, n: i32, a: Avail, out: &mut [u8], stride: usize) {+    let shift = if n == 4 { 2 } else { 3 };+    let st: i32 = (0..n).map(|x| e.t(x)).sum();+    let sl: i32 = (0..n).map(|y| e.l(y)).sum();+    let dc = match (a.top, a.left) {+        (true, true) => (st + sl + n) >> (shift + 1),+        (false, true) => (sl + (n >> 1)) >> shift,+        (true, false) => (st + (n >> 1)) >> shift,+        _ => 128,+    };+    for y in 0..n {+        for x in 0..n {+            put(out, stride, x, y, dc);         }-        3 => {-            for y in 0..n {-                for x in 0..n {-                    let v = if x == n - 1 && y == n - 1 {-                        (e.t(2 * n - 2) + 3 * e.t(2 * n - 1) + 2) >> 2-                    } else {-                        (e.t(x + y) + 2 * e.t(x + y + 1) + e.t(x + y + 2) + 2) >> 2-                    };-                    put(x, y, v);-                }-            }+    }+}++fn pred_down_left(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            let value = if x == n - 1 && y == n - 1 {+                (e.t(2 * n - 2) + 3 * e.t(2 * n - 1) + 2) >> 2+            } else {+                (e.t(x + y) + 2 * e.t(x + y + 1) + e.t(x + y + 2) + 2) >> 2+            };+            put(out, stride, x, y, value);         }-        4 => {-            for y in 0..n {-                for x in 0..n {-                    let v = if x > y {-                        (e.t(x - y - 2) + 2 * e.t(x - y - 1) + e.t(x - y) + 2) >> 2-                    } else if x < y {-                        (e.l(y - x - 2) + 2 * e.l(y - x - 1) + e.l(y - x) + 2) >> 2-                    } else {-                        (e.t(0) + 2 * e.tl + e.l(0) + 2) >> 2-                    };-                    put(x, y, v);-                }-            }+    }+}++fn pred_down_right(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            let value = if x > y {+                (e.t(x - y - 2) + 2 * e.t(x - y - 1) + e.t(x - y) + 2) >> 2+            } else if x < y {+                (e.l(y - x - 2) + 2 * e.l(y - x - 1) + e.l(y - x) + 2) >> 2+            } else {+                (e.t(0) + 2 * e.tl + e.l(0) + 2) >> 2+            };+            put(out, stride, x, y, value);         }-        5 => {-            for y in 0..n {-                for x in 0..n {-                    let z = 2 * x - y;-                    let v = if z >= 0 && z % 2 == 0 {-                        (e.t(x - (y >> 1) - 1) + e.t(x - (y >> 1)) + 1) >> 1-                    } else if z > 0 {-                        (e.t(x - (y >> 1) - 2) + 2 * e.t(x - (y >> 1) - 1) + e.t(x - (y >> 1)) + 2) >> 2-                    } else if z == -1 {-                        (e.l(0) + 2 * e.tl + e.t(0) + 2) >> 2-                    } else {-                        (e.l(y - 2 * x - 1) + 2 * e.l(y - 2 * x - 2) + e.l(y - 2 * x - 3) + 2) >> 2-                    };-                    put(x, y, v);-                }-            }+    }+}++fn pred_vertical_right(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            let z = 2 * x - y;+            let value = if z >= 0 && z % 2 == 0 {+                (e.t(x - (y >> 1) - 1) + e.t(x - (y >> 1)) + 1) >> 1+            } else if z > 0 {+                (e.t(x - (y >> 1) - 2) + 2 * e.t(x - (y >> 1) - 1) + e.t(x - (y >> 1)) + 2) >> 2+            } else if z == -1 {+                (e.l(0) + 2 * e.tl + e.t(0) + 2) >> 2+            } else {+                (e.l(y - 2 * x - 1) + 2 * e.l(y - 2 * x - 2) + e.l(y - 2 * x - 3) + 2) >> 2+            };+            put(out, stride, x, y, value);         }-        6 => {-            for y in 0..n {-                for x in 0..n {-                    let z = 2 * y - x;-                    let v = if z >= 0 && z % 2 == 0 {-                        (e.l(y - (x >> 1) - 1) + e.l(y - (x >> 1)) + 1) >> 1-                    } else if z > 0 {-                        (e.l(y - (x >> 1) - 2) + 2 * e.l(y - (x >> 1) - 1) + e.l(y - (x >> 1)) + 2) >> 2-                    } else if z == -1 {-                        (e.l(0) + 2 * e.tl + e.t(0) + 2) >> 2-                    } else {-                        (e.t(x - 2 * y - 1) + 2 * e.t(x - 2 * y - 2) + e.t(x - 2 * y - 3) + 2) >> 2-                    };-                    put(x, y, v);-                }-            }+    }+}++fn pred_horizontal_down(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            let z = 2 * y - x;+            let value = if z >= 0 && z % 2 == 0 {+                (e.l(y - (x >> 1) - 1) + e.l(y - (x >> 1)) + 1) >> 1+            } else if z > 0 {+                (e.l(y - (x >> 1) - 2) + 2 * e.l(y - (x >> 1) - 1) + e.l(y - (x >> 1)) + 2) >> 2+            } else if z == -1 {+                (e.l(0) + 2 * e.tl + e.t(0) + 2) >> 2+            } else {+                (e.t(x - 2 * y - 1) + 2 * e.t(x - 2 * y - 2) + e.t(x - 2 * y - 3) + 2) >> 2+            };+            put(out, stride, x, y, value);         }-        7 => {-            for y in 0..n {-                for x in 0..n {-                    let i = x + (y >> 1);-                    let v = if y % 2 == 0 { (e.t(i) + e.t(i + 1) + 1) >> 1 } else { (e.t(i) + 2 * e.t(i + 1) + e.t(i + 2) + 2) >> 2 };-                    put(x, y, v);-                }-            }+    }+}++fn pred_vertical_left(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    for y in 0..n {+        for x in 0..n {+            let i = x + (y >> 1);+            let value = if y % 2 == 0 { (e.t(i) + e.t(i + 1) + 1) >> 1 } else { (e.t(i) + 2 * e.t(i + 1) + e.t(i + 2) + 2) >> 2 };+            put(out, stride, x, y, value);         }-        _ => {-            let zmax = 2 * n - 3;-            for y in 0..n {-                for x in 0..n {-                    let z = x + 2 * y;-                    let i = y + (x >> 1);-                    let v = if z < zmax && z % 2 == 0 {-                        (e.l(i) + e.l(i + 1) + 1) >> 1-                    } else if z < zmax {-                        (e.l(i) + 2 * e.l(i + 1) + e.l(i + 2) + 2) >> 2-                    } else if z == zmax {-                        (e.l(n - 2) + 3 * e.l(n - 1) + 2) >> 2-                    } else {-                        e.l(n - 1)-                    };-                    put(x, y, v);-                }-            }+    }+}++fn pred_horizontal_up(e: &Edge, n: i32, out: &mut [u8], stride: usize) {+    let zmax = 2 * n - 3;+    for y in 0..n {+        for x in 0..n {+            let z = x + 2 * y;+            let i = y + (x >> 1);+            let value = if z < zmax && z % 2 == 0 {+                (e.l(i) + e.l(i + 1) + 1) >> 1+            } else if z < zmax {+                (e.l(i) + 2 * e.l(i + 1) + e.l(i + 2) + 2) >> 2+            } else if z == zmax {+                (e.l(n - 2) + 3 * e.l(n - 1) + 2) >> 2+            } else {+                e.l(n - 1)+            };+            put(out, stride, x, y, value);         }     } }diff --git a/crates/video/src/h264/slice.rs b/crates/video/src/h264/slice.rs--- a/crates/video/src/h264/slice.rs+++ b/crates/video/src/h264/slice.rs@@ -214,101 +214,9 @@ impl SliceHeader {             num_ref_idx_active[0] = 0;         }         ensure!(nal.nal_unit_type != 20 && nal.nal_unit_type != 21, "MVC slices are not supported");-        let mut ref_pic_list_mod = [Vec::new(), Vec::new()];-        for (list, mods) in ref_pic_list_mod.iter_mut().enumerate() {-            let present = if list == 0 { !slice_type.is_intra() } else { slice_type.is_b() };-            if present && r.read_flag()? {-                loop {-                    let idc = r.read_ue()?;-                    ensure!(idc <= 5, "modification_of_pic_nums_idc out of range");-                    if idc == 3 {-                        break;-                    }-                    let value = r.read_ue()?;-                    mods.push(RefPicListMod { idc, value });-                    ensure!(mods.len() <= 66, "too many ref_pic_list_modification entries");-                }-            }-        }-        let mut pred_weight_table = None;-        if (pps.weighted_pred && slice_type.is_p()) || (pps.weighted_bipred_idc == 1 && slice_type.is_b()) {-            let luma_log2_denom = r.read_ue()?;-            ensure!(luma_log2_denom <= 7, "luma_log2_weight_denom out of range");-            let mut chroma_log2_denom = 0;-            if sps.chroma_array_type() != 0 {-                chroma_log2_denom = r.read_ue()?;-                ensure!(chroma_log2_denom <= 7, "chroma_log2_weight_denom out of range");-            }-            let mut lists = [Vec::new(), Vec::new()];-            let nlists = if slice_type.is_b() { 2 } else { 1 };-            for (l, entries) in lists.iter_mut().enumerate().take(nlists) {-                for _ in 0..num_ref_idx_active[l] {-                    let mut e = WeightEntry { luma_weight: 1 << luma_log2_denom, chroma_weight: [1 << chroma_log2_denom; 2], ..Default::default() };-                    if r.read_flag()? {-                        e.luma_flag = true;-                        e.luma_weight = r.read_se()?;-                        e.luma_offset = r.read_se()?;-                        ensure!((-128..=127).contains(&e.luma_weight) && (-128..=127).contains(&e.luma_offset), "luma weight out of range");-                    }-                    if sps.chroma_array_type() != 0 && r.read_flag()? {-                        e.chroma_flag = true;-                        for j in 0..2 {-                            e.chroma_weight[j] = r.read_se()?;-                            e.chroma_offset[j] = r.read_se()?;-                            ensure!(-                                (-128..=127).contains(&e.chroma_weight[j]) && (-128..=127).contains(&e.chroma_offset[j]),-                                "chroma weight out of range"-                            );-                        }-                    }-                    entries.push(e);-                }-            }-            let [l0, l1] = lists;-            pred_weight_table = Some(PredWeightTable { luma_log2_denom, chroma_log2_denom, l0, l1 });-        }-        let mut no_output_of_prior_pics = false;-        let mut long_term_reference = false;-        let mut adaptive_ref_pic_marking = false;-        let mut mmcos = Vec::new();-        if nal.nal_ref_idc != 0 {-            if idr {-                no_output_of_prior_pics = r.read_flag()?;-                long_term_reference = r.read_flag()?;-            } else {-                adaptive_ref_pic_marking = r.read_flag()?;-                if adaptive_ref_pic_marking {-                    loop {-                        let op = r.read_ue()?;-                        ensure!(op <= 6, "memory_management_control_operation out of range");-                        if op == 0 {-                            break;-                        }-                        let mut m = Mmco {-                            op,-                            difference_of_pic_nums_minus1: 0,-                            long_term_pic_num: 0,-                            long_term_frame_idx: 0,-                            max_long_term_frame_idx_plus1: 0,-                        };-                        if op == 1 || op == 3 {-                            m.difference_of_pic_nums_minus1 = r.read_ue()?;-                        }-                        if op == 2 {-                            m.long_term_pic_num = r.read_ue()?;-                        }-                        if op == 3 || op == 6 {-                            m.long_term_frame_idx = r.read_ue()?;-                        }-                        if op == 4 {-                            m.max_long_term_frame_idx_plus1 = r.read_ue()?;-                        }-                        mmcos.push(m);-                        ensure!(mmcos.len() <= 66, "too many MMCOs");-                    }-                }-            }-        }+        let ref_fields = parse_reference_fields(&mut r, nal, idr, slice_type, pps, sps, num_ref_idx_active)?;+        let RefFields { ref_pic_list_mod, pred_weight_table, no_output_of_prior_pics, long_term_reference, adaptive_ref_pic_marking, mmcos } =+            ref_fields;         let mut cabac_init_idc = 0;         if pps.entropy_coding_mode && !slice_type.is_intra() {             cabac_init_idc = r.read_ue()?;@@ -391,6 +299,134 @@ impl SliceHeader {     } } +struct RefFields {+    ref_pic_list_mod: [Vec<RefPicListMod>; 2],+    pred_weight_table: Option<PredWeightTable>,+    no_output_of_prior_pics: bool,+    long_term_reference: bool,+    adaptive_ref_pic_marking: bool,+    mmcos: Vec<Mmco>,+}++fn parse_reference_fields(+    r: &mut BitReader<'_>,+    nal: NalHeader,+    idr: bool,+    slice_type: SliceType,+    pps: &Pps,+    sps: &Sps,+    num_ref_idx_active: [u32; 2],+) -> Result<RefFields> {+    let ref_pic_list_mod = parse_ref_pic_list_mod(r, slice_type)?;+    let pred_weight_table = parse_pred_weight_table(r, slice_type, pps, sps, num_ref_idx_active)?;+    let (no_output_of_prior_pics, long_term_reference, adaptive_ref_pic_marking, mmcos) = parse_ref_pic_marking(r, nal, idr)?;+    Ok(RefFields { ref_pic_list_mod, pred_weight_table, no_output_of_prior_pics, long_term_reference, adaptive_ref_pic_marking, mmcos })+}++fn parse_ref_pic_list_mod(r: &mut BitReader<'_>, slice_type: SliceType) -> Result<[Vec<RefPicListMod>; 2]> {+    let mut lists = [Vec::new(), Vec::new()];+    for (list, mods) in lists.iter_mut().enumerate() {+        let present = if list == 0 { !slice_type.is_intra() } else { slice_type.is_b() };+        if present && r.read_flag()? {+            loop {+                let idc = r.read_ue()?;+                ensure!(idc <= 5, "modification_of_pic_nums_idc out of range");+                if idc == 3 {+                    break;+                }+                mods.push(RefPicListMod { idc, value: r.read_ue()? });+                ensure!(mods.len() <= 66, "too many ref_pic_list_modification entries");+            }+        }+    }+    Ok(lists)+}++fn parse_pred_weight_table(r: &mut BitReader<'_>, slice_type: SliceType, pps: &Pps, sps: &Sps, active: [u32; 2]) -> Result<Option<PredWeightTable>> {+    let weighted = (pps.weighted_pred && slice_type.is_p()) || (pps.weighted_bipred_idc == 1 && slice_type.is_b());+    if !weighted {+        return Ok(None);+    }+    let luma_log2_denom = r.read_ue()?;+    ensure!(luma_log2_denom <= 7, "luma_log2_weight_denom out of range");+    let chroma_log2_denom = if sps.chroma_array_type() == 0 { 0 } else { r.read_ue()? };+    ensure!(chroma_log2_denom <= 7, "chroma_log2_weight_denom out of range");+    let mut lists = [Vec::new(), Vec::new()];+    let list_count = if slice_type.is_b() { 2 } else { 1 };+    for (list, entries) in lists.iter_mut().enumerate().take(list_count) {+        for _ in 0..active[list] {+            entries.push(parse_weight_entry(r, luma_log2_denom, chroma_log2_denom, sps.chroma_array_type() != 0)?);+        }+    }+    let [l0, l1] = lists;+    Ok(Some(PredWeightTable { luma_log2_denom, chroma_log2_denom, l0, l1 }))+}++fn parse_weight_entry(r: &mut BitReader<'_>, luma_denom: u32, chroma_denom: u32, has_chroma: bool) -> Result<WeightEntry> {+    let mut entry = WeightEntry { luma_weight: 1 << luma_denom, chroma_weight: [1 << chroma_denom; 2], ..Default::default() };+    if r.read_flag()? {+        entry.luma_flag = true;+        entry.luma_weight = r.read_se()?;+        entry.luma_offset = r.read_se()?;+        ensure!((-128..=127).contains(&entry.luma_weight) && (-128..=127).contains(&entry.luma_offset), "luma weight out of range");+    }+    if has_chroma && r.read_flag()? {+        entry.chroma_flag = true;+        for index in 0..2 {+            entry.chroma_weight[index] = r.read_se()?;+            entry.chroma_offset[index] = r.read_se()?;+            ensure!(+                (-128..=127).contains(&entry.chroma_weight[index]) && (-128..=127).contains(&entry.chroma_offset[index]),+                "chroma weight out of range"+            );+        }+    }+    Ok(entry)+}++fn parse_ref_pic_marking(r: &mut BitReader<'_>, nal: NalHeader, idr: bool) -> Result<(bool, bool, bool, Vec<Mmco>)> {+    let (mut no_output, mut long_term, mut adaptive) = (false, false, false);+    let mut mmcos = Vec::new();+    if nal.nal_ref_idc == 0 {+        return Ok((no_output, long_term, adaptive, mmcos));+    }+    if idr {+        no_output = r.read_flag()?;+        long_term = r.read_flag()?;+    } else {+        adaptive = r.read_flag()?;+        if adaptive {+            parse_mmcos(r, &mut mmcos)?;+        }+    }+    Ok((no_output, long_term, adaptive, mmcos))+}++fn parse_mmcos(r: &mut BitReader<'_>, mmcos: &mut Vec<Mmco>) -> Result<()> {+    loop {+        let op = r.read_ue()?;+        ensure!(op <= 6, "memory_management_control_operation out of range");+        if op == 0 {+            return Ok(());+        }+        let mut m = Mmco { op, difference_of_pic_nums_minus1: 0, long_term_pic_num: 0, long_term_frame_idx: 0, max_long_term_frame_idx_plus1: 0 };+        if op == 1 || op == 3 {+            m.difference_of_pic_nums_minus1 = r.read_ue()?;+        }+        if op == 2 {+            m.long_term_pic_num = r.read_ue()?;+        }+        if op == 3 || op == 6 {+            m.long_term_frame_idx = r.read_ue()?;+        }+        if op == 4 {+            m.max_long_term_frame_idx_plus1 = r.read_ue()?;+        }+        mmcos.push(m);+        ensure!(mmcos.len() <= 66, "too many MMCOs");+    }+}+ /// POC decoding state carried between pictures (8.2.1). #[derive(Clone, Debug, Default)] pub struct PocState {diff --git a/crates/vst3-host/Cargo.toml b/crates/vst3-host/Cargo.toml--- a/crates/vst3-host/Cargo.toml+++ b/crates/vst3-host/Cargo.toml@@ -54,7 +54,9 @@ harness = false unsafe_code = "deny"  [lints.clippy]+cognitive_complexity = "deny"+wildcard_imports = "deny" dbg_macro = "warn" todo = "warn"-too_many_arguments = "allow"+too_many_arguments = "deny" type_complexity = "allow"diff --git a/crates/vst3-host/src/ffi.rs b/crates/vst3-host/src/ffi.rs--- a/crates/vst3-host/src/ffi.rs+++ b/crates/vst3-host/src/ffi.rs@@ -39,7 +39,7 @@ mod process;  pub(crate) use editor::EditorLink; pub(crate) use host::HostContext;-pub(crate) use instance::{Instance, PARAM_BYPASS, PARAM_HIDDEN, PARAM_READ_ONLY, RawParam};+pub(crate) use instance::{Instance, PARAM_BYPASS, PARAM_HIDDEN, PARAM_READ_ONLY, ProcessInput, RawParam}; #[cfg(test)] use instance::{apply_transport, split_state}; pub(crate) use module::{Bundle, exit_modules, hex};diff --git a/crates/vst3-host/src/ffi/editor.rs b/crates/vst3-host/src/ffi/editor.rs--- a/crates/vst3-host/src/ffi/editor.rs+++ b/crates/vst3-host/src/ffi/editor.rs@@ -1,5 +1,8 @@ use super::instance::Instance;-use super::*;+use super::{+    Class, ComPtr, ComWrapper, IComponentTrait, IEditControllerTrait, IPlugFrameTrait, IPlugViewTrait, Mutex, Ordering, PoisonError, STATE_MAGIC,+    c_void, ok, read_c16, sb, sv, window,+};  // ---- editor (IPlugView) -------------------------------------------------------------------- diff --git a/crates/vst3-host/src/ffi/host.rs b/crates/vst3-host/src/ffi/host.rs--- a/crates/vst3-host/src/ffi/host.rs+++ b/crates/vst3-host/src/ffi/host.rs@@ -1,5 +1,8 @@ use super::module::tuid_bytes;-use super::*;+use super::{+    AtomicBool, Class, ComWrapper, EDIT_CAP, FUnknown, IComponentHandlerTrait, IHostApplicationTrait, Interface, Mutex, Ordering, PoisonError,+    c_void, sb, sv, write_c16,+};  // ---- host-side COM objects ----------------------------------------------------------------- diff --git a/crates/vst3-host/src/ffi/instance.rs b/crates/vst3-host/src/ffi/instance.rs--- a/crates/vst3-host/src/ffi/instance.rs+++ b/crates/vst3-host/src/ffi/instance.rs@@ -2,7 +2,11 @@ use super::editor::EditorLink; use super::host::HostContext; use super::module::Bundle; use super::process::{BusBuffers, EventList, MemoryStream, NoteEvent, ParamChanges};-use super::*;+use super::{+    Arc, ComPtr, ComWrapper, EVENT_CAP, IAudioProcessorTrait, IComponentTrait, IConnectionPointTrait, IEditControllerTrait, IMidiMappingTrait,+    IPluginBaseTrait, MAX_BUS_CHANNELS, MAX_BUSES, MAX_PARAMS, MAX_STATE_BYTES, Mutex, Ordering, PARAM_QUEUE_CAP, PITCH_BEND, STATE_MAGIC, Transport,+    Vst3Error, ok, read_c16, sb, sv,+};  // ---- instances ----------------------------------------------------------------------------- @@ -32,7 +36,9 @@ pub(crate) struct Layout { }  pub(super) fn apply_transport(c: &mut sv::ProcessContext, t: &Transport) {-    use sv::ProcessContext_::StatesAndFlags_::*;+    use sv::ProcessContext_::StatesAndFlags_::{+        kBarPositionValid, kContTimeValid, kPlaying, kProjectTimeMusicValid, kRecording, kTempoValid, kTimeSigValid,+    };     let mut state = kTempoValid | kTimeSigValid | kProjectTimeMusicValid | kBarPositionValid | kContTimeValid;     if t.playing {         state |= kPlaying;@@ -375,18 +381,8 @@ impl Instance {     /// `controls` (time, id, value) one point at their time when it falls in this call (the last     /// one wins per parameter), and `notes` (sorted by time) have their times made relative to     /// `offset`.-    pub fn process(-        &mut self,-        frames: usize,-        inputs: &mut BusBuffers,-        outputs: &mut BusBuffers,-        params: &[(u32, f64)],-        controls: &[(u32, u32, f64)],-        notes: &[NoteEvent],-        offset: u32,-        project_time: i64,-        transport: Option<&Transport>,-    ) -> Result<(), Vst3Error> {+    pub fn process(&mut self, input: ProcessInput<'_>) -> Result<(), Vst3Error> {+        let ProcessInput { frames, inputs, outputs, params, controls, notes, offset, project_time, transport } = input;         if !self.active {             return Err(Vst3Error::Process("not active".into()));         }@@ -450,6 +446,18 @@ impl Instance {     } } +pub(crate) struct ProcessInput<'a> {+    pub frames: usize,+    pub inputs: &'a mut BusBuffers,+    pub outputs: &'a mut BusBuffers,+    pub params: &'a [(u32, f64)],+    pub controls: &'a [(u32, u32, f64)],+    pub notes: &'a [NoteEvent],+    pub offset: u32,+    pub project_time: i64,+    pub transport: Option<&'a Transport>,+}+ impl Drop for Instance {     fn drop(&mut self) {         // Close any editor and cut its handles off before the controller goes away.diff --git a/crates/vst3-host/src/ffi/module.rs b/crates/vst3-host/src/ffi/module.rs--- a/crates/vst3-host/src/ffi/module.rs+++ b/crates/vst3-host/src/ffi/module.rs@@ -2,7 +2,11 @@ use super::editor::{EditorInner, EditorLink}; use super::host::HostContext; use super::instance::Instance; use super::process::{EventList, ParamChanges};-use super::*;+use super::{+    Arc, AtomicBool, AtomicUsize, ComPtr, ComWrapper, Duration, EVENT_CAP, FUnknown, IComponentTrait, IConnectionPointTrait, IEditControllerTrait,+    IPluginBaseTrait, IPluginFactory2Trait, IPluginFactoryTrait, Interface, MAX_CLASSES, ManuallyDrop, Mutex, OnceLock, Ordering, PARAM_QUEUE_CAP,+    Path, PathBuf, PoisonError, TryLockError, Vst3Error, c_char, c_int, c_void, mpsc, ok, read_c8, sb, scan, sv,+};  // ---- loaded binaries ----------------------------------------------------------------------- diff --git a/crates/vst3-host/src/ffi/process.rs b/crates/vst3-host/src/ffi/process.rs--- a/crates/vst3-host/src/ffi/process.rs+++ b/crates/vst3-host/src/ffi/process.rs@@ -1,4 +1,7 @@-use super::*;+use super::{+    AtomicI32, AtomicU32, AtomicU64, Class, ComWrapper, IBStreamTrait, IEventListTrait, IParamValueQueueTrait, IParameterChangesTrait,+    MAX_BUS_CHANNELS, MAX_BUSES, MAX_STATE_BYTES, Mutex, Ordering, PoisonError, c_void, sb, sv,+};  /// One parameter's points for one block. SoundCraft sends at most one point per block; a /// plugin writing output changes may add more, of which only the last is kept.diff --git a/crates/vst3-host/src/plugin.rs b/crates/vst3-host/src/plugin.rs--- a/crates/vst3-host/src/plugin.rs+++ b/crates/vst3-host/src/plugin.rs@@ -1,6 +1,6 @@ //! `Vst3Plugin`: a loaded VST3 instance behind the safe `soundcraft_dsp::Plugin` trait. -use crate::ffi::{AFTERTOUCH, BusBuffers, EVENT_CAP, EditorLink, HostContext, Instance, NoteEvent, PARAM_QUEUE_CAP, PITCH_BEND};+use crate::ffi::{AFTERTOUCH, BusBuffers, EVENT_CAP, EditorLink, HostContext, Instance, NoteEvent, PARAM_QUEUE_CAP, PITCH_BEND, ProcessInput}; use soundcraft_dsp::{Plugin, PluginEditor, PluginInfo, Transport, Unit}; use std::collections::HashMap; use std::sync::Arc;@@ -324,17 +324,17 @@ impl Plugin for Vst3Plugin {             let k = self.notes.iter().position(|e| e.time() >= end).unwrap_or(self.notes.len());             let offset = u32::try_from(start).unwrap_or(u32::MAX);             let notes = self.notes.get(..k).unwrap_or(&[]);-            let r = self.inst.process(-                n,-                &mut self.inputs,-                &mut self.outputs,-                &self.pending,-                &self.controls,+            let r = self.inst.process(ProcessInput {+                frames: n,+                inputs: &mut self.inputs,+                outputs: &mut self.outputs,+                params: &self.pending,+                controls: &self.controls,                 notes,                 offset,-                self.position,-                self.transport.as_ref(),-            );+                project_time: self.position,+                transport: self.transport.as_ref(),+            });             self.pending.clear();             self.notes.drain(..k);             self.position = self.position.saturating_add(i64::try_from(n).unwrap_or(0));