chore: scaffold minimal NIH-plug template

Based on musiikki/codename-206 patterns. Provides a clean, minimal
skeleton for new nih-plug audio plugins:

- Cargo.toml with pinned NIH-plug deps (same rev as codename-206)
- src/lib.rs — skeleton plugin with Params, Plugin impl, CLAP/VST3
- xtask/ — bundler xtask (cargo xtask bundle)
- bundler.toml — placeholder for bundle name
- .cargo/config.toml — xtask alias
- .gitignore — /target, /nih-plug, /_template
- LICENSE — Apache-2.0
- README.md — build and deploy instructions
This commit is contained in:
2026-08-21 13:07:09 +09:00
parent b0e1bee433
commit 4700376bc8
7 changed files with 193 additions and 17 deletions
+2
View File
@@ -0,0 +1,2 @@
[alias]
xtask = "run --package xtask --release --"
+6 -17
View File
@@ -1,18 +1,7 @@
# ---> Rust /target
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# These are backup files generated by rustfmt # Local NIH-plug reference clone ("deluxe kit") and cookiecutter template.
**/*.rs.bk # Kept out of version control; the build depends on nih-plug via a pinned git rev,
# not on these working copies. Clone them locally for reading the examples.
# MSVC Windows builds of rustc generate these, which store debugging information /nih-plug
*.pdb /_template
# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
+30
View File
@@ -0,0 +1,30 @@
[package]
name = "nih_plug_template"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <your@email.com>"]
homepage = "https://github.com/YOUR-USERNAME/YOUR-PLUGIN-NAME"
description = "A minimal NIH-plug audio plugin"
license = "Apache-2.0"
[workspace]
members = ["xtask"]
[lib]
# `cdylib` is the plugin binary; `lib` (rlib) lets `cargo test` link the unit tests.
crate-type = ["cdylib", "lib"]
[dependencies]
# Pinned to the same commit as musiikki/codename-206.
# Update the `rev` when you want to update NIH-plug.
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23", features = ["assert_process_allocs"] }
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23" }
[profile.release]
lto = "thin"
strip = "symbols"
[profile.profiling]
inherits = "release"
debug = true
strip = "none"
+7
View File
@@ -0,0 +1,7 @@
# Metadata for NIH-plug's `cargo xtask bundle <package>` bundler.
#
# [package_name]
# name = "Human Readable Plugin Name" # defaults to <package_name>
[nih_plug_template]
name = "Plugin Name"
+136
View File
@@ -0,0 +1,136 @@
// SPDX-License-Identifier: Apache-2.0
use nih_plug::prelude::*;
use std::sync::Arc;
// ──────────────────────────────────────────────
// Params — add your plugin parameters here.
// See musiikki/codename-206/src/params.rs for a real example.
// ──────────────────────────────────────────────
struct PluginParams;
impl Params for PluginParams {
fn as_slice(&self) -> &[AtomicParam] {
&[]
}
fn as_mut_slice(&mut self) -> &mut [AtomicParam] {
&mut []
}
fn param_by_id(&self, _id: ParamId) -> Option<&AtomicParam> {
None
}
fn param_by_id_mut(&mut self, _id: ParamId) -> Option<&mut AtomicParam> {
None
}
fn param_by_name(&self, _name: &str) -> Option<&AtomicParam> {
None
}
fn param_by_name_mut(&mut self, _name: &str) -> Option<&mut AtomicParam> {
None
}
}
// ──────────────────────────────────────────────
// Plugin
// ──────────────────────────────────────────────
struct MyPlugin {
params: Arc<PluginParams>,
}
impl Default for MyPlugin {
fn default() -> Self {
Self {
params: Arc::new(PluginParams),
}
}
}
impl Plugin for MyPlugin {
// TODO: Replace these placeholder values with your plugin's metadata.
const NAME: &'static str = "Plugin Name";
const VENDOR: &'static str = "Your Name";
const URL: &'static str = env!("CARGO_PKG_HOMEPAGE");
const EMAIL: &'static str = "your@email.com";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[
AudioIOLayout {
main_input_channels: NonZeroU32::new(2),
main_output_channels: NonZeroU32::new(2),
..AudioIOLayout::const_default()
},
];
const MIDI_INPUT: MidiConfig = MidiConfig::None;
const MIDI_OUTPUT: MidiConfig = MidiConfig::None;
const SAMPLE_ACCURATE_AUTOMATION: bool = true;
type SysSysexMessage = ();
type BackgroundTask = ();
fn params(&self) -> Arc<dyn Params> {
self.params.clone()
}
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
// TODO: Implement your egui editor here.
// return Some(Box::new(MyEditor::new(self.params.clone())));
None
}
fn initialize(
&mut self,
_audio_io_layout: &AudioIOLayout,
_buffer_config: &BufferConfig,
_context: &mut impl InitContext<Self>,
) -> bool {
true
}
fn reset(&mut self) {}
fn process(
&mut self,
buffer: &mut Buffer,
_aux: &mut AuxiliaryBuffers,
_context: &mut impl ProcessContext<Self>,
) -> ProcessStatus {
// TODO: Implement your DSP here.
// This is a passthrough — replace with your audio processing.
for mut frame in buffer.iter_samples() {
for ch in 0..frame.len() {
*frame.get_mut(ch).unwrap() = *frame.get(ch).unwrap();
}
}
ProcessStatus::Normal
}
}
impl ClapPlugin for MyPlugin {
// TODO: Replace with a unique CLAP ID, e.g. "com.your-domain.your-plugin-name"
const CLAP_ID: &'static str = "com.your-domain.plugin-name";
const CLAP_DESCRIPTION: Option<&'static str> = Some("Your plugin description");
const CLAP_MANUAL_URL: Option<&'static str> = Some(Self::URL);
const CLAP_SUPPORT_URL: Option<&'static str> = None;
const CLAP_FEATURES: &'static [ClapFeature] = &[ClapFeature::AudioEffect];
}
impl Vst3Plugin for MyPlugin {
// TODO: Replace with a unique 16-byte Class ID.
// Must be exactly 16 bytes — padded with '!' if shorter.
const VST3_CLASS_ID: [u8; 16] = *b"Unique16CharId!!";
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
&[Vst3SubCategory::Fx];
}
nih_export_clap!(MyPlugin);
nih_export_vst3!(MyPlugin);
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"
[dependencies]
nih_plug_xtask = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23" }
+5
View File
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
fn main() -> nih_plug_xtask::Result<()> {
nih_plug_xtask::main()
}