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