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