@@ -113,7 +113,7 @@ extern crate log;
113
113
#[ macro_use]
114
114
extern crate bitflags;
115
115
116
- use std:: { mem , ptr} ;
116
+ use std:: ptr;
117
117
118
118
/// Implements `From` and `Into` for enums with `#[repr(usize)]`. Useful for interfacing with C
119
119
/// enums.
@@ -188,88 +188,98 @@ macro_rules! plugin_main {
188
188
/// Initializes a VST plugin and returns a raw pointer to an AEffect struct.
189
189
#[ doc( hidden) ]
190
190
pub fn main < T : Plugin + Default > ( callback : HostCallbackProc ) -> * mut AEffect {
191
- // Create a Box containing a zeroed AEffect. This is transmuted into a *mut pointer so that it
192
- // can be passed into the HostCallback `wrap` method. The AEffect is then updated after the vst
193
- // object is created so that the host still contains a raw pointer to the AEffect struct.
194
- let effect = unsafe { Box :: into_raw ( Box :: new ( mem:: MaybeUninit :: zeroed ( ) . assume_init ( ) ) ) } ;
191
+ // Initialize as much of the AEffect as we can before creating the plugin.
192
+ // In particular, initialize all the function pointers, since initializing
193
+ // these to zero is undefined behavior.
194
+ let boxed_effect = Box :: new ( AEffect {
195
+ magic : VST_MAGIC ,
196
+ dispatcher : interfaces:: dispatch, // fn pointer
195
197
196
- let host = HostCallback :: wrap ( callback, effect) ;
197
- if host. vst_version ( ) == 0 {
198
- // TODO: Better criteria would probably be useful here...
199
- return ptr:: null_mut ( ) ;
200
- }
198
+ _process : interfaces:: process_deprecated, // fn pointer
201
199
202
- trace ! ( "Creating VST plugin instance..." ) ;
203
- let mut plugin = T :: new ( host) ;
204
- let info = plugin. get_info ( ) ;
205
- let params = plugin. get_parameter_object ( ) ;
206
- let editor = plugin. get_editor ( ) ;
200
+ setParameter : interfaces:: set_parameter, // fn pointer
201
+ getParameter : interfaces:: get_parameter, // fn pointer
207
202
208
- // Update AEffect in place
209
- unsafe {
210
- * effect = AEffect {
211
- magic : VST_MAGIC ,
212
- dispatcher : interfaces:: dispatch, // fn pointer
213
-
214
- _process : interfaces:: process_deprecated, // fn pointer
215
-
216
- setParameter : interfaces:: set_parameter, // fn pointer
217
- getParameter : interfaces:: get_parameter, // fn pointer
218
-
219
- numPrograms : info. presets ,
220
- numParams : info. parameters ,
221
- numInputs : info. inputs ,
222
- numOutputs : info. outputs ,
203
+ numPrograms : 0 , // To be updated with plugin specific value.
204
+ numParams : 0 , // To be updated with plugin specific value.
205
+ numInputs : 0 , // To be updated with plugin specific value.
206
+ numOutputs : 0 , // To be updated with plugin specific value.
223
207
224
- flags : {
225
- use api:: PluginFlags ;
208
+ flags : 0 , // To be updated with plugin specific value.
226
209
227
- let mut flag = PluginFlags :: CAN_REPLACING ;
210
+ reserved1 : 0 ,
211
+ reserved2 : 0 ,
228
212
229
- if info. f64_precision {
230
- flag |= PluginFlags :: CAN_DOUBLE_REPLACING ;
231
- }
213
+ initialDelay : 0 , // To be updated with plugin specific value.
232
214
233
- if editor . is_some ( ) {
234
- flag |= PluginFlags :: HAS_EDITOR ;
235
- }
215
+ _realQualities : 0 ,
216
+ _offQualities : 0 ,
217
+ _ioRatio : 0.0 ,
236
218
237
- if info. preset_chunks {
238
- flag |= PluginFlags :: PROGRAM_CHUNKS ;
239
- }
219
+ object : ptr:: null_mut ( ) ,
220
+ user : ptr:: null_mut ( ) ,
240
221
241
- if let plugin:: Category :: Synth = info. category {
242
- flag |= PluginFlags :: IS_SYNTH ;
243
- }
222
+ uniqueId : 0 , // To be updated with plugin specific value.
223
+ version : 0 , // To be updated with plugin specific value.
244
224
245
- if info. silent_when_stopped {
246
- flag |= PluginFlags :: NO_SOUND_IN_STOP ;
247
- }
225
+ processReplacing : interfaces:: process_replacing, // fn pointer
226
+ processReplacingF64 : interfaces:: process_replacing_f64, //fn pointer
248
227
249
- flag. bits ( )
250
- } ,
228
+ future : [ 0u8 ; 56 ] ,
229
+ } ) ;
230
+ let raw_effect = Box :: into_raw ( boxed_effect) ;
251
231
252
- reserved1 : 0 ,
253
- reserved2 : 0 ,
232
+ let host = HostCallback :: wrap ( callback, raw_effect) ;
233
+ if host. vst_version ( ) == 0 {
234
+ // TODO: Better criteria would probably be useful here...
235
+ return ptr:: null_mut ( ) ;
236
+ }
254
237
255
- initialDelay : info. initial_delay ,
238
+ trace ! ( "Creating VST plugin instance..." ) ;
239
+ let mut plugin = T :: new ( host) ;
240
+ let info = plugin. get_info ( ) ;
241
+ let params = plugin. get_parameter_object ( ) ;
242
+ let editor = plugin. get_editor ( ) ;
256
243
257
- _realQualities : 0 ,
258
- _offQualities : 0 ,
259
- _ioRatio : 0.0 ,
244
+ // Update AEffect in place
245
+ let effect = unsafe { & mut * raw_effect } ;
246
+ effect. numPrograms = info. presets ;
247
+ effect. numParams = info. parameters ;
248
+ effect. numInputs = info. inputs ;
249
+ effect. numOutputs = info. outputs ;
250
+ effect. flags = {
251
+ use api:: PluginFlags ;
252
+
253
+ let mut flag = PluginFlags :: CAN_REPLACING ;
254
+
255
+ if info. f64_precision {
256
+ flag |= PluginFlags :: CAN_DOUBLE_REPLACING ;
257
+ }
260
258
261
- object : Box :: into_raw ( Box :: new ( Box :: new ( plugin) as Box < dyn Plugin > ) ) as * mut _ ,
262
- user : Box :: into_raw ( Box :: new ( PluginCache :: new ( & info, params, editor) ) ) as * mut _ ,
259
+ if editor. is_some ( ) {
260
+ flag |= PluginFlags :: HAS_EDITOR ;
261
+ }
263
262
264
- uniqueId : info. unique_id ,
265
- version : info. version ,
263
+ if info. preset_chunks {
264
+ flag |= PluginFlags :: PROGRAM_CHUNKS ;
265
+ }
266
266
267
- processReplacing : interfaces:: process_replacing, // fn pointer
268
- processReplacingF64 : interfaces:: process_replacing_f64, //fn pointer
267
+ if let plugin:: Category :: Synth = info. category {
268
+ flag |= PluginFlags :: IS_SYNTH ;
269
+ }
269
270
270
- future : [ 0u8 ; 56 ] ,
271
+ if info. silent_when_stopped {
272
+ flag |= PluginFlags :: NO_SOUND_IN_STOP ;
271
273
}
274
+
275
+ flag. bits ( )
272
276
} ;
277
+ effect. initialDelay = info. initial_delay ;
278
+ effect. object = Box :: into_raw ( Box :: new ( Box :: new ( plugin) as Box < dyn Plugin > ) ) as * mut _ ;
279
+ effect. user = Box :: into_raw ( Box :: new ( PluginCache :: new ( & info, params, editor) ) ) as * mut _ ;
280
+ effect. uniqueId = info. unique_id ;
281
+ effect. version = info. version ;
282
+
273
283
effect
274
284
}
275
285
0 commit comments