Skip to main content

Crate nice_plug

Crate nice_plug 

Source
Expand description

Documentation is still a work in progress. The best way to learn right now is to browse through the examples and to browse through these docs. There is no full guide yet, but here are some pointers to get started:

  • All useful functionality is exported through the prelude module. Add use nice_plug::prelude::*; to the top of your lib.rs file to get started.

  • Make sure to check out the macros from the debug module. These should be used instead of, println!()/eprint!(), dbg!() and similar macros, and they are re-exported from the prelude. nice-plug sets up a flexible logger for you that all of these functions will output to. By default, the output is logged to STDERR unless you’re running Windows and a Windows debugger is attached, in which case the output is logged to the debug console instead. The NICE_LOG environment variable controls whether output is logged to STDERR, the Windows debug console, or to a file. Check the nice_log!() macro for more information.

  • The aforementioned debug module also contains non-fatal debug-assertions macros that are only evaluated during debug builds. The framework uses these all over the place to check for invariants, so it’s important to test your plugins using debug builds while developing.

  • Check out the features list in nice-plug’s Cargo.toml file for optional features you can enable. This includes things like SIMD support for the buffer adapters and panicking on allocations during DSP code in debug mode.

  • An nice-plug plugin consists of an implementation of the Plugin trait and a call to nice_export_vst3!() and/or nice_export_clap!() in your lib.rs file to expose the plugin functionality. Some of these traits will require you to implement an additional trait containing API-specific information for the plugin.

    Check the Plugin trait’s documentation for more information on nice-plug’s general structure and approach with respect to declarativity.

  • nice-plug comes with a bundler that creates plugin bundles for you based on the exported plugin formats and the operating system and architecture you’re compiling for. Check out the readme for nice-plug-xtask for instructions on how to use this within your own project.

  • It’s also possible to export a standalone application from a plugin using the nice_export_standalone() function. Check that function’s documentation to learn how to do this. This requires enabling the standalone crate feature.

  • Everything is described in more detail on the Plugin trait and everything linked from there, but a plugin’s general lifecycle involves the following function calls.

    1. When the host loads the plugin, your plugin object will be instantiated using its Default implementation. The plugin should refrain from performing expensive calculations or IO at this point.

    2. The host will select an audio IO layout from Plugin::AUDIO_IO_LAYOUTS. The first layout is always used as the default one, and should reflect the plugin’s most commonly used configuration. Usually this is a stereo layout.

    3. After that, Plugin::initialize() will be called with the the selected IO configuration and the audio buffer settings. Here you should allocate any data structures you need or precompute data that depends on the sample rate or maximum buffer size. This is the only place where you can safely allocate memory.

    4. The Plugin::reset() function is always called immediately after initialize(). This is where you should clear out coefficients, envelopes, phases, and other runtime data. The reason for this split is that this function may be called at any time by the host from the audio thread, and it thus needs to be realtime-safe.

      Whenever a preset is loaded, both of these functions will be called again.

    5. After that the Plugin::process() function will be called repeatedly until the plugin is deactivated. Here the plugin receives a Buffer object that contains the input audio (if the plugin has inputs) which the plugin should overwrite with output audio. Check the documentation on the Buffer object for all of the ways you can use this API. You can access note events, transport data, and more through the ProcessContext that’s also passed to the process function.

    6. Plugin::deactivate() is called from the when the plugin gets deactivated. You probably don’t need to do anything here, but you could deallocate or clean up resources here.

  • Plugin parameters are managed automatically by creating a struct deriving the Params trait and returning a handle to it from the Plugin::params() function. Any FloatParam, IntParam, BoolParam or EnumParam fields on that struct will automatically be registered as a parameter if they have an #[id = "foobar"] attribute. The string "foobar" here uniquely identifies the parameter, making it possible to reorder and rename parameters as long as this string stays constant. You can also store persistent non-parameter data and other parameter objects in a Params struct. Check out the trait’s documentation for details on all supported features, and also be sure to take a look at the example plugins.

  • After calling .with_smoother() during an integer or floating point parameter’s creation, you can use param.smoothed to access smoothed values for that parameter. Be sure to check out the Smoother API for more details.

There’s a whole lot more to discuss, but once you understand the above you should be able to figure out the rest by reading through the examples and the API documentation. Good luck!

Re-exports§

pub use wrapper::standalone::nice_export_standalone;

Modules§

audio_setup
Types and definitions surrounding a plugin’s audio IO setup.
buffer
Adapters and utilities for working with audio buffers.
context
Different contexts the plugin can use to make callbacks to the host in different…contexts.
debug
Macros for logging and debug assertions. nice_dbg!(), nice_trace!(), and the nice_debug_assert_*!() macros are compiled out during release builds, so they can be used for asserting adiditonal invariants in debug builds. Check the nice_log!() macro for more information on nice-plug’s logger. None of the logging functions are realtime-safe, and you should avoid using them during release builds in any of the functions that may be called from an audio thread.
editor
Traits for working with plugin editors.
formatters
Convenience functions for formatting and parsing parameter values in various common formats.
log
A lightweight logging facade.
midi
Constants and definitions surrounding MIDI support.
params
nice-plug can handle floating point, integer, boolean, and enum parameters. Parameters are managed by creating a struct deriving the Params trait containing fields for those parameter types, and then returning a reference to that object from your Plugin::params() method. See the Params trait for more information.
plugin
Traits and structs describing plugins and editors. This includes extension structs for features that are specific to one or more plugin-APIs.
prelude
Everything you’ll need to use nice-plug. Import this with use nice_plug::prelude::*;.
util
General conversion functions and utilities.
wrapper
Wrappers for different plugin types. Each wrapper has an entry point macro that you can pass the name of a type that implements Plugin to. The macro will handle the rest.

Macros§

nice_dbg
Analogues to the dbg!() macro, but respecting the NICE_LOG environment variable and with all of the same logging features as the other nice_*!() macros. Like the nice_debug_assert*!() macros, this is only shown when compiling in debug mode, but the macro will still return the value in non-debug modes.
nice_debug_assert
A debug_assert!() analogue that prints the error with line number information instead of panicking. During tests this is upgraded to a regular panicking debug_assert!().
nice_debug_assert_eq
A debug_assert_eq!() analogue that prints the error with line number information instead of panicking. See nice_debug_assert!() for more information.
nice_debug_assert_failure
An unconditional debug assertion failure, for if the condition has already been checked elsewhere. See nice_debug_assert!() for more information.
nice_debug_assert_ne
A debug_assert_ne!() analogue that prints the error with line number information instead of panicking. See nice_debug_assert!() for more information.
nice_error
Similar to nice_log!(), but more scream-y. Used for printing fatal errors.
nice_export_clap
Export one or more CLAP plugins from this library using the provided plugin types.
nice_export_vst3
Export one or more VST3 plugins from this library using the provided plugin types. The first plugin’s vendor information is used for the factory’s information.
nice_log
Write something to the logger. This defaults to STDERR unless the user is running Windows and a debugger has been attached, in which case OutputDebugString() will be used instead.
nice_trace
The same as nice_log!(), but with source and thread information. Like the nice_debug_assert*!() macros, this is only shown when compiling in debug mode.
nice_warn
Similar to nice_log!(), but less subtle. Used for printing warnings.