From bfc472e49b3c0b40eccd58c8f2ab11a283353f4c Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 2 Jun 2022 01:16:30 +0200 Subject: [PATCH] Introduce a new enum for CLAP features Based on the new CLAP 0.26 clap-features.h. --- BREAKING_CHANGES.md | 9 ++- plugins/crisp/src/lib.rs | 8 ++- plugins/crossover/src/lib.rs | 6 +- plugins/diopser/src/lib.rs | 7 +- plugins/examples/gain/src/lib.rs | 7 +- plugins/examples/gain_gui_egui/src/lib.rs | 7 +- plugins/examples/gain_gui_iced/src/lib.rs | 7 +- plugins/examples/gain_gui_vizia/src/lib.rs | 7 +- plugins/examples/midi_inverter/src/lib.rs | 2 +- plugins/examples/sine/src/lib.rs | 7 +- plugins/examples/stft/src/lib.rs | 7 +- plugins/loudness_war_winner/src/lib.rs | 16 ++--- plugins/puberty_simulator/src/lib.rs | 8 ++- plugins/safety_limiter/src/lib.rs | 7 +- src/plugin.rs | 7 +- src/prelude.rs | 1 + src/wrapper/clap.rs | 1 + src/wrapper/clap/descriptor.rs | 3 +- src/wrapper/clap/features.rs | 84 ++++++++++++++++++++++ 19 files changed, 174 insertions(+), 27 deletions(-) create mode 100644 src/wrapper/clap/features.rs diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 1acd7eb0..04d1ec7d 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -6,7 +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. -## [2022-05-2y] +## [2022-06-01] + +- The `ClapPlugin::CLAP_FEATURES` field now uses an array of `ClapFeature` + values instead of `&'static str`s. CLAP 0.26 contains many new predefined + features, and the existing ones now use dashes instead of underscores. Custom + features are still possible using `ClapFeature::Custom`. + +## [2022-05-27] - The `Plugin::initialize()` method now takes a `&mut impl InitContext` instead of a `&mut impl ProcessContext`. diff --git a/plugins/crisp/src/lib.rs b/plugins/crisp/src/lib.rs index a1cf4dff..b8e38494 100644 --- a/plugins/crisp/src/lib.rs +++ b/plugins/crisp/src/lib.rs @@ -477,8 +477,12 @@ impl Crisp { impl ClapPlugin for Crisp { const CLAP_ID: &'static str = "nl.robbertvanderhelm.crisp"; const CLAP_DESCRIPTION: &'static str = "Adds a bright crispy top end to low bass sounds"; - const CLAP_FEATURES: &'static [&'static str] = - &["audio-effect", "stereo", "distortion", "filter"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Distortion, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/crossover/src/lib.rs b/plugins/crossover/src/lib.rs index e83ada5b..f51d5d58 100644 --- a/plugins/crossover/src/lib.rs +++ b/plugins/crossover/src/lib.rs @@ -280,7 +280,11 @@ impl Crossover { impl ClapPlugin for Crossover { const CLAP_ID: &'static str = "nl.robbertvanderhelm.crossover"; const CLAP_DESCRIPTION: &'static str = "Cleanly split a signal into multiple bands"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "stereo", "utility"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/diopser/src/lib.rs b/plugins/diopser/src/lib.rs index ca2eeb73..99e7c42d 100644 --- a/plugins/diopser/src/lib.rs +++ b/plugins/diopser/src/lib.rs @@ -397,7 +397,12 @@ fn unnormalize_automation_precision(normalized: f32) -> u32 { impl ClapPlugin for Diopser { const CLAP_ID: &'static str = "nl.robbertvanderhelm.diopser"; const CLAP_DESCRIPTION: &'static str = "A totally original phase rotation plugin"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "stereo", "filter", "utility"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Filter, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/gain/src/lib.rs b/plugins/examples/gain/src/lib.rs index 14589304..a4f8bd8b 100644 --- a/plugins/examples/gain/src/lib.rs +++ b/plugins/examples/gain/src/lib.rs @@ -154,7 +154,12 @@ impl Plugin for Gain { impl ClapPlugin for Gain { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.gain"; const CLAP_DESCRIPTION: &'static str = "A smoothed gain parameter example plugin"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "mono", "stereo", "tool"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Filter, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/gain_gui_egui/src/lib.rs b/plugins/examples/gain_gui_egui/src/lib.rs index 75093723..97d12461 100644 --- a/plugins/examples/gain_gui_egui/src/lib.rs +++ b/plugins/examples/gain_gui_egui/src/lib.rs @@ -192,7 +192,12 @@ impl Plugin for Gain { impl ClapPlugin for Gain { const CLAP_ID: &'static str = "com.moist-plugins-gmbh-egui.gain-gui"; const CLAP_DESCRIPTION: &'static str = "A smoothed gain parameter example plugin"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "mono", "stereo", "tool"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/gain_gui_iced/src/lib.rs b/plugins/examples/gain_gui_iced/src/lib.rs index 9d5b15c1..b6e52460 100644 --- a/plugins/examples/gain_gui_iced/src/lib.rs +++ b/plugins/examples/gain_gui_iced/src/lib.rs @@ -138,7 +138,12 @@ impl Plugin for Gain { impl ClapPlugin for Gain { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.gain-gui-iced"; const CLAP_DESCRIPTION: &'static str = "A smoothed gain parameter example plugin"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "mono", "stereo", "tool"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/gain_gui_vizia/src/lib.rs b/plugins/examples/gain_gui_vizia/src/lib.rs index 9ea7bdaa..be126fef 100644 --- a/plugins/examples/gain_gui_vizia/src/lib.rs +++ b/plugins/examples/gain_gui_vizia/src/lib.rs @@ -138,7 +138,12 @@ impl Plugin for Gain { impl ClapPlugin for Gain { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.gain-gui-vizia"; const CLAP_DESCRIPTION: &'static str = "A smoothed gain parameter example plugin"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "mono", "stereo", "tool"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Filter, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/midi_inverter/src/lib.rs b/plugins/examples/midi_inverter/src/lib.rs index 0d900d61..8995fd74 100644 --- a/plugins/examples/midi_inverter/src/lib.rs +++ b/plugins/examples/midi_inverter/src/lib.rs @@ -188,7 +188,7 @@ impl ClapPlugin for MidiInverter { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.midi-inverter"; const CLAP_DESCRIPTION: &'static str = "Inverts all note and MIDI signals in ways you don't want to"; - const CLAP_FEATURES: &'static [&'static str] = &["note-effect", "utility"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ClapFeature::NoteEffect, ClapFeature::Utility]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/sine/src/lib.rs b/plugins/examples/sine/src/lib.rs index cf421f5d..4c386ae1 100644 --- a/plugins/examples/sine/src/lib.rs +++ b/plugins/examples/sine/src/lib.rs @@ -196,7 +196,12 @@ impl Plugin for Sine { impl ClapPlugin for Sine { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.sine"; const CLAP_DESCRIPTION: &'static str = "An optionally MIDI controlled sine test tone"; - const CLAP_FEATURES: &'static [&'static str] = &["instrument", "mono", "stereo", "utility"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/examples/stft/src/lib.rs b/plugins/examples/stft/src/lib.rs index 6371006a..298fa890 100644 --- a/plugins/examples/stft/src/lib.rs +++ b/plugins/examples/stft/src/lib.rs @@ -164,7 +164,12 @@ impl Plugin for Stft { impl ClapPlugin for Stft { const CLAP_ID: &'static str = "com.moist-plugins-gmbh.stft"; const CLAP_DESCRIPTION: &'static str = "An example plugin using the STFT helper"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "stereo", "tool"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/loudness_war_winner/src/lib.rs b/plugins/loudness_war_winner/src/lib.rs index e90bfe5a..c5a2f2fa 100644 --- a/plugins/loudness_war_winner/src/lib.rs +++ b/plugins/loudness_war_winner/src/lib.rs @@ -243,14 +243,14 @@ impl LoudnessWarWinner { impl ClapPlugin for LoudnessWarWinner { const CLAP_ID: &'static str = "nl.robbertvanderhelm.loudness-war-winner"; const CLAP_DESCRIPTION: &'static str = "Win the loudness war with ease"; - const CLAP_FEATURES: &'static [&'static str] = &[ - "audio-effect", - "stereo", - "mono", - "limiter", - "distortion", - "utility", - "pain", + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Limiter, + ClapFeature::Distortion, + ClapFeature::Utility, + ClapFeature::Custom("pain"), ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; diff --git a/plugins/puberty_simulator/src/lib.rs b/plugins/puberty_simulator/src/lib.rs index dea926a3..1df0f77f 100644 --- a/plugins/puberty_simulator/src/lib.rs +++ b/plugins/puberty_simulator/src/lib.rs @@ -414,8 +414,12 @@ impl PubertySimulator { impl ClapPlugin for PubertySimulator { const CLAP_ID: &'static str = "nl.robbertvanderhelm.puberty-simulator"; const CLAP_DESCRIPTION: &'static str = "Simulates a pitched down cracking voice"; - const CLAP_FEATURES: &'static [&'static str] = - &["audio-effect", "stereo", "glitch", "pitch_shifter"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Glitch, + ClapFeature::PitchShifter, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/plugins/safety_limiter/src/lib.rs b/plugins/safety_limiter/src/lib.rs index f08c1523..fd59958c 100644 --- a/plugins/safety_limiter/src/lib.rs +++ b/plugins/safety_limiter/src/lib.rs @@ -298,7 +298,12 @@ impl SafetyLimiter { impl ClapPlugin for SafetyLimiter { const CLAP_ID: &'static str = "nl.robbertvanderhelm.safety-limiter"; const CLAP_DESCRIPTION: &'static str = "Plays SOS in Morse code when redlining"; - const CLAP_FEATURES: &'static [&'static str] = &["audio-effect", "stereo", "utility"]; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Stereo, + ClapFeature::Mono, + ClapFeature::Utility, + ]; const CLAP_MANUAL_URL: &'static str = Self::URL; const CLAP_SUPPORT_URL: &'static str = Self::URL; } diff --git a/src/plugin.rs b/src/plugin.rs index ed62f31d..96f8d5e7 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -8,6 +8,7 @@ use crate::buffer::Buffer; use crate::context::{GuiContext, InitContext, ProcessContext}; use crate::midi::MidiConfig; use crate::param::internals::Params; +use crate::wrapper::clap::features::ClapFeature; /// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to /// expose the plugin in a particular plugin format. @@ -193,9 +194,7 @@ pub trait ClapPlugin: Plugin { const CLAP_DESCRIPTION: &'static str; /// Arbitrary keywords describing the plugin. See the CLAP specification for examples: /// . - /// - /// On windows `win32-dpi-aware` is automatically added. - const CLAP_FEATURES: &'static [&'static str]; + const CLAP_FEATURES: &'static [ClapFeature]; /// A URL to the plugin's manual, CLAP does not specify what to do when there is none. // // TODO: CLAP does not specify this, can these manual fields be null pointers? @@ -221,6 +220,8 @@ pub trait Vst3Plugin: Plugin { /// One or more categories, separated by pipe characters (`|`), up to 127 characters. Anything /// logner than that will be truncated. See the VST3 SDK for examples of common categories: /// + // + // TODO: Create a category enum similar to CLapFeature const VST3_CATEGORIES: &'static str; /// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so diff --git a/src/prelude.rs b/src/prelude.rs index ceba24e7..e33f7d71 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -23,4 +23,5 @@ pub use crate::plugin::{ AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ClapPlugin, Editor, ParentWindowHandle, Plugin, PortNames, ProcessMode, ProcessStatus, Vst3Plugin, }; +pub use crate::wrapper::clap::features::ClapFeature; pub use crate::wrapper::state::PluginState; diff --git a/src/wrapper/clap.rs b/src/wrapper/clap.rs index 191cff4d..0110c32c 100644 --- a/src/wrapper/clap.rs +++ b/src/wrapper/clap.rs @@ -4,6 +4,7 @@ mod util; mod context; mod descriptor; mod factory; +pub mod features; mod wrapper; /// Re-export for the wrapper. diff --git a/src/wrapper/clap/descriptor.rs b/src/wrapper/clap/descriptor.rs index 4f2d5e41..8458b437 100644 --- a/src/wrapper/clap/descriptor.rs +++ b/src/wrapper/clap/descriptor.rs @@ -51,7 +51,8 @@ impl Default for PluginDescriptor

{ .expect("`CLAP_DESCRIPTION` contained null bytes"), clap_features: P::CLAP_FEATURES .iter() - .map(|s| CString::new(*s).expect("`CLAP_FEATURES` contained null bytes")) + .map(|feat| feat.as_str()) + .map(|s| CString::new(s).expect("`CLAP_FEATURES` contained null bytes")) .collect(), clap_features_ptrs: MaybeUninit::uninit(), diff --git a/src/wrapper/clap/features.rs b/src/wrapper/clap/features.rs new file mode 100644 index 00000000..833f85c2 --- /dev/null +++ b/src/wrapper/clap/features.rs @@ -0,0 +1,84 @@ +//! Features a plugin supports. This is essentially the same thing as tags, keyword, or categories. +//! Hosts may use these to organize plugins. + +/// A keyword for a CLAP plugin. See +/// for more +/// information. +pub enum ClapFeature { + Instrument, + AudioEffect, + NoteEffect, + Analyzer, + Filter, + Phaser, + Equalizer, + Deesser, + PhaseVocoder, + Granular, + FrequencyShifter, + PitchShifter, + Distortion, + TransientShaper, + Compressor, + Limiter, + Flanger, + Chorus, + Delay, + Reverb, + Tremolo, + Glitch, + Utility, + PitchCorrection, + Restoration, + MultiEffects, + Mixing, + Mastering, + Mono, + Stereo, + Surround, + Ambisonic, + Win32DpiAware, + /// A non-predefined feature. Hosts may display this among its plugin categories. + Custom(&'static str), +} + +impl ClapFeature { + pub fn as_str(&self) -> &'static str { + match &self { + ClapFeature::Instrument => "instrument", + ClapFeature::AudioEffect => "audio-effect", + ClapFeature::NoteEffect => "note-effect", + ClapFeature::Analyzer => "analyzer", + ClapFeature::Filter => "filter", + ClapFeature::Phaser => "phaser", + ClapFeature::Equalizer => "equalizer", + ClapFeature::Deesser => "de-esser", + ClapFeature::PhaseVocoder => "phase-vocoder", + ClapFeature::Granular => "granular", + ClapFeature::FrequencyShifter => "frequency-shifter", + ClapFeature::PitchShifter => "pitch-shifter", + ClapFeature::Distortion => "distortion", + ClapFeature::TransientShaper => "transient-shaper", + ClapFeature::Compressor => "compressor", + ClapFeature::Limiter => "limiter", + ClapFeature::Flanger => "flanger", + ClapFeature::Chorus => "chorus", + ClapFeature::Delay => "delay", + ClapFeature::Reverb => "reverb", + ClapFeature::Tremolo => "tremolo", + ClapFeature::Glitch => "glitch", + ClapFeature::Utility => "utility", + ClapFeature::PitchCorrection => "pitch-correction", + ClapFeature::Restoration => "restoration", + ClapFeature::MultiEffects => "multi-effects", + ClapFeature::Mixing => "mixing", + ClapFeature::Mastering => "mastering", + ClapFeature::Mono => "mono", + ClapFeature::Stereo => "stereo", + ClapFeature::Surround => "surround", + ClapFeature::Ambisonic => "ambisonic", + ClapFeature::Win32DpiAware => "win32-dpi-aware", + ClapFeature::Custom(s) => s, + } + } +}