iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugLogger.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
22#include <cstdio>
23#include <cctype>
24#include <cstdarg>
25#include <cstdint>
26#include <cstring>
27#include <ctime>
28#include <cassert>
29
30#include "wdlstring.h"
31#include "mutex.h"
32
33#include "IPlugConstants.h"
34#include "IPlugUtilities.h"
35
36BEGIN_IPLUG_NAMESPACE
37
38#ifdef NDEBUG
39 #define DBGMSG(...) do {} while(0)// should be optimized away
40#else
41 #if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_WEB) || defined(OS_IOS)
42 #define DBGMSG(...) printf(__VA_ARGS__)
43 #elif defined OS_WIN
44 static void DBGMSG(const char* format, ...)
45 {
46 char buf[4096];
47 va_list args;
48 int n;
49
50 va_start(args, format);
51 n = vsnprintf_s(buf, sizeof buf, sizeof buf - 1, format, args);
52 va_end(args);
53
54 OutputDebugStringW(UTF8AsUTF16(buf).Get());
55 }
56 #endif
57#endif
58
59#if defined TRACER_BUILD
60 #define TRACE Trace(TRACELOC, "");
61
62 #if defined OS_WIN
63 #define SYS_THREAD_ID (intptr_t) GetCurrentThreadId()
64 #elif defined(OS_MAC) || defined(OS_LINUX) || defined(OS_WEB)
65 #define SYS_THREAD_ID (intptr_t) pthread_self()
66 #endif
67
68 #else
69 #define TRACE
70 #endif
71
72 #define TRACELOC __FUNCTION__,__LINE__
73 static void Trace(const char* funcName, int line, const char* fmtStr, ...);
74
75 #define APPEND_TIMESTAMP(str) AppendTimestamp(__DATE__, __TIME__, str)
76
77 struct LogFile
78 {
79 FILE* mFP;
80 static LogFile* sInstance;
81
82 static LogFile* GetInstance()
83 {
84 if (!sInstance)
85 sInstance = new LogFile();
86 return sInstance;
87 }
88
89 LogFile()
90 {
91 #ifdef OS_WIN
92 char logFilePath[MAX_WIN32_PATH_LEN];
93 snprintf(logFilePath, MAX_WIN32_PATH_LEN,"%s/%s", "C:\\", LOGFILE);
94 #else
95 char logFilePath[MAX_MACOS_PATH_LEN];
96 snprintf(logFilePath, MAX_MACOS_PATH_LEN, "%s/%s", getenv("HOME"), LOGFILE);
97 #endif
98 mFP = fopenUTF8(logFilePath, "w");
99 assert(mFP);
100
101 DBGMSG("Logging to %s\n", logFilePath);
102 }
103
104 ~LogFile()
105 {
106 if (mFP)
107 {
108 fclose(mFP);
109 mFP = nullptr;
110 }
111 }
112
113 LogFile(const LogFile&) = delete;
114 LogFile& operator=(const LogFile&) = delete;
115 };
116
117 inline LogFile* LogFile::sInstance = nullptr;
118
119 static bool IsWhitespace(char c)
120 {
121 return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
122 }
123
124 static const char* CurrentTime()
125 {
126 // TODO: replace with std::chrono based version
127 time_t t = time(0);
128 tm* pT = localtime(&t);
129
130 char cStr[32];
131 strftime(cStr, 32, "%Y%m%d %H:%M ", pT);
132
133 int tz = 60 * pT->tm_hour + pT->tm_min;
134 int yday = pT->tm_yday;
135 pT = gmtime(&t);
136 tz -= 60 * pT->tm_hour + pT->tm_min;
137 yday -= pT->tm_yday;
138 if (yday != 0)
139 {
140 if (yday > 1) yday = -1;
141 else if (yday < -1) yday = 1;
142 tz += 24 * 60 * yday;
143 }
144 int i = (int) strlen(cStr);
145 cStr[i++] = tz >= 0 ? '+' : '-';
146 if (tz < 0) tz = -tz;
147 snprintf(&cStr[i], 32, "%02d%02d", tz / 60, tz % 60);
148
149 static char sTimeStr[32];
150 strcpy(sTimeStr, cStr);
151 return sTimeStr;
152 }
153
154 static const char* AppendTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, const char* cStr)
155 {
156 static WDL_String str;
157 str.Set(cStr);
158 str.Append(" ");
159 WDL_String tStr;
160 tStr.Set("[");
161 tStr.Append(Mmm_dd_yyyy);
162 tStr.SetLen(7);
163 tStr.DeleteSub(4, 1);
164 tStr.Append(" ");
165 tStr.Append(hh_mm_ss);
166 tStr.SetLen(12);
167 tStr.Append("]");
168 str.Append(tStr.Get());
169 return str.Get();
170 }
171
172 #if defined TRACER_BUILD
173
174 const int TXTLEN = 1024;
175
176 // _vsnsprintf
177
178 #define VARARGS_TO_STR(str) { \
179 try { \
180 va_list argList; \
181 va_start(argList, format); \
182 int i = vsnprintf(str, TXTLEN-2, format, argList); \
183 if (i < 0 || i > TXTLEN-2) { \
184 str[TXTLEN-1] = '\0'; \
185 } \
186 va_end(argList); \
187 } \
188 catch(...) { \
189 strcpy(str, "parse error"); \
190 } \
191 strcat(str, "\r\n"); \
192 }
193
194 static intptr_t GetOrdinalThreadID(intptr_t sysThreadID)
195 {
196 static WDL_TypedBuf<intptr_t> sThreadIDs;
197 int i, n = sThreadIDs.GetSize();
198 intptr_t* pThreadID = sThreadIDs.Get();
199 for (i = 0; i < n; ++i, ++pThreadID)
200 {
201 if (sysThreadID == *pThreadID)
202 {
203 return i;
204 }
205 }
206 sThreadIDs.Resize(n + 1);
207 *(sThreadIDs.Get() + n) = sysThreadID;
208 return n;
209 }
210
211 #define MAX_LOG_LINES 16384
212 void Trace(const char* funcName, int line, const char* format, ...)
213 {
214 static int sTrace = 0;
215 static int32_t sProcessCount = 0;
216 static int32_t sIdleCount = 0;
217
218 if (sTrace++ < MAX_LOG_LINES)
219 {
220 #ifndef TRACETOSTDOUT
221 LogFile* sLogFile = LogFile::GetInstance();
222 assert(sLogFile->mFP);
223 #endif
224 static WDL_Mutex sLogMutex;
225 char str[TXTLEN];
226 VARARGS_TO_STR(str);
227
228 #ifdef TRACETOSTDOUT
229 DBGMSG("[%ld:%s:%d]%s", GetOrdinalThreadID(SYS_THREAD_ID), funcName, line, str);
230 #else
231 WDL_MutexLock lock(&sLogMutex);
232 intptr_t threadID = GetOrdinalThreadID(SYS_THREAD_ID);
233
234 if(strstr(funcName, "rocess") || strstr(funcName, "ender")) // These are not typos! by excluding the first character, we can use TRACE in methods called ProcessXXX or process etc.
235 {
236 if(++sProcessCount > MAX_PROCESS_TRACE_COUNT)
237 {
238 fflush(sLogFile->mFP);
239 return;
240 }
241 else if (sProcessCount == MAX_PROCESS_TRACE_COUNT)
242 {
243 fprintf(sLogFile->mFP, "**************** DISABLING PROCESS TRACING AFTER %d HITS ****************\n\n", sProcessCount);
244 fflush(sLogFile->mFP);
245 return;
246 }
247 }
248
249#ifdef VST2_API
250 if(strstr(str, "effGetProgram") || strstr(str, "effEditGetRect") || strstr(funcName, "MouseOver"))
251#else
252 if(strstr(funcName, "MouseOver") || strstr(funcName, "idle"))
253#endif
254 {
255 if(++sIdleCount > MAX_IDLE_TRACE_COUNT)
256 {
257 fflush(sLogFile->mFP);
258 return;
259 }
260 else if (sIdleCount == MAX_IDLE_TRACE_COUNT)
261 {
262 fprintf(sLogFile->mFP, "**************** DISABLING IDLE/MOUSEOVER TRACING AFTER %d HITS ****************\n", sIdleCount);
263 fflush(sLogFile->mFP);
264 return;
265 }
266 }
267
268 if (threadID > 0)
269 fprintf(sLogFile->mFP, "*** -");
270
271 fprintf(sLogFile->mFP, "[%ld:%s:%d]%s", threadID, funcName, line, str);
272 fflush(sLogFile->mFP);
273 #endif
274 }
275 }
276
277 #ifdef VST2_API
278 #include "aeffectx.h"
279 static const char* VSTOpcodeStr(int opCode)
280 {
281 switch (opCode)
282 {
283 case effOpen:
284 return "effOpen";
285 case effClose:
286 return "effClose";
287 case effSetProgram:
288 return "effSetProgram";
289 case effGetProgram:
290 return "effGetProgram";
291 case effSetProgramName:
292 return "effSetProgramName";
293 case effGetProgramName:
294 return "effGetProgramName";
295 case effGetParamLabel:
296 return "effGetParamLabel";
297 case effGetParamDisplay:
298 return "effGetParamDisplay";
299 case effGetParamName:
300 return "effGetParamName";
301 case __effGetVuDeprecated:
302 return "__effGetVuDeprecated";
303 case effSetSampleRate:
304 return "effSetSampleRate";
305 case effSetBlockSize:
306 return "effSetBlockSize";
307 case effMainsChanged:
308 return "effMainsChanged";
309 case effEditGetRect:
310 return "effEditGetRect";
311 case effEditOpen:
312 return "effEditOpen";
313 case effEditClose:
314 return "effEditClose";
315 case __effEditDrawDeprecated:
316 return "__effEditDrawDeprecated";
317 case __effEditMouseDeprecated:
318 return "__effEditMouseDeprecated";
319 case __effEditKeyDeprecated:
320 return "__effEditKeyDeprecated";
321 case effEditIdle:
322 return "effEditIdle";
323 case __effEditTopDeprecated:
324 return "__effEditTopDeprecated";
325 case __effEditSleepDeprecated:
326 return "__effEditSleepDeprecated";
327 case __effIdentifyDeprecated:
328 return "__effIdentifyDeprecated";
329 case effGetChunk:
330 return "effGetChunk";
331 case effSetChunk:
332 return "effSetChunk";
333 case effProcessEvents:
334 return "effProcessEvents";
335 case effCanBeAutomated:
336 return "effCanBeAutomated";
337 case effString2Parameter:
338 return "effString2Parameter";
339 case __effGetNumProgramCategoriesDeprecated:
340 return "__effGetNumProgramCategoriesDeprecated";
341 case effGetProgramNameIndexed:
342 return "effGetProgramNameIndexed";
343 case __effCopyProgramDeprecated:
344 return "__effCopyProgramDeprecated";
345 case __effConnectInputDeprecated:
346 return "__effConnectInputDeprecated";
347 case __effConnectOutputDeprecated:
348 return "__effConnectOutputDeprecated";
349 case effGetInputProperties:
350 return "effGetInputProperties";
351 case effGetOutputProperties:
352 return "effGetOutputProperties";
353 case effGetPlugCategory:
354 return "effGetPlugCategory";
355 case __effGetCurrentPositionDeprecated:
356 return "__effGetCurrentPositionDeprecated";
357 case __effGetDestinationBufferDeprecated:
358 return "__effGetDestinationBufferDeprecated";
359 case effOfflineNotify:
360 return "effOfflineNotify";
361 case effOfflinePrepare:
362 return "effOfflinePrepare";
363 case effOfflineRun:
364 return "effOfflineRun";
365 case effProcessVarIo:
366 return "effProcessVarIo";
367 case effSetSpeakerArrangement:
368 return "effSetSpeakerArrangement";
369 case __effSetBlockSizeAndSampleRateDeprecated:
370 return "__effSetBlockSizeAndSampleRateDeprecated";
371 case effSetBypass:
372 return "effSetBypass";
373 case effGetEffectName:
374 return "effGetEffectName";
375 case __effGetErrorTextDeprecated:
376 return "__effGetErrorTextDeprecated";
377 case effGetVendorString:
378 return "effGetVendorString";
379 case effGetProductString:
380 return "effGetProductString";
381 case effGetVendorVersion:
382 return "effGetVendorVersion";
383 case effVendorSpecific:
384 return "effVendorSpecific";
385 case effCanDo:
386 return "effCanDo";
387 case effGetTailSize:
388 return "effGetTailSize";
389 case __effIdleDeprecated:
390 return "__effIdleDeprecated";
391 case __effGetIconDeprecated:
392 return "__effGetIconDeprecated";
393 case __effSetViewPositionDeprecated:
394 return "__effSetViewPositionDeprecated";
395 case effGetParameterProperties:
396 return "effGetParameterProperties";
397 case __effKeysRequiredDeprecated:
398 return "__effKeysRequiredDeprecated";
399 case effGetVstVersion:
400 return "effGetVstVersion";
401 case effEditKeyDown:
402 return "effEditKeyDown";
403 case effEditKeyUp:
404 return "effEditKeyUp";
405 case effSetEditKnobMode:
406 return "effSetEditKnobMode";
407 case effGetMidiProgramName:
408 return "effGetMidiProgramName";
409 case effGetCurrentMidiProgram:
410 return "effGetCurrentMidiProgram";
411 case effGetMidiProgramCategory:
412 return "effGetMidiProgramCategory";
413 case effHasMidiProgramsChanged:
414 return "effHasMidiProgramsChanged";
415 case effGetMidiKeyName:
416 return "effGetMidiKeyName";
417 case effBeginSetProgram:
418 return "effBeginSetProgram";
419 case effEndSetProgram:
420 return "effEndSetProgram";
421 case effGetSpeakerArrangement:
422 return "effGetSpeakerArrangement";
423 case effShellGetNextPlugin:
424 return "effShellGetNextPlugin";
425 case effStartProcess:
426 return "effStartProcess";
427 case effStopProcess:
428 return "effStopProcess";
429 case effSetTotalSampleToProcess:
430 return "effSetTotalSampleToProcess";
431 case effSetPanLaw:
432 return "effSetPanLaw";
433 case effBeginLoadBank:
434 return "effBeginLoadBank";
435 case effBeginLoadProgram:
436 return "effBeginLoadProgram";
437 case effSetProcessPrecision:
438 return "effSetProcessPrecision";
439 case effGetNumMidiInputChannels:
440 return "effGetNumMidiInputChannels";
441 case effGetNumMidiOutputChannels:
442 return "effGetNumMidiOutputChannels";
443 default:
444 return "unknown";
445 }
446 }
447 #endif
448
449 #if defined AU_API
450 #include <AudioUnit/AudioUnitProperties.h>
451 #include <CoreServices/CoreServices.h>
452 static const char* AUSelectStr(int select)
453 {
454 switch (select)
455 {
456 case kComponentOpenSelect:
457 return "kComponentOpenSelect";
458 case kComponentCloseSelect:
459 return "kComponentCloseSelect";
460 case kComponentVersionSelect:
461 return "kComponentVersionSelect";
462 case kAudioUnitInitializeSelect:
463 return "kAudioUnitInitializeSelect";
464 case kAudioUnitUninitializeSelect:
465 return "kAudioUnitUninitializeSelect";
466 case kAudioUnitGetPropertyInfoSelect:
467 return "kAudioUnitGetPropertyInfoSelect";
468 case kAudioUnitGetPropertySelect:
469 return "kAudioUnitGetPropertySelect";
470 case kAudioUnitSetPropertySelect:
471 return "kAudioUnitSetPropertySelect";
472 case kAudioUnitAddPropertyListenerSelect:
473 return "kAudioUnitAddPropertyListenerSelect";
474 case kAudioUnitRemovePropertyListenerSelect:
475 return "kAudioUnitRemovePropertyListenerSelect";
476 case kAudioUnitAddRenderNotifySelect:
477 return "kAudioUnitAddRenderNotifySelect";
478 case kAudioUnitRemoveRenderNotifySelect:
479 return "kAudioUnitRemoveRenderNotifySelect";
480 case kAudioUnitGetParameterSelect:
481 return "kAudioUnitGetParameterSelect";
482 case kAudioUnitSetParameterSelect:
483 return "kAudioUnitSetParameterSelect";
484 case kAudioUnitScheduleParametersSelect:
485 return "kAudioUnitScheduleParametersSelect";
486 case kAudioUnitRenderSelect:
487 return "kAudioUnitRenderSelect";
488 case kAudioUnitResetSelect:
489 return "kAudioUnitResetSelect";
490 case kComponentCanDoSelect:
491 return "kComponentCanDoSelect";
492 case kAudioUnitComplexRenderSelect:
493 return "kAudioUnitComplexRenderSelect";
494 case kAudioUnitProcessSelect:
495 return "kAudioUnitProcessSelect";
496 case kAudioUnitProcessMultipleSelect:
497 return "kAudioUnitProcessMultipleSelect";
498 case kAudioUnitRange:
499 return "kAudioUnitRange";
500 case kAudioUnitRemovePropertyListenerWithUserDataSelect:
501 return "kAudioUnitRemovePropertyListenerWithUserDataSelect";
502 default:
503 return "unknown";
504 }
505 }
506
507 static const char* AUPropertyStr(int propID)
508 {
509 switch (propID)
510 {
511 case kAudioUnitProperty_ClassInfo:
512 return "kAudioUnitProperty_ClassInfo";
513 case kAudioUnitProperty_MakeConnection:
514 return "kAudioUnitProperty_MakeConnection";
515 case kAudioUnitProperty_SampleRate:
516 return "kAudioUnitProperty_SampleRate";
517 case kAudioUnitProperty_ParameterList:
518 return "kAudioUnitProperty_ParameterList";
519 case kAudioUnitProperty_ParameterInfo:
520 return "kAudioUnitProperty_ParameterInfo";
521 case kAudioUnitProperty_FastDispatch:
522 return "kAudioUnitProperty_FastDispatch";
523 case kAudioUnitProperty_CPULoad:
524 return "kAudioUnitProperty_CPULoad";
525 case kAudioUnitProperty_StreamFormat:
526 return "kAudioUnitProperty_StreamFormat";
527 case kAudioUnitProperty_ElementCount:
528 return "kAudioUnitProperty_ElementCount";
529 case kAudioUnitProperty_Latency:
530 return "kAudioUnitProperty_Latency";
531 case kAudioUnitProperty_SupportedNumChannels:
532 return "kAudioUnitProperty_SupportedNumChannels";
533 case kAudioUnitProperty_MaximumFramesPerSlice:
534 return "kAudioUnitProperty_MaximumFramesPerSlice";
535 case kAudioUnitProperty_SetExternalBuffer:
536 return "kAudioUnitProperty_SetExternalBuffer";
537 case kAudioUnitProperty_ParameterValueStrings:
538 return "kAudioUnitProperty_ParameterValueStrings";
539 case kAudioUnitProperty_GetUIComponentList:
540 return "kAudioUnitProperty_GetUIComponentList";
541 case kAudioUnitProperty_AudioChannelLayout:
542 return "kAudioUnitProperty_AudioChannelLayout";
543 case kAudioUnitProperty_TailTime:
544 return "kAudioUnitProperty_TailTime";
545 case kAudioUnitProperty_BypassEffect:
546 return "kAudioUnitProperty_BypassEffect";
547 case kAudioUnitProperty_LastRenderError:
548 return "kAudioUnitProperty_LastRenderError";
549 case kAudioUnitProperty_SetRenderCallback:
550 return "kAudioUnitProperty_SetRenderCallback";
551 case kAudioUnitProperty_FactoryPresets:
552 return "kAudioUnitProperty_FactoryPresets";
553 case kAudioUnitProperty_ContextName:
554 return "kAudioUnitProperty_ContextName";
555 case kAudioUnitProperty_RenderQuality:
556 return "kAudioUnitProperty_RenderQuality";
557 case kAudioUnitProperty_HostCallbacks:
558 return "kAudioUnitProperty_HostCallbacks";
559 case kAudioUnitProperty_CurrentPreset:
560 return "kAudioUnitProperty_CurrentPreset";
561 case kAudioUnitProperty_InPlaceProcessing:
562 return "kAudioUnitProperty_InPlaceProcessing";
563 case kAudioUnitProperty_ElementName:
564 return "kAudioUnitProperty_ElementName";
565 case kAudioUnitProperty_CocoaUI:
566 return "kAudioUnitProperty_CocoaUI";
567 case kAudioUnitProperty_SupportedChannelLayoutTags:
568 return "kAudioUnitProperty_SupportedChannelLayoutTags";
569 case kAudioUnitProperty_ParameterIDName:
570 return "kAudioUnitProperty_ParameterIDName";
571 case kAudioUnitProperty_ParameterClumpName:
572 return "kAudioUnitProperty_ParameterClumpName";
573 case kAudioUnitProperty_PresentPreset:
574 return "kAudioUnitProperty_PresentPreset";
575 case kAudioUnitProperty_OfflineRender:
576 return "kAudioUnitProperty_OfflineRender";
577 case kAudioUnitProperty_ParameterStringFromValue:
578 return "kAudioUnitProperty_ParameterStringFromValue";
579 case kAudioUnitProperty_ParameterValueFromString:
580 return "kAudioUnitProperty_ParameterValueFromString";
581 case kAudioUnitProperty_IconLocation:
582 return "kAudioUnitProperty_IconLocation";
583 case kAudioUnitProperty_PresentationLatency:
584 return "kAudioUnitProperty_PresentationLatency";
585 case kAudioUnitProperty_DependentParameters:
586 return "kAudioUnitProperty_DependentParameters";
587 case kAudioUnitProperty_AUHostIdentifier:
588 return "kAudioUnitProperty_AUHostIdentifier";
589 case kAudioUnitProperty_MIDIOutputCallbackInfo:
590 return "kAudioUnitProperty_MIDIOutputCallbackInfo";
591 case kAudioUnitProperty_MIDIOutputCallback:
592 return "kAudioUnitProperty_MIDIOutputCallback";
593 case kAudioUnitProperty_InputSamplesInOutput:
594 return "kAudioUnitProperty_InputSamplesInOutput";
595 case kAudioUnitProperty_ClassInfoFromDocument:
596 return "kAudioUnitProperty_ClassInfoFromDocument";
597 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1010
598 case kAudioUnitProperty_ShouldAllocateBuffer:
599 return "kAudioUnitProperty_ShouldAllocateBuffer";
600 case kAudioUnitProperty_FrequencyResponse:
601 return "kAudioUnitProperty_FrequencyResponse";
602 case kAudioUnitProperty_ParameterHistoryInfo:
603 return "kAudioUnitProperty_FrequencyResponse";
604 case kAudioUnitProperty_NickName:
605 return "kAudioUnitProperty_NickName";
606 #endif
607 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1011
608 case kAudioUnitProperty_RequestViewController:
609 return "kAudioUnitProperty_RequestViewController";
610 case kAudioUnitProperty_ParametersForOverview:
611 return "kAudioUnitProperty_ParametersForOverview";
612 case kAudioUnitProperty_SupportsMPE:
613 return "kAudioUnitProperty_SupportsMPE";
614 #endif
615 default:
616 return "unknown";
617 }
618 }
619
620 static const char* AUScopeStr(int scope)
621 {
622 switch (scope)
623 {
624 case kAudioUnitScope_Global:
625 return "kAudioUnitScope_Global";
626 case kAudioUnitScope_Input:
627 return "kAudioUnitScope_Input";
628 case kAudioUnitScope_Output:
629 return "kAudioUnitScope_Output";
630 case kAudioUnitScope_Group:
631 return "kAudioUnitScope_Group";
632 case kAudioUnitScope_Part:
633 return "kAudioUnitScope_Part";
634 case kAudioUnitScope_Note:
635 return "kAudioUnitScope_Note";
636 default:
637 return "unknown";
638 }
639 }
640 #endif // AU_API
641
642#else // TRACER_BUILD
643 static void Trace(const char* funcName, int line, const char* format, ...) {}
644static const char* VSTOpcodeStr(int opCode) { return ""; }
645 static const char* AUSelectStr(int select) { return ""; }
646 static const char* AUPropertyStr(int propID) { return ""; }
647 static const char* AUScopeStr(int scope) { return ""; }
648#endif // !TRACER_BUILD
649
650END_IPLUG_NAMESPACE
IPlug Constant definitions, Types, magic numbers.
Utility functions and macros.