Replace VST3 category string with enum slice
I've been putting this off for a while, but now is finally the day. We already did this for CLAP a while back. This is both simpler and less error prone.
This commit is contained in:
parent
7fe339987a
commit
d6184ea06e
|
@ -6,6 +6,14 @@ new and what's changed, this document lists all breaking changes in reverse
|
|||
chronological order. If a new feature did not require any changes to existing
|
||||
code then it will not be listed here.
|
||||
|
||||
## [2023-02-01]
|
||||
|
||||
- The `Vst3Plugin::VST3_CATEGORIES` string constant has been replaced by a
|
||||
`Vst3Plugin::VST3_SUBCATEGORIES` constant of type `&[Vst3SubCategory]`.
|
||||
`Vst3SubCategory` is an enum containing all of VST3's predefined categories,
|
||||
and it behaves similarly to the `ClapFeature` enum used for CLAP plugins. This
|
||||
makes defining subcategories for VST3 plugins easier and less error prone.
|
||||
|
||||
## [2023-01-31]
|
||||
|
||||
- NIH-plug has gained support MIDI SysEx in a simple, type-safe, and
|
||||
|
|
|
@ -431,6 +431,7 @@ impl ClapPlugin for BuffrGlitch {
|
|||
const CLAP_SUPPORT_URL: Option<&'static str> = None;
|
||||
const CLAP_FEATURES: &'static [ClapFeature] = &[
|
||||
ClapFeature::AudioEffect,
|
||||
ClapFeature::Synthesizer,
|
||||
ClapFeature::Stereo,
|
||||
ClapFeature::Glitch,
|
||||
];
|
||||
|
@ -438,7 +439,11 @@ impl ClapPlugin for BuffrGlitch {
|
|||
|
||||
impl Vst3Plugin for BuffrGlitch {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"BuffrGlitch.RvdH";
|
||||
const VST3_CATEGORIES: &'static str = "Fx";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Fx,
|
||||
Vst3SubCategory::Synth,
|
||||
Vst3SubCategory::Custom("Glitch"),
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(BuffrGlitch);
|
||||
|
|
|
@ -507,7 +507,11 @@ impl ClapPlugin for Crisp {
|
|||
|
||||
impl Vst3Plugin for Crisp {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"CrispPluginRvdH.";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Filter|Distortion";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Fx,
|
||||
Vst3SubCategory::Filter,
|
||||
Vst3SubCategory::Distortion,
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(Crisp);
|
||||
|
|
|
@ -401,7 +401,8 @@ impl ClapPlugin for Crossover {
|
|||
|
||||
impl Vst3Plugin for Crossover {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"CrossoverRvdH...";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Crossover);
|
||||
|
|
|
@ -355,7 +355,8 @@ impl ClapPlugin for Diopser {
|
|||
|
||||
impl Vst3Plugin for Diopser {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"DiopserPlugRvdH.";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Filter";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Filter];
|
||||
}
|
||||
|
||||
nih_export_clap!(Diopser);
|
||||
|
|
|
@ -195,7 +195,8 @@ impl ClapPlugin for Gain {
|
|||
|
||||
impl Vst3Plugin for Gain {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"GainMoistestPlug";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Gain);
|
||||
|
|
|
@ -225,7 +225,8 @@ impl ClapPlugin for Gain {
|
|||
|
||||
impl Vst3Plugin for Gain {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"GainGuiYeahBoyyy";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Gain);
|
||||
|
|
|
@ -167,7 +167,8 @@ impl ClapPlugin for Gain {
|
|||
|
||||
impl Vst3Plugin for Gain {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"GainGuiIcedAaAAa";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Gain);
|
||||
|
|
|
@ -166,7 +166,8 @@ impl ClapPlugin for Gain {
|
|||
|
||||
impl Vst3Plugin for Gain {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"GainGuiVIIIZIAAA";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Gain);
|
||||
|
|
|
@ -227,7 +227,8 @@ impl ClapPlugin for MidiInverter {
|
|||
|
||||
impl Vst3Plugin for MidiInverter {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"M1d1Inv3r70rzAaA";
|
||||
const VST3_CATEGORIES: &'static str = "Instrument|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Instrument, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(MidiInverter);
|
||||
|
|
|
@ -612,7 +612,8 @@ impl ClapPlugin for PolyModSynth {
|
|||
// modulation
|
||||
impl Vst3Plugin for PolyModSynth {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"PolyM0dSynth1337";
|
||||
const VST3_CATEGORIES: &'static str = "Instrument|Synth";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Instrument, Vst3SubCategory::Synth];
|
||||
}
|
||||
|
||||
nih_export_clap!(PolyModSynth);
|
||||
|
|
|
@ -213,7 +213,11 @@ impl ClapPlugin for Sine {
|
|||
|
||||
impl Vst3Plugin for Sine {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"SineMoistestPlug";
|
||||
const VST3_CATEGORIES: &'static str = "Instrument|Synth|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Instrument,
|
||||
Vst3SubCategory::Synth,
|
||||
Vst3SubCategory::Tools,
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(Sine);
|
||||
|
|
|
@ -179,7 +179,8 @@ impl ClapPlugin for Stft {
|
|||
|
||||
impl Vst3Plugin for Stft {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"StftMoistestPlug";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(Stft);
|
||||
|
|
|
@ -102,7 +102,11 @@ impl ClapPlugin for SysEx {
|
|||
|
||||
impl Vst3Plugin for SysEx {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"SysExCoolPluginn";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Instrument|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Fx,
|
||||
Vst3SubCategory::Instrument,
|
||||
Vst3SubCategory::Tools,
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(SysEx);
|
||||
|
|
|
@ -261,7 +261,12 @@ impl ClapPlugin for LoudnessWarWinner {
|
|||
|
||||
impl Vst3Plugin for LoudnessWarWinner {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"LoudnessWar.RvdH";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics|Distortion";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Fx,
|
||||
Vst3SubCategory::Dynamics,
|
||||
Vst3SubCategory::Distortion,
|
||||
Vst3SubCategory::Custom("Pain"),
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(LoudnessWarWinner);
|
||||
|
|
|
@ -431,7 +431,8 @@ impl ClapPlugin for PubertySimulator {
|
|||
|
||||
impl Vst3Plugin for PubertySimulator {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"PubertySim..RvdH";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Pitch Shift";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::PitchShift];
|
||||
}
|
||||
|
||||
nih_export_clap!(PubertySimulator);
|
||||
|
|
|
@ -340,7 +340,8 @@ impl ClapPlugin for SafetyLimiter {
|
|||
|
||||
impl Vst3Plugin for SafetyLimiter {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"SafetyLimtrRvdH.";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Tools";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||
&[Vst3SubCategory::Fx, Vst3SubCategory::Tools];
|
||||
}
|
||||
|
||||
nih_export_clap!(SafetyLimiter);
|
||||
|
|
|
@ -581,7 +581,11 @@ impl ClapPlugin for SpectralCompressor {
|
|||
|
||||
impl Vst3Plugin for SpectralCompressor {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"SpectrlComprRvdH";
|
||||
const VST3_CATEGORIES: &'static str = "Fx|Dynamics|Spectral";
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[
|
||||
Vst3SubCategory::Fx,
|
||||
Vst3SubCategory::Dynamics,
|
||||
Vst3SubCategory::Custom("Spectral"),
|
||||
];
|
||||
}
|
||||
|
||||
nih_export_clap!(SpectralCompressor);
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::midi::MidiConfig;
|
|||
use crate::params::Params;
|
||||
use crate::wrapper::clap::features::ClapFeature;
|
||||
use crate::wrapper::state::PluginState;
|
||||
pub use crate::wrapper::vst3::subcategories::Vst3SubCategory;
|
||||
|
||||
/// A function that can execute a plugin's [`BackgroundTask`][Plugin::BackgroundTask]s. A plugin can
|
||||
/// dispatch these tasks from the `initialize()` function, the `process()` function, or the GUI, so
|
||||
|
@ -249,12 +250,11 @@ pub trait Vst3Plugin: Plugin {
|
|||
///
|
||||
/// This will be shuffled into a different byte order on Windows for project-compatibility.
|
||||
const VST3_CLASS_ID: [u8; 16];
|
||||
/// One or more categories, separated by pipe characters (`|`), up to 127 characters. Anything
|
||||
/// longer than that will be truncated. See the VST3 SDK for examples of common categories:
|
||||
/// <https://github.com/steinbergmedia/vst3_pluginterfaces/blob/2ad397ade5b51007860bedb3b01b8afd2c5f6fba/vst/ivstaudioprocessor.h#L49-L90>
|
||||
//
|
||||
// TODO: Create a category enum similar to ClapFeature
|
||||
const VST3_CATEGORIES: &'static str;
|
||||
/// One or more subcategories. The host may use these to categorize the plugin. Internally this
|
||||
/// slice will be converted to a string where each character is separated by a pipe character
|
||||
/// (`|`). This string has a limit of 127 characters, and anything longer than that will be
|
||||
/// truncated.
|
||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory];
|
||||
|
||||
/// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so
|
||||
/// projects and presets can be shared between platforms. This should not be overridden.
|
||||
|
|
|
@ -30,3 +30,4 @@ pub use crate::plugin::{
|
|||
};
|
||||
pub use crate::wrapper::clap::features::ClapFeature;
|
||||
pub use crate::wrapper::state::PluginState;
|
||||
pub use crate::wrapper::vst3::subcategories::Vst3SubCategory;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/// A keyword for a CLAP plugin. See
|
||||
/// <https://github.com/free-audio/clap/blob/main/include/clap/plugin-features.h> for more
|
||||
/// information.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ClapFeature {
|
||||
// These are the main categories, every plugin should have at least one of these
|
||||
Instrument,
|
||||
|
|
|
@ -8,6 +8,7 @@ use vst3_sys::VST3;
|
|||
// Alias needed for the VST3 attribute macro
|
||||
use vst3_sys as vst3_com;
|
||||
|
||||
use super::subcategories::Vst3SubCategory;
|
||||
use super::util::u16strlcpy;
|
||||
use super::wrapper::Wrapper;
|
||||
use crate::plugin::Vst3Plugin;
|
||||
|
@ -102,20 +103,7 @@ impl<P: Vst3Plugin> IPluginFactory2 for Factory<P> {
|
|||
strlcpy(&mut info.category, "Audio Module Class");
|
||||
strlcpy(&mut info.name, P::NAME);
|
||||
info.class_flags = 1 << 1; // kSimpleModeSupported
|
||||
|
||||
// No idea if any hosts do something with this, but it's part of VST3's example categories
|
||||
// list
|
||||
if P::HARD_REALTIME_ONLY {
|
||||
nih_debug_assert!(!P::VST3_CATEGORIES.ends_with('|'));
|
||||
nih_debug_assert!(!P::VST3_CATEGORIES.contains("OnlyRT"));
|
||||
strlcpy(
|
||||
&mut info.subcategories,
|
||||
&format!("{}|OnlyRT", P::VST3_CATEGORIES),
|
||||
);
|
||||
} else {
|
||||
strlcpy(&mut info.subcategories, P::VST3_CATEGORIES);
|
||||
};
|
||||
|
||||
strlcpy(&mut info.subcategories, &make_subcategories_string::<P>());
|
||||
strlcpy(&mut info.vendor, P::VENDOR);
|
||||
strlcpy(&mut info.version, P::VERSION);
|
||||
strlcpy(&mut info.sdk_version, VST3_SDK_VERSION);
|
||||
|
@ -142,7 +130,7 @@ impl<P: Vst3Plugin> IPluginFactory3 for Factory<P> {
|
|||
strlcpy(&mut info.category, "Audio Module Class");
|
||||
u16strlcpy(&mut info.name, P::NAME);
|
||||
info.class_flags = 1 << 1; // kSimpleModeSupported
|
||||
strlcpy(&mut info.subcategories, P::VST3_CATEGORIES);
|
||||
strlcpy(&mut info.subcategories, &make_subcategories_string::<P>());
|
||||
u16strlcpy(&mut info.vendor, P::VENDOR);
|
||||
u16strlcpy(&mut info.version, P::VERSION);
|
||||
u16strlcpy(&mut info.sdk_version, VST3_SDK_VERSION);
|
||||
|
@ -155,3 +143,20 @@ impl<P: Vst3Plugin> IPluginFactory3 for Factory<P> {
|
|||
kResultOk
|
||||
}
|
||||
}
|
||||
|
||||
fn make_subcategories_string<P: Vst3Plugin>() -> String {
|
||||
// No idea if any hosts do something with OnlyRT, but it's part of VST3's example categories
|
||||
// list. Plugins should not be adding this feature manually
|
||||
nih_debug_assert!(!P::VST3_SUBCATEGORIES.contains(&Vst3SubCategory::Custom("OnlyRT")));
|
||||
let category_string = P::VST3_SUBCATEGORIES
|
||||
.iter()
|
||||
.map(Vst3SubCategory::as_str)
|
||||
.collect::<Vec<&str>>()
|
||||
.join("|");
|
||||
|
||||
if P::HARD_REALTIME_ONLY {
|
||||
format!("{category_string}|OnlyRT")
|
||||
} else {
|
||||
category_string
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
/// <https://github.com/steinbergmedia/vst3_pluginterfaces/blob/bc5ff0f87aaa3cd28c114810f4f03c384421ad2c/vst/ivstaudioprocessor.h#L49-L90>
|
||||
/// for a list of all predefined subcategories. Multiple subcategories are concatenated to a string
|
||||
/// separated by pipe characters, and the total length of this string may not exceed 127 characters.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Vst3SubCategory {
|
||||
// These are the main categories, every plugin should have at least one of these, I think
|
||||
Fx,
|
||||
|
|
Loading…
Reference in a new issue