Skip to content

Commit 8a068a7

Browse files
committed
refactor extensions a little; add Proxy helper
1 parent 4ac9aef commit 8a068a7

32 files changed

Lines changed: 619 additions & 674 deletions

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ textwrap = { version = "0.16.2", features = ["terminal_size"] }
4141
time = { version = "0.3", features = ["serde"]}
4242
walkdir = "2.3"
4343
wait-timeout = "0.2.1"
44+
rustc-hash = "2.1.1"
4445

4546
[target.'cfg(target_os = "macos")'.dependencies]
4647
core-foundation = "0.10.1"

src/plugin/ext.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@ pub mod tail;
2020
pub mod thread_pool;
2121
pub mod voice_info;
2222

23-
/// An abstraction for a CLAP plugin extension. `P` here is the plugin type. In practice, this is
24-
/// either `Plugin`, `PluginShared` or `PluginAudioThread`. Abstractions for main thread functions will implement
25-
/// this trait for `Plugin`, abstractions for audio thread functions will implement this trait
26-
/// for `PluginAudioThread` and abstractions for thread-safe functions will implement this trait for
27-
/// `PluginShared`.
28-
pub trait Extension<P> {
23+
/// An abstraction for a CLAP plugin extension.
24+
pub trait Extension {
2925
/// The list of C-string IDs for the extension.
3026
const IDS: &'static [&'static CStr];
3127

28+
/// The plugin type (`Plugin` for main-thread, `PluginShared` for shared, `PluginAudioThread` for audio-thread) for which this extension is implemented.
29+
type Plugin;
3230
/// The type of the C-struct for the extension.
3331
type Struct;
3432

@@ -38,5 +36,5 @@ pub trait Extension<P> {
3836
/// # Safety
3937
/// The extension struct pointer must be a valid pointer to the correct extension struct for
4038
/// the plugin instance and given `IDS`.
41-
unsafe fn new(plugin: P, extension_struct: NonNull<Self::Struct>) -> Self;
39+
unsafe fn new(plugin: Self::Plugin, extension_struct: NonNull<Self::Struct>) -> Self;
4240
}

src/plugin/ext/ambisonic.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ pub struct Ambisonic<'a> {
1111
ambisonic: NonNull<clap_plugin_ambisonic>,
1212
}
1313

14-
impl<'a> Extension<&'a Plugin<'a>> for Ambisonic<'a> {
14+
impl<'a> Extension for Ambisonic<'a> {
1515
const IDS: &'static [&'static CStr] = &[CLAP_EXT_AMBISONIC, CLAP_EXT_AMBISONIC_COMPAT];
1616

17+
type Plugin = &'a Plugin<'a>;
1718
type Struct = clap_plugin_ambisonic;
1819

1920
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {

src/plugin/ext/audio_ports.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,18 @@ pub struct AudioPort {
4848
/// Supports 64 bit processing
4949
pub supports_double_sample_size: bool,
5050

51+
/// Prefers 64 bit processing
52+
pub prefers_double_sample_size: bool,
53+
5154
/// All ports with this flag require common sample size
5255
#[allow(unused)] // TODO: use for future mixed precision processing tests
5356
pub requires_common_sample_size: bool,
5457
}
5558

56-
impl<'a> Extension<&'a Plugin<'a>> for AudioPorts<'a> {
59+
impl<'a> Extension for AudioPorts<'a> {
5760
const IDS: &'static [&'static CStr] = &[CLAP_EXT_AUDIO_PORTS];
5861

62+
type Plugin = &'a Plugin<'a>;
5963
type Struct = clap_plugin_audio_ports;
6064

6165
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {
@@ -70,6 +74,20 @@ impl AudioPorts<'_> {
7074
/// Get the audio port configuration for this plugin. This automatically performs a number of
7175
/// consistency checks on the plugin's audio port configuration.
7276
pub fn config(&self) -> Result<AudioPortConfig> {
77+
fn get_raw_port_info(this: &AudioPorts, is_input: bool, port_index: u32) -> Option<clap_audio_port_info> {
78+
let audio_ports = this.audio_ports.as_ptr();
79+
let plugin = this.plugin.as_ptr();
80+
81+
unsafe {
82+
let mut info = clap_audio_port_info { ..zeroed() };
83+
if !clap_call! { audio_ports=>get(plugin, port_index, is_input, &mut info) } {
84+
return None;
85+
}
86+
87+
Some(info)
88+
}
89+
}
90+
7391
let mut config = AudioPortConfig::default();
7492

7593
let audio_ports = self.audio_ports.as_ptr();
@@ -82,12 +100,12 @@ impl AudioPorts<'_> {
82100
};
83101

84102
for index in 0..num_inputs {
85-
let info = match self.get_raw_port_info(true, index) {
103+
let info = match get_raw_port_info(self, true, index) {
86104
Some(info) => info,
87105
None => {
88106
anyhow::bail!(
89107
"Plugin returned false when querying audio port info for input port {index} (out of \
90-
{num_inputs} total)."
108+
{num_inputs} total)"
91109
);
92110
}
93111
};
@@ -99,12 +117,12 @@ impl AudioPorts<'_> {
99117
}
100118

101119
for index in 0..num_outputs {
102-
let info = match self.get_raw_port_info(false, index) {
120+
let info = match get_raw_port_info(self, false, index) {
103121
Some(info) => info,
104122
None => {
105123
anyhow::bail!(
106124
"Plugin returned false when querying audio port info for output port {index} (out of \
107-
{num_outputs} total)."
125+
{num_outputs} total)"
108126
);
109127
}
110128
};
@@ -155,22 +173,6 @@ impl AudioPorts<'_> {
155173

156174
Ok(config)
157175
}
158-
159-
/// Get the raw audio port information for the given port index. This does not perform any
160-
/// consistency checks.
161-
pub fn get_raw_port_info(&self, is_input: bool, port_index: u32) -> Option<clap_audio_port_info> {
162-
let audio_ports = self.audio_ports.as_ptr();
163-
let plugin = self.plugin.as_ptr();
164-
165-
unsafe {
166-
let mut info = clap_audio_port_info { ..zeroed() };
167-
if !clap_call! { audio_ports=>get(plugin, port_index, is_input, &mut info) } {
168-
return None;
169-
}
170-
171-
Some(info)
172-
}
173-
}
174176
}
175177

176178
pub fn check_audio_port_info_valid(
@@ -228,6 +230,7 @@ pub fn check_audio_port_info_valid(
228230

229231
supports_double_sample_size,
230232
requires_common_sample_size,
233+
prefers_double_sample_size,
231234
})
232235
}
233236

src/plugin/ext/audio_ports_activation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ pub struct AudioPortsActivation<'a> {
1111
audio_ports_activation: NonNull<clap_plugin_audio_ports_activation>,
1212
}
1313

14-
impl<'a> Extension<&'a Plugin<'a>> for AudioPortsActivation<'a> {
14+
impl<'a> Extension for AudioPortsActivation<'a> {
1515
const IDS: &'static [&'static CStr] = &[CLAP_EXT_AUDIO_PORTS_ACTIVATION, CLAP_EXT_AUDIO_PORTS_ACTIVATION_COMPAT];
1616

17+
type Plugin = &'a Plugin<'a>;
1718
type Struct = clap_plugin_audio_ports_activation;
1819

1920
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {

src/plugin/ext/audio_ports_config.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::plugin::ext::Extension;
22
use crate::plugin::ext::ambisonic::Ambisonic;
3-
use crate::plugin::ext::audio_ports::check_audio_port_type_consistent;
3+
use crate::plugin::ext::audio_ports::{AudioPort, check_audio_port_info_valid, check_audio_port_type_consistent};
44
use crate::plugin::ext::surround::Surround;
55
use crate::plugin::instance::Plugin;
66
use crate::plugin::util::{c_char_slice_to_string, clap_call};
@@ -35,9 +35,10 @@ pub struct AudioPortsConfigConfig {
3535
pub main_output_channel_count: Option<u32>,
3636
}
3737

38-
impl<'a> Extension<&'a Plugin<'a>> for AudioPortsConfig<'a> {
38+
impl<'a> Extension for AudioPortsConfig<'a> {
3939
const IDS: &'static [&'static CStr] = &[CLAP_EXT_AUDIO_PORTS_CONFIG];
4040

41+
type Plugin = &'a Plugin<'a>;
4142
type Struct = clap_plugin_audio_ports_config;
4243

4344
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {
@@ -48,12 +49,13 @@ impl<'a> Extension<&'a Plugin<'a>> for AudioPortsConfig<'a> {
4849
}
4950
}
5051

51-
impl<'a> Extension<&'a Plugin<'a>> for AudioPortsConfigInfo<'a> {
52+
impl<'a> Extension for AudioPortsConfigInfo<'a> {
5253
const IDS: &'static [&'static CStr] = &[
5354
CLAP_EXT_AUDIO_PORTS_CONFIG_INFO,
5455
CLAP_EXT_AUDIO_PORTS_CONFIG_INFO_COMPAT,
5556
];
5657

58+
type Plugin = &'a Plugin<'a>;
5759
type Struct = clap_plugin_audio_ports_config_info;
5860

5961
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {
@@ -147,6 +149,7 @@ impl AudioPortsConfig<'_> {
147149
}
148150

149151
impl AudioPortsConfigInfo<'_> {
152+
/// Get the current selected audio ports configuration ID.
150153
pub fn current(&self) -> clap_id {
151154
let audio_ports_config_info = self.audio_ports_config_info.as_ptr();
152155
let plugin = self.plugin.as_ptr();
@@ -156,24 +159,20 @@ impl AudioPortsConfigInfo<'_> {
156159
}
157160
}
158161

159-
/// Get the raw audio port information for the given port index. This does not perform any
160-
/// consistency checks.
161-
pub fn get_raw_port_info(
162-
&self,
163-
config_id: clap_id,
164-
is_input: bool,
165-
port_index: u32,
166-
) -> Option<clap_audio_port_info> {
167-
let audio_ports_config_info = self.audio_ports_config_info.as_ptr();
168-
let plugin = self.plugin.as_ptr();
162+
/// Get information about an audio port for a configuration.
163+
pub fn get(&self, config_id: clap_id, is_input: bool, port_index: u32) -> Result<AudioPort> {
164+
let info = unsafe {
165+
let audio_ports_config_info = self.audio_ports_config_info.as_ptr();
166+
let plugin = self.plugin.as_ptr();
169167

170-
unsafe {
171168
let mut info = clap_audio_port_info { ..zeroed() };
172169
if !clap_call! { audio_ports_config_info=>get(plugin, config_id, port_index, is_input, &mut info) } {
173-
return None;
170+
anyhow::bail!("audio_ports_config_info::get() returned false");
174171
}
175172

176-
Some(info)
177-
}
173+
info
174+
};
175+
176+
check_audio_port_info_valid(self.plugin, is_input, port_index, &info)
178177
}
179178
}

src/plugin/ext/configurable_audio_ports.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ pub struct ConfigurableAudioPorts<'a> {
4343
configurable_audio_ports: NonNull<clap_plugin_configurable_audio_ports>,
4444
}
4545

46-
impl<'a> Extension<&'a Plugin<'a>> for ConfigurableAudioPorts<'a> {
46+
impl<'a> Extension for ConfigurableAudioPorts<'a> {
4747
const IDS: &'static [&'static CStr] = &[
4848
CLAP_EXT_CONFIGURABLE_AUDIO_PORTS,
4949
CLAP_EXT_CONFIGURABLE_AUDIO_PORTS_COMPAT,
5050
];
5151

52+
type Plugin = &'a Plugin<'a>;
5253
type Struct = clap_plugin_configurable_audio_ports;
5354

5455
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {

src/plugin/ext/latency.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ pub struct Latency<'a> {
1111
latency: NonNull<clap_plugin_latency>,
1212
}
1313

14-
impl<'a> Extension<&'a Plugin<'a>> for Latency<'a> {
14+
impl<'a> Extension for Latency<'a> {
1515
const IDS: &'static [&'static CStr] = &[CLAP_EXT_LATENCY];
1616

17+
type Plugin = &'a Plugin<'a>;
1718
type Struct = clap_plugin_latency;
1819

1920
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {

src/plugin/ext/note_ports.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ pub struct NotePort {
3434
pub supported_dialects: Vec<clap_note_dialect>,
3535
}
3636

37-
impl<'a> Extension<&'a Plugin<'a>> for NotePorts<'a> {
37+
impl<'a> Extension for NotePorts<'a> {
3838
const IDS: &'static [&'static CStr] = &[CLAP_EXT_NOTE_PORTS];
3939

40+
type Plugin = &'a Plugin<'a>;
4041
type Struct = clap_plugin_note_ports;
4142

4243
unsafe fn new(plugin: &'a Plugin<'a>, extension_struct: NonNull<Self::Struct>) -> Self {

0 commit comments

Comments
 (0)