iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlug_include_in_plug_src.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
11#pragma once
12
21#pragma mark - OS_WIN
22
23// clang-format off
24
25#if defined OS_WIN && !defined VST3C_API
26 HINSTANCE gHINSTANCE = 0;
27 #if defined(VST2_API) || defined(AAX_API) || defined(CLAP_API)
28 #ifdef __MINGW32__
29 extern "C"
30 #endif
31 BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD fdwReason, LPVOID res)
32 {
33 gHINSTANCE = hDllInst;
34 return true;
35 }
36 #endif
37
38 UINT(WINAPI *__GetDpiForWindow)(HWND);
39
40 float GetScaleForHWND(HWND hWnd)
41 {
42 if (!__GetDpiForWindow)
43 {
44 HINSTANCE h = LoadLibraryW(L"user32.dll");
45 if (h) *(void **)&__GetDpiForWindow = GetProcAddress(h, "GetDpiForWindow");
46
47 if (!__GetDpiForWindow)
48 return 1;
49 }
50
51 int dpi = __GetDpiForWindow(hWnd);
52
53 if (dpi != USER_DEFAULT_SCREEN_DPI)
54 {
55#if defined IGRAPHICS_QUANTISE_SCREENSCALE
56 return std::round(static_cast<float>(dpi) / USER_DEFAULT_SCREEN_DPI);
57#else
58 return static_cast<float>(dpi) / USER_DEFAULT_SCREEN_DPI;
59#endif
60 }
61
62 return 1;
63 }
64
65#endif
66
67#pragma mark - ** Global Functions and Defines **
68
69#pragma mark - VST2
70#if defined VST2_API
71 extern "C"
72 {
73 EXPORT void* VSTPluginMain(audioMasterCallback hostCallback)
74 {
75 using namespace iplug;
76
77 IPlugVST2* pPlug = iplug::MakePlug(iplug::InstanceInfo{hostCallback});
78
79 if (pPlug)
80 {
81 AEffect& aEffect = pPlug->GetAEffect();
82 pPlug->EnsureDefaultPreset();
83 aEffect.numPrograms = std::max(aEffect.numPrograms, 1); // some hosts don't like 0 presets
84 return &aEffect;
85 }
86 return 0;
87 }
88
89 EXPORT int main(int hostCallback)
90 {
91 audioMasterCallback callback = reinterpret_cast<audioMasterCallback>(static_cast<VstIntPtr>(hostCallback));
92 return static_cast<int>(reinterpret_cast<std::uintptr_t>(VSTPluginMain(callback)));
93 }
94 };
95#pragma mark - VST3 (All)
96#elif defined VST3_API || VST3C_API || defined VST3P_API
97 #include "public.sdk/source/main/pluginfactory.h"
98 #include "pluginterfaces/vst/ivstcomponent.h"
99 #include "pluginterfaces/vst/ivsteditcontroller.h"
100
101#if !defined VST3_PROCESSOR_UID && !defined VST3_CONTROLLER_UID
102#define VST3_PROCESSOR_UID 0xF2AEE70D, 0x00DE4F4E, PLUG_MFR_ID, PLUG_UNIQUE_ID
103#define VST3_CONTROLLER_UID 0xF2AEE70E, 0x00DE4F4F, PLUG_MFR_ID, PLUG_UNIQUE_ID
104#endif
105
106 #ifndef EFFECT_TYPE_VST3
107 #if PLUG_TYPE == 1
108 #define EFFECT_TYPE_VST3 kInstrumentSynth
109 #else
110 #define EFFECT_TYPE_VST3 kFx
111 #endif
112 #endif
113
114 #if defined VST3P_API || defined VST3_API
115 bool InitModule()
116 {
117 #ifdef OS_WIN
118 extern void* moduleHandle;
119 gHINSTANCE = (HINSTANCE) moduleHandle;
120 #endif
121 return true;
122 }
123
124 // called after library is unloaded
125 bool DeinitModule()
126 {
127 return true;
128 }
129 #endif
130 #pragma mark - VST3
131 #if defined VST3_API
132 static Steinberg::FUnknown* createInstance(void*)
133 {
134 return (Steinberg::Vst::IAudioProcessor*) iplug::MakePlug(iplug::InstanceInfo());
135 }
136
137 BEGIN_FACTORY_DEF(PLUG_MFR, PLUG_URL_STR, PLUG_EMAIL_STR)
138
139 DEF_CLASS2(INLINE_UID_FROM_FUID(FUID(VST3_PROCESSOR_UID)),
140 Steinberg::PClassInfo::kManyInstances, // cardinality
141 kVstAudioEffectClass, // the component category (don't change this)
142 PLUG_NAME, // plug-in name
143 Steinberg::Vst::kSimpleModeSupported, // means gui and plugin aren't split
144 VST3_SUBCATEGORY, // Subcategory for this plug-in
145 PLUG_VERSION_STR, // plug-in version
146 kVstVersionString, // the VST 3 SDK version (don't change - use define)
147 createInstance) // function pointer called to be instantiate
148
149 END_FACTORY
150 #pragma mark - VST3 Processor
151 #elif defined VST3P_API
152 static Steinberg::FUnknown* createProcessorInstance(void*)
153 {
154 return MakeProcessor();
155 }
156
157 static Steinberg::FUnknown* createControllerInstance(void*)
158 {
159 return MakeController();
160 }
161
162 BEGIN_FACTORY_DEF(PLUG_MFR, PLUG_URL_STR, PLUG_EMAIL_STR)
163
164 DEF_CLASS2 (INLINE_UID_FROM_FUID(FUID(VST3_PROCESSOR_UID)),
165 PClassInfo::kManyInstances, // cardinality
166 kVstAudioEffectClass, // the component category (do not changed this)
167 PLUG_NAME, // here the Plug-in name (to be changed)
168 Vst::kDistributable, // means component/controller can on different computers
169 VST3_SUBCATEGORY, // Subcategory for this Plug-in (to be changed)
170 PLUG_VERSION_STR, // Plug-in version (to be changed)
171 kVstVersionString, // the VST 3 SDK version (don't change - use define)
172 createProcessorInstance) // function pointer called to be instantiate
173
174 DEF_CLASS2(INLINE_UID_FROM_FUID(FUID(VST3_CONTROLLER_UID)),
175 PClassInfo::kManyInstances, // cardinality
176 kVstComponentControllerClass, // the Controller category (do not changed this)
177 PLUG_NAME " Controller", // controller name (could be the same than component name)
178 0, // not used here
179 "", // not used here
180 PLUG_VERSION_STR, // Plug-in version (to be changed)
181 kVstVersionString, // the VST 3 SDK version (don't change - use define)
182 createControllerInstance) // function pointer called to be instantiate
183
184 END_FACTORY
185 #endif
186#pragma mark - AUv2
187#elif defined AU_API
188 extern "C"
189 {
190 #ifndef AU_NO_COMPONENT_ENTRY
191 //Component Manager
192 EXPORT ComponentResult AUV2_ENTRY(ComponentParameters* pParams, void* pPlug)
193 {
194 return iplug::IPlugAU::IPlugAUEntry(pParams, pPlug);
195 }
196 #endif
197
198 //>10.7 SDK AUPlugin
199 EXPORT void* AUV2_FACTORY(const AudioComponentDescription* pInDesc)
200 {
201 return iplug::IPlugAUFactory<PLUG_CLASS_NAME, PLUG_DOES_MIDI_IN>::Factory(pInDesc);
202 }
203 };
204#pragma mark - WAM
205#elif defined WAM_API
206 extern "C"
207 {
208 EMSCRIPTEN_KEEPALIVE void* createModule()
209 {
210 Processor* pWAM = dynamic_cast<Processor*>(iplug::MakePlug(iplug::InstanceInfo()));
211 return (void*) pWAM;
212 }
213 }
214#pragma mark - WEB
215#elif defined WEB_API
216#include <memory>
217#include "config.h"
218 std::unique_ptr<iplug::IPlugWeb> gPlug;
219 extern void StartMainLoopTimer();
220
221 extern "C"
222 {
223 EMSCRIPTEN_KEEPALIVE void iplug_syncfs()
224 {
225 EM_ASM({
226 if(Module.syncdone == 1) {
227 Module.syncdone = 0;
228 FS.syncfs(false, function (err) {
229 assert(!err);
230 console.log("Synced to IDBFS...");
231 Module.syncdone = 1;
232 });
233 }
234 });
235 }
236
237 EMSCRIPTEN_KEEPALIVE void iplug_fsready()
238 {
239 gPlug = std::unique_ptr<iplug::IPlugWeb>(iplug::MakePlug(iplug::InstanceInfo()));
240 gPlug->SetHost("www", 0);
241 gPlug->OpenWindow(nullptr);
242 iplug_syncfs(); // plug in may initialise settings in constructor, write to persistent data after init
243 }
244 }
245
246 int main()
247 {
248 //create persistent data file system and synchronise
249 EM_ASM(
250 var name = '/' + UTF8ToString($0) + '_data';
251 FS.mkdir(name);
252 FS.mount(IDBFS, {}, name);
253
254 Module.syncdone = 0;
255 FS.syncfs(true, function (err) {
256 assert(!err);
257 console.log("Synced from IDBFS...");
258 Module.syncdone = 1;
259 ccall('iplug_fsready', 'v');
260 });
261 , PLUG_NAME);
262
263 StartMainLoopTimer();
264
265 // TODO: this code never runs, so when do we delete?!
266 gPlug = nullptr;
267
268 return 0;
269 }
270
271#pragma mark - CLAP
272#elif defined CLAP_API
273
274// Make sure optional fields are defined
275
276#ifndef CLAP_MANUAL_URL
277#define CLAP_MANUAL_URL ""
278#endif
279#ifndef CLAP_SUPPORT_URL
280#define CLAP_SUPPORT_URL ""
281#endif
282#ifndef CLAP_DESCRIPTION
283#define CLAP_DESCRIPTION ""
284#endif
285#ifndef CLAP_FEATURES
286 #if PLUG_TYPE==0
287 #define CLAP_FEATURES CLAP_PLUGIN_FEATURE_AUDIO_EFFECT
288 #elif PLUG_TYPE==1
289 #define CLAP_FEATURES CLAP_PLUGIN_FEATURE_INSTRUMENT
290 #elif PLUG_TYPE==2
291 #define CLAP_FEATURES CLAP_PLUGIN_FEATURE_NOTE_EFFECT
292 #endif
293#endif
294
295std::string gPluginPath;
296std::unique_ptr<clap_plugin_descriptor> gPluginDesc;
297
298static bool clap_init(const char* pluginPath)
299{
300 // Init globals
301
302 gPluginPath = pluginPath;
303 gPluginDesc = std::unique_ptr<clap_plugin_descriptor>(new clap_plugin_descriptor());
304
305 // Init the descriptor
306
307 gPluginDesc->clap_version = CLAP_VERSION;
308
309 gPluginDesc->id = BUNDLE_DOMAIN "." BUNDLE_MFR "." BUNDLE_NAME;
310 gPluginDesc->name = PLUG_NAME;
311 gPluginDesc->vendor = PLUG_MFR;
312 gPluginDesc->url = PLUG_URL_STR;
313
314 gPluginDesc->manual_url = CLAP_MANUAL_URL;
315 gPluginDesc->version = PLUG_VERSION_STR;
316 gPluginDesc->support_url = CLAP_SUPPORT_URL;
317 gPluginDesc->description = CLAP_DESCRIPTION;
318
319 static const char *clap_features[] = { CLAP_FEATURES, NULL };
320 gPluginDesc->features = clap_features;
321
322 return true;
323}
324
325static void clap_deinit(void)
326{
327 gPluginPath.clear();
328 gPluginDesc = nullptr;
329}
330
331static uint32_t clap_get_plugin_count(const clap_plugin_factory_t *factory)
332{
333 return 1;
334}
335
336static const clap_plugin_descriptor* clap_get_plugin_descriptor(const clap_plugin_factory_t *factory, uint32_t index)
337{
338 if (!index)
339 return gPluginDesc.get();
340
341 return nullptr;
342}
343
344static const clap_plugin* clap_create_plugin(const clap_plugin_factory_t *factory, const clap_host* host, const char* plugin_id)
345{
346 if (!strcmp(gPluginDesc->id, plugin_id))
347 {
348 IPlugCLAP* pPlug = MakePlug(InstanceInfo{gPluginDesc.get(), host});
349 return pPlug->clapPlugin();
350 }
351
352 return nullptr;
353}
354
355CLAP_EXPORT const clap_plugin_factory_t clap_factory = {
356 clap_get_plugin_count,
357 clap_get_plugin_descriptor,
358 clap_create_plugin,
359};
360
361const void *clap_get_factory(const char *factory_id)
362{
363 if (!::strcmp(factory_id, CLAP_PLUGIN_FACTORY_ID))
364 return &clap_factory;
365
366 return nullptr;
367}
368
369CLAP_EXPORT const clap_plugin_entry_t clap_entry = {
370 CLAP_VERSION,
371 clap_init,
372 clap_deinit,
373 clap_get_factory,
374};
375
376#elif defined AUv3_API || defined AAX_API || defined APP_API
377// Nothing to do here
378#else
379 #error "No API defined!"
380#endif
381
382#pragma mark - ** Instantiation **
383
384BEGIN_IPLUG_NAMESPACE
385
386#pragma mark -
387#pragma mark VST2, VST3, AAX, AUv3, APP, WAM, WEB, CLAP
388
389#if defined VST2_API || defined VST3_API || defined AAX_API || defined AUv3_API || defined APP_API || defined WAM_API || defined WEB_API || defined CLAP_API
390
391Plugin* MakePlug(const iplug::InstanceInfo& info)
392{
393 // From VST3 - is this necessary?
394 static WDL_Mutex sMutex;
395 WDL_MutexLock lock(&sMutex);
396
397 return new PLUG_CLASS_NAME(info);
398}
399
400#pragma mark - AUv2
401#elif defined AU_API
402
403Plugin* MakePlug(void* pMemory)
404{
405 iplug::InstanceInfo info;
406 info.mCocoaViewFactoryClassName.Set(AUV2_VIEW_CLASS_STR);
407
408 if (pMemory)
409 return new(pMemory) PLUG_CLASS_NAME(info);
410 else
411 return new PLUG_CLASS_NAME(info);
412}
413
414#pragma mark - VST3 Controller
415#elif defined VST3C_API
416
417Steinberg::FUnknown* MakeController()
418{
419 static WDL_Mutex sMutex;
420 WDL_MutexLock lock(&sMutex);
421 iplug::IPlugVST3Controller::InstanceInfo info;
422 info.mOtherGUID = Steinberg::FUID(VST3_PROCESSOR_UID);
423 // If you are trying to build a distributed VST3 plug-in and you hit an error here like "no matching constructor..." or
424 // "error: unknown type name 'VST3Controller'", you need to replace all instances of the name of your plug-in class (e.g. IPlugEffect)
425 // with the macro PLUG_CLASS_NAME, as defined in your plug-ins config.h, so IPlugEffect::IPlugEffect() {} becomes PLUG_CLASS_NAME::PLUG_CLASS_NAME().
426 return static_cast<Steinberg::Vst::IEditController*>(new PLUG_CLASS_NAME(info));
427}
428
429#pragma mark - VST3 Processor
430#elif defined VST3P_API
431
432Steinberg::FUnknown* MakeProcessor()
433{
434 static WDL_Mutex sMutex;
435 WDL_MutexLock lock(&sMutex);
436 iplug::IPlugVST3Processor::InstanceInfo info;
437 info.mOtherGUID = Steinberg::FUID(VST3_CONTROLLER_UID);
438 return static_cast<Steinberg::Vst::IAudioProcessor*>(new PLUG_CLASS_NAME(info));
439}
440#else
441#error "No API defined!"
442#endif
443
444#pragma mark - ** Config Utility **
445
446static Config MakeConfig(int nParams, int nPresets)
447{
448 return Config(nParams, nPresets, PLUG_CHANNEL_IO, PLUG_NAME, PLUG_NAME, PLUG_MFR, PLUG_VERSION_HEX, PLUG_UNIQUE_ID, PLUG_MFR_ID, PLUG_LATENCY, PLUG_DOES_MIDI_IN, PLUG_DOES_MIDI_OUT, PLUG_DOES_MPE, PLUG_DOES_STATE_CHUNKS, PLUG_TYPE, PLUG_HAS_UI, PLUG_WIDTH, PLUG_HEIGHT, PLUG_HOST_RESIZE, PLUG_MIN_WIDTH, PLUG_MAX_WIDTH, PLUG_MIN_HEIGHT, PLUG_MAX_HEIGHT, BUNDLE_ID, APP_GROUP_ID); // TODO: Product Name?
449}
450
451END_IPLUG_NAMESPACE
452
453/*
454 #if defined _DEBUG
455 #define PLUG_NAME APPEND_TIMESTAMP(PLUG_NAME " DEBUG")
456 #elif defined TRACER_BUILD
457 #define PLUG_NAME APPEND_TIMESTAMP(PLUG_NAME " TRACER")
458 #elif defined TIMESTAMP_PLUG_NAME
459 #pragma REMINDER("plug name is timestamped")
460 #define PLUG_NAME APPEND_TIMESTAMP(PLUG_NAME)
461 #else
462 #define PLUG_NAME PLUG_NAME
463 #endif
464 */
465
466#if !defined NO_IGRAPHICS && !defined VST3P_API
467#include "IGraphics_include_in_plug_src.h"
468#endif
469
470// clang-format on
CLAP API base class for an IPlug plug-in.
Definition: IPlugCLAP.h:50
VST2.4 API base class for an IPlug plug-in.
Definition: IPlugVST2.h:36
void EnsureDefaultPreset()
[VST2 only] Called to fill uninitialzed presets