2022-02-06 03:13:07 +11:00
|
|
|
# NIH-plug
|
|
|
|
|
2022-04-12 00:10:16 +10:00
|
|
|
[![Automated builds](https://github.com/robbert-vdh/nih-plug/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/robbert-vdh/nih-plug/actions/workflows/build.yml?query=branch%3Amaster)
|
2022-03-08 05:57:47 +11:00
|
|
|
[![Tests](https://github.com/robbert-vdh/nih-plug/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/robbert-vdh/nih-plug/actions/workflows/test.yml?query=branch%3Amaster)
|
2022-04-30 02:28:40 +10:00
|
|
|
[![Docs](https://github.com/robbert-vdh/nih-plug/actions/workflows/docs.yml/badge.svg?branch=master)](https://nih-plug.robbertvanderhelm.nl/)
|
2022-01-25 03:32:27 +11:00
|
|
|
|
2022-09-24 00:11:17 +10:00
|
|
|
NIH-plug is an API-agnostic audio plugin framework written in Rust, as well as a
|
|
|
|
small collection of plugins. The idea is to have a stateful yet simple plugin
|
|
|
|
API that gets rid of as much unnecessary ceremony wherever possible, while also
|
|
|
|
keeping the amount of magic to minimum and making it easy to experiment with
|
|
|
|
different approaches to things. See the [current features](#current-features)
|
|
|
|
section for more information on the project's current status.
|
2022-01-29 01:02:55 +11:00
|
|
|
|
2022-08-31 09:35:25 +10:00
|
|
|
Come join us on the [Rust Audio Discord](https://discord.gg/ykxU3rt4Cb), check
|
2022-09-24 00:11:17 +10:00
|
|
|
out the [documentation](https://nih-plug.robbertvanderhelm.nl/), or use the
|
2022-08-31 09:35:25 +10:00
|
|
|
[cookiecutter template](https://github.com/robbert-vdh/nih-plug-template) to
|
|
|
|
quickly get started with NIH-plug.
|
2022-03-02 04:48:00 +11:00
|
|
|
|
2022-02-13 02:27:57 +11:00
|
|
|
### Table of contents
|
|
|
|
|
2022-02-14 04:42:05 +11:00
|
|
|
- [Plugins](#plugins)
|
|
|
|
- [Framework](#framework)
|
2022-03-17 01:29:39 +11:00
|
|
|
- [Current features](#current-features)
|
2022-02-14 04:42:05 +11:00
|
|
|
- [Building](#building)
|
2022-02-28 23:47:45 +11:00
|
|
|
- [Plugin formats](#plugin-formats)
|
2022-02-14 04:42:05 +11:00
|
|
|
- [Example plugins](#example-plugins)
|
2022-02-13 02:27:57 +11:00
|
|
|
- [Licensing](#licensing)
|
|
|
|
|
|
|
|
## Plugins
|
|
|
|
|
2022-09-24 00:11:17 +10:00
|
|
|
Check each plugin's readme file for more details on what the plugin actually
|
|
|
|
does. You can download the development binaries for Linux, Windows and macOS
|
|
|
|
from the [automated
|
2022-06-10 23:59:18 +10:00
|
|
|
builds](https://github.com/robbert-vdh/nih-plug/actions/workflows/build.yml?query=branch%3Amaster)
|
2022-05-25 07:56:21 +10:00
|
|
|
page. Or if you're not signed in on GitHub, then you can also find the latest
|
2022-09-24 00:11:17 +10:00
|
|
|
nightly build
|
|
|
|
[here](https://nightly.link/robbert-vdh/nih-plug/workflows/build/master). You
|
2022-09-29 11:34:59 +10:00
|
|
|
may need to [disable Gatekeeper](https://disable-gatekeeper.github.io/) on macOS to be able to use
|
2022-09-24 00:11:17 +10:00
|
|
|
the plugins.
|
2022-05-25 07:56:21 +10:00
|
|
|
|
2022-09-24 00:11:17 +10:00
|
|
|
Scroll down for more information on the underlying plugin framework.
|
2022-02-13 02:27:57 +11:00
|
|
|
|
2022-11-10 01:47:26 +11:00
|
|
|
- [**Buffr Glitch**](plugins/buffr_glitch) is the plugin for you if you enjoy
|
|
|
|
the sound of a CD player skipping This plugin is essentially a MIDI triggered
|
|
|
|
buffer repeat plugin. When you play a note, the plugin will sample the period
|
|
|
|
corresponding to that note's frequency and use that as a single waveform
|
|
|
|
cycle. This can end up sounding like an in-tune glitch when used sparingly, or
|
|
|
|
like a weird synthesizer when used less subtly.
|
2022-03-09 03:41:23 +11:00
|
|
|
- [**Crisp**](plugins/crisp) adds a bright crispy top end to any low bass sound.
|
|
|
|
Inspired by Polarity's [Fake Distortion](https://youtu.be/MKfFn4L1zeg) video.
|
2022-07-23 02:46:34 +10:00
|
|
|
- [**Crossover**](plugins/crossover) is as boring as it sounds. It cleanly
|
|
|
|
splits the signal into two to five bands using a variety of algorithms. Those
|
|
|
|
bands are then sent to auxiliary outputs so they can be accessed and processed
|
|
|
|
individually. Meant as an alternative to Bitwig's Multiband FX devices but
|
|
|
|
with cleaner crossovers and a linear-phase option.
|
2022-02-13 03:27:23 +11:00
|
|
|
- [**Diopser**](plugins/diopser) is a totally original phase rotation plugin.
|
2022-02-13 02:27:57 +11:00
|
|
|
Useful for oomphing up kickdrums and basses, transforming synths into their
|
|
|
|
evil phase-y cousin, and making everything sound like a cheap Sci-Fi laser
|
2022-02-15 10:00:41 +11:00
|
|
|
beam.
|
2022-04-27 23:37:17 +10:00
|
|
|
- [**Loudness War Winner**](plugins/loudness_war_winner) does what it says on
|
|
|
|
the tin. Have you ever wanted to show off your dominance by winning the
|
|
|
|
loudness war? Neither have I. Dissatisfaction guaranteed.
|
2022-03-08 06:08:47 +11:00
|
|
|
- [**Puberty Simulator**](plugins/puberty_simulator) is that patent pending One
|
|
|
|
Weird Plugin that simulates the male voice change during puberty! If it was
|
|
|
|
not already obvious from that sentence, this plugin is a joke, but it might
|
2022-03-08 05:51:38 +11:00
|
|
|
actually be useful (or at least interesting) in some situations. This plugin
|
|
|
|
pitches the signal down an octave, but it also has the side effect of causing
|
2022-03-08 06:08:47 +11:00
|
|
|
things to sound like a cracking voice or to make them sound slightly out of
|
|
|
|
tune.
|
2022-05-25 07:57:11 +10:00
|
|
|
- [**Safety Limiter**](plugins/safety_limiter) is a simple tool to prevent ear
|
|
|
|
damage. As soon as there is a peak above 0 dBFS or the specified threshold,
|
|
|
|
the plugin will cut over to playing SOS in Morse code, gradually fading out
|
|
|
|
again when the input returns back to safe levels. Made for personal use during
|
|
|
|
plugin development and intense sound design sessions, but maybe you'll find it
|
|
|
|
useful too!
|
2023-04-06 04:07:13 +10:00
|
|
|
- [**Soft Vacuum**](plugins/soft_vacuum) is a straightforward port of
|
2023-04-03 01:23:16 +10:00
|
|
|
Airwindows' [Hard Vacuum](https://www.airwindows.com/hard-vacuum-vst/) plugin
|
2023-04-07 21:18:13 +10:00
|
|
|
with parameter smoothing and up to 16x linear-phase oversampling, because I
|
|
|
|
liked the distortion and just wished it had oversampling. All credit goes to
|
|
|
|
Chris from Airwindows. I just wanted to share this in case anyone else finds
|
|
|
|
it useful.
|
2022-07-14 06:27:56 +10:00
|
|
|
- [**Spectral Compressor**](plugins/spectral_compressor) can squash anything
|
|
|
|
into pink noise, apply simultaneous upwards and downwards compressor to
|
2022-07-26 00:35:34 +10:00
|
|
|
dynamically match the sidechain signal's spectrum and morph one sound into
|
|
|
|
another, and lots more. Have you ever wondered what a 16384 band OTT would
|
|
|
|
sound like? Neither have I.
|
2022-02-13 02:27:57 +11:00
|
|
|
|
|
|
|
## Framework
|
|
|
|
|
2022-03-17 01:29:39 +11:00
|
|
|
### Current features
|
2022-02-07 04:31:49 +11:00
|
|
|
|
2022-03-17 01:29:39 +11:00
|
|
|
- Supports both VST3 and [CLAP](https://github.com/free-audio/clap) by simply
|
|
|
|
adding the corresponding `nih_export_<api>!(Foo)` macro to your plugin's
|
|
|
|
library.
|
2022-04-23 01:00:59 +10:00
|
|
|
- Standalone binaries can be made by calling `nih_export_standalone(Foo)` from
|
2022-06-15 09:01:57 +10:00
|
|
|
your `main()` function. Standalones come with a CLI for configuration and full
|
|
|
|
JACK audio, MIDI, and transport support.
|
2022-10-22 10:15:16 +11:00
|
|
|
- Rich declarative parameter system without any boilerplate.
|
2022-03-17 01:29:39 +11:00
|
|
|
- Define parameters for your plugin by adding `FloatParam`, `IntParam`,
|
|
|
|
`BoolParam`, and `EnumParam<T>` fields to your parameter struct, assign
|
|
|
|
stable IDs to them with the `#[id = "foobar"]`, and a `#[derive(Params)]`
|
|
|
|
does all of the boring work for you.
|
|
|
|
- Parameters can have complex value distributions and the parameter objects
|
|
|
|
come with built-in smoothers and callbacks.
|
|
|
|
- Use simple enums deriving the `Enum` trait with the `EnumParam<T>` parameter
|
|
|
|
type for parameters that allow the user to choose between multiple discrete
|
|
|
|
options. That way you can use regular Rust pattern matching when working
|
|
|
|
with these values without having to do any conversions yourself.
|
|
|
|
- Store additional non-parameter state for your plugin by adding any field
|
2022-03-17 03:04:38 +11:00
|
|
|
that can be serialized with [Serde](https://serde.rs/) to your plugin's
|
2022-03-17 01:29:39 +11:00
|
|
|
`Params` object and annotating them with `#[persist = "key"]`.
|
2022-10-22 08:23:13 +11:00
|
|
|
- Optional support for state migrations, for handling breaking changes in
|
|
|
|
plugin parameters.
|
2022-03-17 01:29:39 +11:00
|
|
|
- Group your parameters into logical groups by nesting `Params` objects using
|
2022-10-13 10:20:56 +11:00
|
|
|
the `#[nested(group = "...")]`attribute.
|
|
|
|
- The `#[nested]` attribute also enables you to use multiple copies of the
|
|
|
|
same parameter, either as regular object fields or through arrays.
|
2022-03-24 03:36:58 +11:00
|
|
|
- When needed, you can also provide your own implementation for the `Params`
|
2022-10-13 10:20:56 +11:00
|
|
|
trait to enable compile time generated parameters and other bespoke
|
|
|
|
functionality.
|
2022-03-17 01:29:39 +11:00
|
|
|
- Stateful. Behaves mostly like JUCE, just without all of the boilerplate.
|
2022-10-22 10:15:16 +11:00
|
|
|
- Comes with a simple yet powerful way to asynchronously run background tasks
|
|
|
|
from a plugin that's both type-safe and realtime-safe.
|
2022-03-17 01:29:39 +11:00
|
|
|
- Does not make any assumptions on how you want to process audio, but does come
|
|
|
|
with utilities and adapters to help with common access patterns.
|
|
|
|
- Efficiently iterate over an audio buffer either per-sample per-channel,
|
|
|
|
per-block per-channel, or even per-block per-sample-per-channel with the
|
|
|
|
option to manually index the buffer or get access to a channel slice at any
|
|
|
|
time.
|
|
|
|
- Easily leverage per-channel SIMD using the SIMD adapters on the buffer and
|
|
|
|
block iterators.
|
|
|
|
- Comes with bring-your-own-FFT adapters for common (inverse) short-time
|
|
|
|
Fourier Transform operations. More to come.
|
|
|
|
- Optional sample accurate automation support for VST3 and CLAP that can be
|
|
|
|
enabled by setting the `Plugin::SAMPLE_ACCURATE_AUTOMATION` constant to
|
|
|
|
`true`.
|
2022-07-07 03:44:03 +10:00
|
|
|
- Support for CLAP's polyphonic modulation on a per-parameter basis.
|
2022-08-18 21:55:31 +10:00
|
|
|
- Optional support for compressing the human readable JSON state files using
|
|
|
|
[Zstandard](https://en.wikipedia.org/wiki/Zstd).
|
2022-03-17 01:29:39 +11:00
|
|
|
- Comes with adapters for popular Rust GUI frameworks as well as some basic
|
|
|
|
widgets for them that integrate with NIH-plug's parameter system. Currently
|
2022-03-18 09:14:45 +11:00
|
|
|
there's support for [egui](nih_plug_egui), [iced](nih_plug_iced) and
|
|
|
|
[VIZIA](nih_plug_vizia).
|
2022-04-08 01:42:52 +10:00
|
|
|
- A simple and safe API for state saving and restoring from the editor is
|
|
|
|
provided by the framework if you want to do your own internal preset
|
|
|
|
management.
|
2022-04-12 03:52:51 +10:00
|
|
|
- Full support for receiving and outputting both modern polyphonic note
|
|
|
|
expression events as well as MIDI CCs, channel pressure, and pitch bend for
|
|
|
|
CLAP and VST3.
|
2023-02-01 03:58:54 +11:00
|
|
|
- MIDI SysEx is also supported. Plugins can define their own structs or sum
|
|
|
|
types to wrap around those messages so they don't need to interact with raw
|
|
|
|
byte buffers in the process function.
|
2023-02-21 02:57:32 +11:00
|
|
|
- Support for flexible dynamic buffer configurations, including variable numbers
|
|
|
|
of input and output ports.
|
2022-03-17 01:29:39 +11:00
|
|
|
- A plugin bundler accessible through the
|
2022-04-06 00:42:41 +10:00
|
|
|
`cargo xtask bundle <package> <build_arguments>` command that automatically
|
|
|
|
detects which plugin targets your plugin exposes and creates the correct
|
|
|
|
plugin bundles for your target operating system and architecture, with
|
|
|
|
cross-compilation support. The cargo subcommand can easily be added to [your
|
|
|
|
own project](https://github.com/robbert-vdh/nih-plug/tree/master/nih_plug_xtask)
|
|
|
|
as an alias or [globally](https://github.com/robbert-vdh/nih-plug/tree/master/cargo_nih_plug)
|
2022-03-17 01:29:39 +11:00
|
|
|
as a regular cargo subcommand.
|
2022-04-06 00:42:41 +10:00
|
|
|
- Tested on Linux and Windows, with limited testing on macOS. Windows support
|
|
|
|
has mostly been tested through Wine with
|
2022-03-17 01:29:39 +11:00
|
|
|
[yabridge](https://github.com/robbert-vdh/yabridge).
|
|
|
|
- See the [`Plugin`](src/plugin.rs) trait's documentation for an incomplete list
|
2022-09-04 12:40:11 +10:00
|
|
|
of the functionality that has currently not yet been implemented.
|
2022-02-07 04:31:49 +11:00
|
|
|
|
2022-02-13 02:27:57 +11:00
|
|
|
### Building
|
2022-01-30 04:38:09 +11:00
|
|
|
|
2022-02-13 02:27:57 +11:00
|
|
|
NIH-plug works with the latest stable Rust compiler.
|
2022-02-06 03:14:28 +11:00
|
|
|
|
2022-02-16 04:30:45 +11:00
|
|
|
After installing [Rust](https://rustup.rs/), you can compile any of the plugins
|
2022-01-30 04:38:09 +11:00
|
|
|
in the `plugins` directory in the following way, replacing `gain` with the name
|
|
|
|
of the plugin:
|
|
|
|
|
|
|
|
```shell
|
2022-02-27 06:12:08 +11:00
|
|
|
cargo xtask bundle gain --release
|
2022-01-30 04:38:09 +11:00
|
|
|
```
|
|
|
|
|
2022-02-28 23:47:45 +11:00
|
|
|
### Plugin formats
|
|
|
|
|
2022-03-04 04:31:27 +11:00
|
|
|
NIH-plug can currently export VST3 and
|
|
|
|
[CLAP](https://github.com/free-audio/clap) plugins. Exporting a specific plugin
|
|
|
|
format for a plugin is as simple as calling the `nih_export_<format>!(Foo);`
|
2022-06-15 23:35:20 +10:00
|
|
|
macro. The `cargo xtask bundle` command will detect which plugin formats your
|
2022-03-04 04:31:27 +11:00
|
|
|
plugin supports and create the appropriate bundles accordingly, even when cross
|
|
|
|
compiling.
|
2022-02-28 23:47:45 +11:00
|
|
|
|
2022-02-13 02:27:57 +11:00
|
|
|
### Example plugins
|
2022-02-04 12:57:29 +11:00
|
|
|
|
|
|
|
The best way to get an idea for what the API looks like is to look at the
|
|
|
|
examples.
|
|
|
|
|
2022-02-14 07:04:07 +11:00
|
|
|
- [**gain**](plugins/examples/gain) is a simple smoothed gain plugin that shows
|
|
|
|
off a couple other parts of the API, like support for storing arbitrary
|
|
|
|
serializable state.
|
2022-03-18 09:20:16 +11:00
|
|
|
- **gain-gui** is the same plugin as gain, but with a GUI to control the
|
|
|
|
parameter and a digital peak meter. Comes in three exciting flavors:
|
2022-04-15 07:53:14 +10:00
|
|
|
[egui](plugins/examples/gain_gui_egui),
|
|
|
|
[iced](plugins/examples/gain_gui_iced), and
|
|
|
|
[VIZIA](plugins/examples/gain_gui_vizia).
|
2022-07-06 21:55:53 +10:00
|
|
|
- [**midi_inverter**](plugins/examples/midi_inverter) takes note/MIDI events and
|
2022-04-12 04:47:00 +10:00
|
|
|
flips around the note, channel, expression, pressure, and CC values. This
|
|
|
|
example demonstrates how to receive and output those events.
|
2022-07-06 21:55:53 +10:00
|
|
|
- [**poly_mod_synth**](plugins/examples/poly_mod_synth) is a simple polyphonic
|
|
|
|
synthesizer with support for polyphonic modulation in supported CLAP hosts.
|
|
|
|
This demonstrates how polyphonic modulation can be used in NIH-plug.
|
2022-02-14 07:04:07 +11:00
|
|
|
- [**sine**](plugins/examples/sine) is a simple test tone generator plugin with
|
|
|
|
frequency smoothing that can also make use of MIDI input instead of generating
|
|
|
|
a static signal based on the plugin's parameters.
|
2022-03-06 12:07:53 +11:00
|
|
|
- [**stft**](plugins/examples/stft) shows off some of NIH-plug's other optional
|
2022-03-07 04:54:18 +11:00
|
|
|
higher level helper features, such as an adapter to process audio with a
|
|
|
|
short-term Fourier transform using the overlap-add method, all using the
|
|
|
|
compositional `Buffer` interfaces.
|
2023-02-02 00:52:01 +11:00
|
|
|
- [**sysex**](plugins/examples/sysex) is a simple example of how to send and
|
|
|
|
receive SysEx messages by defining custom message types.
|
2022-02-04 12:57:29 +11:00
|
|
|
|
2022-01-29 01:02:55 +11:00
|
|
|
## Licensing
|
|
|
|
|
2022-02-14 06:10:43 +11:00
|
|
|
The framework, its libraries, and the example plugins in `plugins/examples/` are
|
|
|
|
all licensed under the [ISC license](https://www.isc.org/licenses/). However,
|
|
|
|
the [VST3 bindings](https://github.com/RustAudio/vst3-sys) used by
|
|
|
|
`nih_export_vst3!()` are licensed under the GPLv3 license. This means that
|
|
|
|
unless you replace these bindings with your own bindings made from scratch, any
|
|
|
|
VST3 plugins built with NIH-plug need to be able to comply with the terms of the
|
|
|
|
GPLv3 license.
|
|
|
|
|
|
|
|
The other plugins in the `plugins/` directory may be licensed under the GPLv3
|
|
|
|
license. Check the plugin's `Cargo.toml` file for more information.
|