From 7cd7294b22021bcd21b2f8f1e142d56c8143fad1 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 4 Jul 2022 12:44:30 +0200 Subject: [PATCH] Make CLAP descriptions and special URLs optional This closes #14. --- BREAKING_CHANGES.md | 6 ++++ plugins/crisp/src/lib.rs | 7 ++-- plugins/crossover/src/lib.rs | 7 ++-- plugins/diopser/src/lib.rs | 6 ++-- plugins/examples/gain/src/lib.rs | 8 ++--- plugins/examples/gain_gui_egui/src/lib.rs | 6 ++-- plugins/examples/gain_gui_iced/src/lib.rs | 6 ++-- plugins/examples/gain_gui_vizia/src/lib.rs | 8 ++--- plugins/examples/midi_inverter/src/lib.rs | 8 ++--- plugins/examples/sine/src/lib.rs | 7 ++-- plugins/examples/stft/src/lib.rs | 6 ++-- plugins/loudness_war_winner/src/lib.rs | 6 ++-- plugins/puberty_simulator/src/lib.rs | 6 ++-- plugins/safety_limiter/src/lib.rs | 6 ++-- src/plugin.rs | 18 +++++----- src/wrapper/clap/descriptor.rs | 40 ++++++++++++++-------- 16 files changed, 85 insertions(+), 66 deletions(-) diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index cbd31bcb..9926f38a 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -6,6 +6,12 @@ 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-07-04] + +- The `CLAP_DESCRIPTION`, `CLAP_MANUAL_URL`, and `CLAP_SUPPORT_URL` associated + constants from the `ClapPlugin` are now optional and have the type + `Option<&'static str>` instead of `&'static str`. + ## [2022-07-02] - The `Params::serialize_fields()` and `Params::deserialize_fields()` methods diff --git a/plugins/crisp/src/lib.rs b/plugins/crisp/src/lib.rs index 73409403..87b35132 100644 --- a/plugins/crisp/src/lib.rs +++ b/plugins/crisp/src/lib.rs @@ -481,15 +481,16 @@ 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_DESCRIPTION: Option<&'static str> = + Some("Adds a bright crispy top end to low bass sounds"); + 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, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Distortion, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Crisp { diff --git a/plugins/crossover/src/lib.rs b/plugins/crossover/src/lib.rs index eee1c18f..8ebc0519 100644 --- a/plugins/crossover/src/lib.rs +++ b/plugins/crossover/src/lib.rs @@ -385,14 +385,15 @@ 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_DESCRIPTION: Option<&'static str> = + Some("Cleanly split a signal into multiple bands"); + 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, ClapFeature::Stereo, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Crossover { diff --git a/plugins/diopser/src/lib.rs b/plugins/diopser/src/lib.rs index b19afb09..a64f9f4d 100644 --- a/plugins/diopser/src/lib.rs +++ b/plugins/diopser/src/lib.rs @@ -408,15 +408,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("A totally original phase rotation plugin"); + 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, ClapFeature::Stereo, ClapFeature::Filter, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Diopser { diff --git a/plugins/examples/gain/src/lib.rs b/plugins/examples/gain/src/lib.rs index 3c182cb2..f23e206b 100644 --- a/plugins/examples/gain/src/lib.rs +++ b/plugins/examples/gain/src/lib.rs @@ -153,15 +153,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("A smoothed gain parameter example plugin"); + 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, ClapFeature::Stereo, - ClapFeature::Filter, + ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Gain { diff --git a/plugins/examples/gain_gui_egui/src/lib.rs b/plugins/examples/gain_gui_egui/src/lib.rs index 97d12461..666b8fff 100644 --- a/plugins/examples/gain_gui_egui/src/lib.rs +++ b/plugins/examples/gain_gui_egui/src/lib.rs @@ -191,15 +191,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("A smoothed gain parameter example plugin"); + 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, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Gain { diff --git a/plugins/examples/gain_gui_iced/src/lib.rs b/plugins/examples/gain_gui_iced/src/lib.rs index b6e52460..e7a82227 100644 --- a/plugins/examples/gain_gui_iced/src/lib.rs +++ b/plugins/examples/gain_gui_iced/src/lib.rs @@ -137,15 +137,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("A smoothed gain parameter example plugin"); + 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, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Gain { diff --git a/plugins/examples/gain_gui_vizia/src/lib.rs b/plugins/examples/gain_gui_vizia/src/lib.rs index be126fef..6c9722e7 100644 --- a/plugins/examples/gain_gui_vizia/src/lib.rs +++ b/plugins/examples/gain_gui_vizia/src/lib.rs @@ -137,15 +137,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("A smoothed gain parameter example plugin"); + 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, ClapFeature::Stereo, - ClapFeature::Filter, + ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Gain { diff --git a/plugins/examples/midi_inverter/src/lib.rs b/plugins/examples/midi_inverter/src/lib.rs index 8995fd74..cfbddce3 100644 --- a/plugins/examples/midi_inverter/src/lib.rs +++ b/plugins/examples/midi_inverter/src/lib.rs @@ -186,11 +186,11 @@ impl Plugin for MidiInverter { 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_DESCRIPTION: Option<&'static str> = + Some("Inverts all note and MIDI signals in ways you don't want to"); + const CLAP_MANUAL_URL: Option<&'static str> = Some(Self::URL); + const CLAP_SUPPORT_URL: Option<&'static str> = None; 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; } impl Vst3Plugin for MidiInverter { diff --git a/plugins/examples/sine/src/lib.rs b/plugins/examples/sine/src/lib.rs index bf0d6e6e..bd740c8f 100644 --- a/plugins/examples/sine/src/lib.rs +++ b/plugins/examples/sine/src/lib.rs @@ -195,15 +195,16 @@ 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_DESCRIPTION: Option<&'static str> = + Some("An optionally MIDI controlled sine test tone"); + const CLAP_MANUAL_URL: Option<&'static str> = Some(Self::URL); + const CLAP_SUPPORT_URL: Option<&'static str> = None; const CLAP_FEATURES: &'static [ClapFeature] = &[ ClapFeature::Synthesizer, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Sine { diff --git a/plugins/examples/stft/src/lib.rs b/plugins/examples/stft/src/lib.rs index 298fa890..766878bc 100644 --- a/plugins/examples/stft/src/lib.rs +++ b/plugins/examples/stft/src/lib.rs @@ -163,15 +163,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("An example plugin using the STFT helper"); + 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, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for Stft { diff --git a/plugins/loudness_war_winner/src/lib.rs b/plugins/loudness_war_winner/src/lib.rs index c5a2f2fa..81ad1f0e 100644 --- a/plugins/loudness_war_winner/src/lib.rs +++ b/plugins/loudness_war_winner/src/lib.rs @@ -242,7 +242,9 @@ 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_DESCRIPTION: Option<&'static str> = Some("Win the loudness war with ease"); + 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, ClapFeature::Stereo, @@ -252,8 +254,6 @@ impl ClapPlugin for LoudnessWarWinner { ClapFeature::Utility, ClapFeature::Custom("pain"), ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for LoudnessWarWinner { diff --git a/plugins/puberty_simulator/src/lib.rs b/plugins/puberty_simulator/src/lib.rs index 8bf169be..bb16c188 100644 --- a/plugins/puberty_simulator/src/lib.rs +++ b/plugins/puberty_simulator/src/lib.rs @@ -415,15 +415,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("Simulates a pitched down cracking voice"); + 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, ClapFeature::Stereo, ClapFeature::Glitch, ClapFeature::PitchShifter, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for PubertySimulator { diff --git a/plugins/safety_limiter/src/lib.rs b/plugins/safety_limiter/src/lib.rs index 907a568e..9d543c0b 100644 --- a/plugins/safety_limiter/src/lib.rs +++ b/plugins/safety_limiter/src/lib.rs @@ -304,15 +304,15 @@ 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_DESCRIPTION: Option<&'static str> = Some("Plays SOS in Morse code when redlining"); + 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, ClapFeature::Stereo, ClapFeature::Mono, ClapFeature::Utility, ]; - const CLAP_MANUAL_URL: &'static str = Self::URL; - const CLAP_SUPPORT_URL: &'static str = Self::URL; } impl Vst3Plugin for SafetyLimiter { diff --git a/src/plugin.rs b/src/plugin.rs index 4e968e76..1f0ff959 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -192,17 +192,15 @@ pub trait ClapPlugin: Plugin { /// A unique ID that identifies this particular plugin. This is usually in reverse domain name /// notation, e.g. `com.manufacturer.plugin-name`. const CLAP_ID: &'static str; - /// A short description for the plugin. - const CLAP_DESCRIPTION: &'static str; - /// Arbitrary keywords describing the plugin. See the CLAP specification for examples: - /// . + /// An optional short description for the plugin. + const CLAP_DESCRIPTION: Option<&'static str>; + /// The URL to the plugin's manual, if available. + const CLAP_MANUAL_URL: Option<&'static str>; + /// The URL to the plugin's support page, if available. + const CLAP_SUPPORT_URL: Option<&'static str>; + /// Keywords describing the plugin. The host may use this to classify the plugin in its plugin + /// browser. 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? - const CLAP_MANUAL_URL: &'static str; - /// A URL to the plugin's support page, CLAP does not specify what to do when there is none. - const CLAP_SUPPORT_URL: &'static str; /// If this is set to true, then the plugin will report itself as having a hard realtime /// processing requirement when the host asks for it. Supported hosts will never ask the plugin diff --git a/src/wrapper/clap/descriptor.rs b/src/wrapper/clap/descriptor.rs index 8458b437..1b78c094 100644 --- a/src/wrapper/clap/descriptor.rs +++ b/src/wrapper/clap/descriptor.rs @@ -4,7 +4,6 @@ use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::mem::MaybeUninit; use std::os::raw::c_char; -use std::ptr; use crate::plugin::ClapPlugin; @@ -19,10 +18,10 @@ pub struct PluginDescriptor { name: CString, vendor: CString, url: CString, - clap_manual_url: CString, - clap_support_url: CString, version: CString, - clap_description: CString, + clap_manual_url: Option, + clap_support_url: Option, + clap_description: Option, clap_features: Vec, clap_features_ptrs: MaybeUninit>, @@ -42,13 +41,14 @@ impl Default for PluginDescriptor

{ name: CString::new(P::NAME).expect("`NAME` contained null bytes"), vendor: CString::new(P::VENDOR).expect("`VENDOR` contained null bytes"), url: CString::new(P::URL).expect("`URL` contained null bytes"), - clap_manual_url: CString::new(P::CLAP_MANUAL_URL) - .expect("`CLAP_MANUAL_URL` contained null bytes"), - clap_support_url: CString::new(P::CLAP_SUPPORT_URL) - .expect("`CLAP_SUPPORT_URL` contained null bytes"), version: CString::new(P::VERSION).expect("`VERSION` contained null bytes"), - clap_description: CString::new(P::CLAP_DESCRIPTION) - .expect("`CLAP_DESCRIPTION` contained null bytes"), + clap_manual_url: P::CLAP_MANUAL_URL + .map(|url| CString::new(url).expect("`CLAP_MANUAL_URL` contained null bytes")), + clap_support_url: P::CLAP_SUPPORT_URL + .map(|url| CString::new(url).expect("`CLAP_SUPPORT_URL` contained null bytes")), + clap_description: P::CLAP_DESCRIPTION.map(|description| { + CString::new(description).expect("`CLAP_DESCRIPTION` contained null bytes") + }), clap_features: P::CLAP_FEATURES .iter() .map(|feat| feat.as_str()) @@ -67,7 +67,7 @@ impl Default for PluginDescriptor

{ .iter() .map(|feature| feature.as_ptr()) .collect(); - clap_features_ptrs.push(ptr::null()); + clap_features_ptrs.push(std::ptr::null()); descriptor.clap_features_ptrs.write(clap_features_ptrs); // We couldn't initialize this directly because of all the CStrings @@ -77,10 +77,22 @@ impl Default for PluginDescriptor

{ name: descriptor.name.as_ptr(), vendor: descriptor.vendor.as_ptr(), url: descriptor.url.as_ptr(), - manual_url: descriptor.clap_manual_url.as_ptr(), - support_url: descriptor.clap_support_url.as_ptr(), version: descriptor.version.as_ptr(), - description: descriptor.clap_description.as_ptr(), + manual_url: descriptor + .clap_manual_url + .as_ref() + .map(|url| url.as_ptr()) + .unwrap_or(std::ptr::null()), + support_url: descriptor + .clap_support_url + .as_ref() + .map(|url| url.as_ptr()) + .unwrap_or(std::ptr::null()), + description: descriptor + .clap_description + .as_ref() + .map(|description| description.as_ptr()) + .unwrap_or(std::ptr::null()), features: unsafe { descriptor.clap_features_ptrs.assume_init_ref() }.as_ptr(), });