@@ -2,6 +2,39 @@ use clack_common::extensions::*;
2
2
use clap_sys:: ext:: audio_ports_activation:: {
3
3
clap_plugin_audio_ports_activation, CLAP_EXT_AUDIO_PORTS_ACTIVATION ,
4
4
} ;
5
+ use std:: fmt:: Display ;
6
+
7
+ #[ repr( u32 ) ]
8
+ #[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Debug ) ]
9
+ pub enum SampleSize {
10
+ Unspecified = 0 ,
11
+ Float32 = 32 ,
12
+ Float64 = 64 ,
13
+ }
14
+
15
+ impl SampleSize {
16
+ pub fn from_raw ( raw : u32 ) -> Option < Self > {
17
+ use SampleSize :: * ;
18
+ match raw {
19
+ 0 => Some ( Unspecified ) ,
20
+ 32 => Some ( Float32 ) ,
21
+ 64 => Some ( Float64 ) ,
22
+ _ => None ,
23
+ }
24
+ }
25
+ }
26
+
27
+ impl Display for SampleSize {
28
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
29
+ let display_str = match self {
30
+ Self :: Unspecified => "Unspecified" ,
31
+ Self :: Float32 => "32-bit" ,
32
+ Self :: Float64 => "64-bit" ,
33
+ } ;
34
+
35
+ f. write_str ( display_str)
36
+ }
37
+ }
5
38
6
39
#[ derive( Copy , Clone ) ]
7
40
#[ allow( dead_code) ]
@@ -19,4 +52,122 @@ unsafe impl Extension for PluginAudioPortsActivation {
19
52
}
20
53
}
21
54
22
- // TODO: stub
55
+ #[ cfg( feature = "clack-host" ) ]
56
+ mod host {
57
+ use super :: * ;
58
+ use clack_host:: extensions:: prelude:: * ;
59
+
60
+ impl PluginAudioPortsActivation {
61
+ #[ inline]
62
+ pub fn can_activate_while_processing ( & self , plugin : & mut PluginMainThreadHandle ) -> bool {
63
+ match plugin. use_extension ( & self . 0 ) . can_activate_while_processing {
64
+ None => false ,
65
+ Some ( can_activate_while_processing) => {
66
+ #[ allow( clippy:: undocumented_unsafe_blocks) ]
67
+ unsafe {
68
+ can_activate_while_processing ( plugin. as_raw ( ) )
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ #[ inline]
75
+ pub fn set_active (
76
+ & self ,
77
+ plugin : & mut PluginSharedHandle ,
78
+ is_input : bool ,
79
+ port_index : u32 ,
80
+ is_active : bool ,
81
+ sample_size : u32 ,
82
+ ) -> bool {
83
+ match plugin. use_extension ( & self . 0 ) . set_active {
84
+ None => false ,
85
+ Some ( set_active) => {
86
+ #[ allow( clippy:: undocumented_unsafe_blocks) ]
87
+ unsafe {
88
+ set_active (
89
+ plugin. as_raw ( ) ,
90
+ is_input,
91
+ port_index,
92
+ is_active,
93
+ sample_size,
94
+ )
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ #[ cfg( feature = "clack-plugin" ) ]
103
+ mod plugin {
104
+ use super :: * ;
105
+ use clack_plugin:: extensions:: prelude:: * ;
106
+
107
+ pub trait PluginAudioPortsActivationImpl {
108
+ fn can_activate_while_processing ( & mut self ) -> bool ;
109
+ }
110
+
111
+ // NOTE: we have this trait split b/c if `PluginAudioPortsActivationImpl::can_activate_while_processing` is true,
112
+ // then `set_active` is called from the audio thread (otherwise it is called from the main thread).
113
+ pub trait PluginAudioPortsActivationSharedImpl {
114
+ fn set_active (
115
+ & self ,
116
+ is_input : bool ,
117
+ port_index : u32 ,
118
+ is_active : bool ,
119
+ sample_size : SampleSize ,
120
+ ) -> bool ;
121
+ }
122
+
123
+ // SAFETY: The given struct is the CLAP extension struct for the matching side of this extension.
124
+ unsafe impl < P : Plugin > ExtensionImplementation < P > for PluginAudioPortsActivation
125
+ where
126
+ for < ' a > P :: Shared < ' a > : PluginAudioPortsActivationSharedImpl ,
127
+ for < ' a > P :: MainThread < ' a > : PluginAudioPortsActivationImpl ,
128
+ {
129
+ const IMPLEMENTATION : RawExtensionImplementation =
130
+ RawExtensionImplementation :: new ( & clap_plugin_audio_ports_activation {
131
+ can_activate_while_processing : Some ( can_activate_while_processing :: < P > ) ,
132
+ set_active : Some ( set_active :: < P > ) ,
133
+ } ) ;
134
+ }
135
+
136
+ #[ allow( clippy:: missing_safety_doc) ]
137
+ unsafe extern "C" fn can_activate_while_processing < P : Plugin > (
138
+ plugin : * const clap_plugin ,
139
+ ) -> bool
140
+ where
141
+ for < ' a > P :: MainThread < ' a > : PluginAudioPortsActivationImpl ,
142
+ {
143
+ PluginWrapper :: < P > :: handle ( plugin, |plugin| {
144
+ Ok ( plugin
145
+ . main_thread ( )
146
+ . as_mut ( )
147
+ . can_activate_while_processing ( ) )
148
+ } )
149
+ . unwrap_or ( false )
150
+ }
151
+
152
+ #[ allow( clippy:: missing_safety_doc) ]
153
+ unsafe extern "C" fn set_active < P : Plugin > (
154
+ plugin : * const clap_plugin ,
155
+ is_input : bool ,
156
+ port_index : u32 ,
157
+ is_active : bool ,
158
+ sample_size : u32 ,
159
+ ) -> bool
160
+ where
161
+ for < ' a > P :: Shared < ' a > : PluginAudioPortsActivationSharedImpl ,
162
+ {
163
+ let sample_size = SampleSize :: from_raw ( sample_size) . unwrap ( ) ;
164
+ PluginWrapper :: < P > :: handle ( plugin, |plugin| {
165
+ Ok ( plugin
166
+ . shared ( )
167
+ . set_active ( is_input, port_index, is_active, sample_size) )
168
+ } )
169
+ . unwrap_or ( false )
170
+ }
171
+ }
172
+ #[ cfg( feature = "clack-plugin" ) ]
173
+ pub use plugin:: * ;
0 commit comments