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:
+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);
|
||||
Reference in New Issue
Block a user