Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoPluginVST.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |
4 * | |
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
6 * or without fee is hereby granted, provided that the above copyright notice and this | |
7 * permission notice appear in all copies. | |
8 * | |
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #ifndef DISTRHO_PLUGIN_VST_HPP_INCLUDED | |
18 #define DISTRHO_PLUGIN_VST_HPP_INCLUDED | |
19 | |
20 #include "DistrhoPluginChecks.h" | |
21 #include "../DistrhoUtils.hpp" | |
22 | |
23 #include <algorithm> | |
24 #include <cmath> | |
25 | |
26 #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EMBED_UI | |
27 # undef DISTRHO_PLUGIN_HAS_UI | |
28 # define DISTRHO_PLUGIN_HAS_UI 0 | |
29 #endif | |
30 | |
31 #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |
32 # undef DISTRHO_PLUGIN_HAS_UI | |
33 # define DISTRHO_PLUGIN_HAS_UI 0 | |
34 #endif | |
35 | |
36 #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |
37 # include "Base.hpp" | |
38 #endif | |
39 | |
40 #if DISTRHO_PLUGIN_HAS_UI == 1 && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS == 0 | |
41 # define DPF_VST3_USES_SEPARATE_CONTROLLER 1 | |
42 #else | |
43 # define DPF_VST3_USES_SEPARATE_CONTROLLER 0 | |
44 #endif | |
45 | |
46 // -------------------------------------------------------------------------------------------------------------------- | |
47 | |
48 #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |
49 # include <atomic> | |
50 #else | |
51 // quick and dirty std::atomic replacement for the things we need | |
52 namespace std { | |
53 struct atomic_int { | |
54 volatile int value; | |
55 explicit atomic_int(volatile int v) noexcept : value(v) {} | |
56 int operator++() volatile noexcept { return __atomic_add_fetch(&value, 1, __ATOMIC_RELAXED); } | |
57 int operator--() volatile noexcept { return __atomic_sub_fetch(&value, 1, __ATOMIC_RELAXED); } | |
58 operator int() volatile noexcept { return __atomic_load_n(&value, __ATOMIC_RELAXED); } | |
59 }; | |
60 }; | |
61 #endif | |
62 | |
63 // -------------------------------------------------------------------------------------------------------------------- | |
64 | |
65 START_NAMESPACE_DISTRHO | |
66 | |
67 // -------------------------------------------------------------------------------------------------------------------- | |
68 | |
69 enum Vst3InternalParameters { | |
70 #if DPF_VST3_USES_SEPARATE_CONTROLLER | |
71 kVst3InternalParameterBufferSize, | |
72 kVst3InternalParameterSampleRate, | |
73 #endif | |
74 #if DISTRHO_PLUGIN_WANT_LATENCY | |
75 kVst3InternalParameterLatency, | |
76 #endif | |
77 #if DISTRHO_PLUGIN_WANT_PROGRAMS | |
78 kVst3InternalParameterProgram, | |
79 #endif | |
80 kVst3InternalParameterBaseCount, | |
81 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |
82 kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | |
83 kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | |
84 kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end | |
85 #else | |
86 kVst3InternalParameterCount = kVst3InternalParameterBaseCount | |
87 #endif | |
88 }; | |
89 | |
90 #if DPF_VST3_USES_SEPARATE_CONTROLLER || DISTRHO_PLUGIN_WANT_LATENCY || DISTRHO_PLUGIN_WANT_PROGRAMS || DISTRHO_PLUGIN_WANT_MIDI_INPUT | |
91 # define DPF_VST3_HAS_INTERNAL_PARAMETERS 1 | |
92 #else | |
93 # define DPF_VST3_HAS_INTERNAL_PARAMETERS 0 | |
94 #endif | |
95 | |
96 #if DPF_VST3_HAS_INTERNAL_PARAMETERS && DISTRHO_PLUGIN_WANT_MIDI_INPUT && \ | |
97 !(DPF_VST3_USES_SEPARATE_CONTROLLER || DISTRHO_PLUGIN_WANT_LATENCY || DISTRHO_PLUGIN_WANT_PROGRAMS) | |
98 # define DPF_VST3_PURE_MIDI_INTERNAL_PARAMETERS 1 | |
99 #else | |
100 # define DPF_VST3_PURE_MIDI_INTERNAL_PARAMETERS 0 | |
101 #endif | |
102 | |
103 // -------------------------------------------------------------------------------------------------------------------- | |
104 | |
105 static inline | |
106 bool strcmp_utf16(const int16_t* const str16, const char* const str8) | |
107 { | |
108 size_t i = 0; | |
109 for (; str8[i] != '\0'; ++i) | |
110 { | |
111 const uint8_t char8 = static_cast<uint8_t>(str8[i]); | |
112 | |
113 // skip non-ascii chars, unsupported | |
114 if (char8 >= 0x80) | |
115 return false; | |
116 | |
117 if (str16[i] != char8) | |
118 return false; | |
119 } | |
120 | |
121 return str16[i] == str8[i]; | |
122 } | |
123 | |
124 // -------------------------------------------------------------------------------------------------------------------- | |
125 | |
126 static inline | |
127 size_t strlen_utf16(const int16_t* const str) | |
128 { | |
129 size_t i = 0; | |
130 | |
131 while (str[i] != 0) | |
132 ++i; | |
133 | |
134 return i; | |
135 } | |
136 | |
137 // -------------------------------------------------------------------------------------------------------------------- | |
138 | |
139 static inline | |
140 void strncpy_utf8(char* const dst, const int16_t* const src, const size_t length) | |
141 { | |
142 DISTRHO_SAFE_ASSERT_RETURN(length > 0,); | |
143 | |
144 if (const size_t len = std::min(strlen_utf16(src), length-1U)) | |
145 { | |
146 for (size_t i=0; i<len; ++i) | |
147 { | |
148 // skip non-ascii chars, unsupported | |
149 if (src[i] >= 0x80) | |
150 continue; | |
151 | |
152 dst[i] = src[i]; | |
153 } | |
154 dst[len] = 0; | |
155 } | |
156 else | |
157 { | |
158 dst[0] = 0; | |
159 } | |
160 } | |
161 | |
162 static inline | |
163 void strncpy_utf16(int16_t* const dst, const char* const src, const size_t length) | |
164 { | |
165 DISTRHO_SAFE_ASSERT_RETURN(length > 0,); | |
166 | |
167 if (const size_t len = std::min(std::strlen(src), length-1U)) | |
168 { | |
169 for (size_t i=0; i<len; ++i) | |
170 { | |
171 // skip non-ascii chars, unsupported | |
172 if ((uint8_t)src[i] >= 0x80) | |
173 continue; | |
174 | |
175 dst[i] = src[i]; | |
176 } | |
177 dst[len] = 0; | |
178 } | |
179 else | |
180 { | |
181 dst[0] = 0; | |
182 } | |
183 } | |
184 | |
185 // -------------------------------------------------------------------------------------------------------------------- | |
186 | |
187 template<typename T> | |
188 static inline | |
189 void snprintf_utf16_t(int16_t* const dst, const T value, const char* const format, const size_t size) | |
190 { | |
191 DISTRHO_SAFE_ASSERT_RETURN(size > 0,); | |
192 | |
193 char* const tmpbuf = (char*)std::malloc(size); | |
194 DISTRHO_SAFE_ASSERT_RETURN(tmpbuf != nullptr,); | |
195 | |
196 std::snprintf(tmpbuf, size-1, format, value); | |
197 tmpbuf[size-1] = '\0'; | |
198 | |
199 strncpy_utf16(dst, tmpbuf, size); | |
200 std::free(tmpbuf); | |
201 } | |
202 | |
203 static inline | |
204 void snprintf_f32_utf16(int16_t* const dst, const float value, const size_t size) | |
205 { | |
206 return snprintf_utf16_t<float>(dst, value, "%f", size); | |
207 } | |
208 | |
209 static inline | |
210 void snprintf_f32_utf16(int16_t* const dst, const double value, const size_t size) | |
211 { | |
212 return snprintf_utf16_t<double>(dst, value, "%f", size); | |
213 } | |
214 | |
215 static inline | |
216 void snprintf_i32_utf16(int16_t* const dst, const int32_t value, const size_t size) | |
217 { | |
218 return snprintf_utf16_t<int32_t>(dst, value, "%d", size); | |
219 } | |
220 | |
221 static inline | |
222 void snprintf_u32_utf16(int16_t* const dst, const uint32_t value, const size_t size) | |
223 { | |
224 return snprintf_utf16_t<uint32_t>(dst, value, "%u", size); | |
225 } | |
226 | |
227 #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |
228 // -------------------------------------------------------------------------------------------------------------------- | |
229 // translate a vstgui-based key character and code to matching values used by DPF | |
230 | |
231 static inline | |
232 uint translateVstKeyCode(bool& special, const int16_t keychar, const int16_t keycode) noexcept | |
233 { | |
234 using namespace DGL_NAMESPACE; | |
235 | |
236 // special stuff first | |
237 special = true; | |
238 switch (keycode) | |
239 { | |
240 case 1: return kKeyBackspace; | |
241 // 2 \t (handled below) | |
242 // 3 clear | |
243 // 4 \r (handled below) | |
244 case 6: return kKeyEscape; | |
245 // 7 space (handled below) | |
246 // 8 next | |
247 // 17 select | |
248 // 18 print | |
249 // 19 \n (handled below) | |
250 // 20 snapshot | |
251 case 22: return kKeyDelete; | |
252 // 23 help | |
253 // 57 = (handled below) | |
254 // numpad stuff follows | |
255 // 24 0 (handled below) | |
256 // 25 1 (handled below) | |
257 // 26 2 (handled below) | |
258 // 27 3 (handled below) | |
259 // 28 4 (handled below) | |
260 // 29 5 (handled below) | |
261 // 30 6 (handled below) | |
262 // 31 7 (handled below) | |
263 // 32 8 (handled below) | |
264 // 33 9 (handled below) | |
265 // 34 * (handled below) | |
266 // 35 + (handled below) | |
267 // 36 separator | |
268 // 37 - (handled below) | |
269 // 38 . (handled below) | |
270 // 39 / (handled below) | |
271 // handle rest of special keys | |
272 /* these special keys are missing: | |
273 - kKeySuper | |
274 - kKeyCapsLock | |
275 - kKeyPrintScreen | |
276 */ | |
277 case 40: return kKeyF1; | |
278 case 41: return kKeyF2; | |
279 case 42: return kKeyF3; | |
280 case 43: return kKeyF4; | |
281 case 44: return kKeyF5; | |
282 case 45: return kKeyF6; | |
283 case 46: return kKeyF7; | |
284 case 47: return kKeyF8; | |
285 case 48: return kKeyF9; | |
286 case 49: return kKeyF10; | |
287 case 50: return kKeyF11; | |
288 case 51: return kKeyF12; | |
289 case 11: return kKeyLeft; | |
290 case 12: return kKeyUp; | |
291 case 13: return kKeyRight; | |
292 case 14: return kKeyDown; | |
293 case 15: return kKeyPageUp; | |
294 case 16: return kKeyPageDown; | |
295 case 10: return kKeyHome; | |
296 case 9: return kKeyEnd; | |
297 case 21: return kKeyInsert; | |
298 case 54: return kKeyShift; | |
299 case 55: return kKeyControl; | |
300 case 56: return kKeyAlt; | |
301 case 58: return kKeyMenu; | |
302 case 52: return kKeyNumLock; | |
303 case 53: return kKeyScrollLock; | |
304 case 5: return kKeyPause; | |
305 } | |
306 | |
307 // regular keys next | |
308 special = false; | |
309 switch (keycode) | |
310 { | |
311 case 2: return '\t'; | |
312 case 4: return '\r'; | |
313 case 7: return ' '; | |
314 case 19: return '\n'; | |
315 case 57: return '='; | |
316 case 24: return '0'; | |
317 case 25: return '1'; | |
318 case 26: return '2'; | |
319 case 27: return '3'; | |
320 case 28: return '4'; | |
321 case 29: return '5'; | |
322 case 30: return '6'; | |
323 case 31: return '7'; | |
324 case 32: return '8'; | |
325 case 33: return '9'; | |
326 case 34: return '*'; | |
327 case 35: return '+'; | |
328 case 37: return '-'; | |
329 case 38: return '.'; | |
330 case 39: return '/'; | |
331 } | |
332 | |
333 // fallback | |
334 return keychar; | |
335 } | |
336 #endif | |
337 | |
338 // -------------------------------------------------------------------------------------------------------------------- | |
339 // handy way to create a utf16 string from a utf8 one on the current function scope, used for message strings | |
340 | |
341 struct ScopedUTF16String { | |
342 int16_t* str; | |
343 ScopedUTF16String(const char* const s) noexcept | |
344 : str(nullptr) | |
345 { | |
346 const size_t len = std::strlen(s); | |
347 str = static_cast<int16_t*>(std::malloc(sizeof(int16_t) * (len + 1))); | |
348 DISTRHO_SAFE_ASSERT_RETURN(str != nullptr,); | |
349 strncpy_utf16(str, s, len + 1); | |
350 } | |
351 | |
352 ~ScopedUTF16String() noexcept | |
353 { | |
354 std::free(str); | |
355 } | |
356 | |
357 operator const int16_t*() const noexcept | |
358 { | |
359 return str; | |
360 } | |
361 }; | |
362 | |
363 // -------------------------------------------------------------------------------------------------------------------- | |
364 // handy way to create a utf8 string from a utf16 one on the current function scope (limited to 128 chars) | |
365 | |
366 struct ScopedUTF8String { | |
367 char str[128]; | |
368 | |
369 ScopedUTF8String(const int16_t* const s) noexcept | |
370 { | |
371 strncpy_utf8(str, s, 128); | |
372 } | |
373 | |
374 operator const char*() const noexcept | |
375 { | |
376 return str; | |
377 } | |
378 }; | |
379 | |
380 // -------------------------------------------------------------------------------------------------------------------- | |
381 | |
382 END_NAMESPACE_DISTRHO | |
383 | |
384 // -------------------------------------------------------------------------------------------------------------------- | |
385 | |
386 #endif // DISTRHO_PLUGIN_VST_HPP_INCLUDED |