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:
@@ -0,0 +1,2 @@
|
||||
[alias]
|
||||
xtask = "run --package xtask --release --"
|
||||
+6
-17
@@ -1,18 +1,7 @@
|
||||
# ---> Rust
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
/target
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# 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/
|
||||
# Local NIH-plug reference clone ("deluxe kit") and cookiecutter template.
|
||||
# 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.
|
||||
/nih-plug
|
||||
/_template
|
||||
|
||||
+30
@@ -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"
|
||||
@@ -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
@@ -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);
|
||||
@@ -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" }
|
||||
@@ -0,0 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
fn main() -> nih_plug_xtask::Result<()> {
|
||||
nih_plug_xtask::main()
|
||||
}
|
||||
Reference in New Issue
Block a user