VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / utils / CarlaVst3Utils.hpp
blobfb41bfc2bf8c8186b45c2cca91220341cdf93997
1 /*
2 * Carla VST3 utils
3 * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_VST3_UTILS_HPP_INCLUDED
19 #define CARLA_VST3_UTILS_HPP_INCLUDED
21 #include "CarlaBackend.h"
22 #include "CarlaUtils.hpp"
24 #include "travesty/audio_processor.h"
25 #include "travesty/component.h"
26 #include "travesty/edit_controller.h"
27 #include "travesty/factory.h"
28 #include "travesty/host.h"
30 // --------------------------------------------------------------------------------------------------------------------
32 #if !(defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
33 #if defined(__aarch64__) || defined(__arm64__)
34 #define V3_ARCHITECTURE "aarch64"
35 #elif defined(__TARGET_ARCH_ARM)
36 #if __TARGET_ARCH_ARM == 9
37 #define V3_ARCHITECTURE "armv9l"
38 #elif __TARGET_ARCH_ARM == 8
39 #define V3_ARCHITECTURE "armv8l"
40 #elif __TARGET_ARCH_ARM == 7
41 #define V3_ARCHITECTURE "armv7l"
42 #elif _TARGET_ARCH_ARM == 6
43 #define V3_ARCHITECTURE "armv6l"
44 #elif __TARGET_ARCH_ARM == 5
45 #define V3_ARCHITECTURE "armv5l"
46 #else
47 #define V3_ARCHITECTURE "arm"
48 #endif
49 #elif defined(__arm__)
50 #define V3_ARCHITECTURE "arm"
51 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64)
52 #define V3_ARCHITECTURE "x86_64"
53 #elif defined(__i386) || defined(__i386__)
54 #define V3_ARCHITECTURE "i386"
55 #elif defined(__ia64) || defined(__ia64__)
56 #define V3_ARCHITECTURE "ia64"
57 #elif defined(__mips64)
58 #define V3_ARCHITECTURE "mips64"
59 #elif defined(__mips) || defined(__mips__)
60 #define V3_ARCHITECTURE "mips"
61 #elif defined(__ppc64) || defined(__ppc64__) || defined(__powerpc64__)
62 #ifdef __LITTLE_ENDIAN__
63 #define V3_ARCHITECTURE "ppc64le"
64 #else
65 #define V3_ARCHITECTURE "ppc64"
66 #endif
67 #elif defined(__ppc) || defined(__ppc__) || defined(__powerpc__)
68 #define V3_ARCHITECTURE "ppc"
69 #elif defined(__riscv)
70 #if __riscv_xlen == 64
71 #define V3_ARCHITECTURE "riscv64"
72 #else
73 #define V3_ARCHITECTURE "riscv"
74 #endif
75 #else
76 #define V3_ARCHITECTURE "unknown"
77 #endif
78 #if defined(__HAIKU__)
79 #define V3_PLATFORM "haiku"
80 #elif defined(__linux__) || defined(__linux)
81 #define V3_PLATFORM "linux"
82 #elif defined(__FreeBSD__)
83 #define V3_PLATFORM "freebsd"
84 #elif defined(__NetBSD__)
85 #define V3_PLATFORM "netbsd"
86 #elif defined(__OpenBSD__)
87 #define V3_PLATFORM "openbsd"
88 #elif defined(__GNU__)
89 #define V3_PLATFORM "hurd"
90 #else
91 #define V3_PLATFORM "unknown"
92 #endif
93 #endif
95 #if defined(CARLA_OS_MAC)
96 #define V3_CONTENT_DIR "MacOS"
97 #elif defined(_M_ARM64)
98 #define V3_CONTENT_DIR "aarch64-win" /* TBD */
99 #elif defined(_M_ARM)
100 #define V3_CONTENT_DIR "arm-win" /* TBD */
101 #elif defined(CARLA_OS_WIN64)
102 #define V3_CONTENT_DIR "x86_64-win"
103 #elif defined(CARLA_OS_WIN32)
104 #define V3_CONTENT_DIR "x86-win"
105 #else
106 #define V3_CONTENT_DIR V3_ARCHITECTURE "-" V3_PLATFORM
107 #endif
109 #if defined(CARLA_OS_MAC)
110 # define V3_ENTRYFNNAME "bundleEntry"
111 # define V3_EXITFNNAME "bundleExit"
112 typedef void (*V3_ENTRYFN)(void*);
113 typedef void (*V3_EXITFN)(void);
114 #elif defined(CARLA_OS_WIN)
115 # define V3_ENTRYFNNAME "InitDll"
116 # define V3_EXITFNNAME "ExitDll"
117 typedef void (*V3_ENTRYFN)(void);
118 typedef void (*V3_EXITFN)(void);
119 #else
120 # define V3_ENTRYFNNAME "ModuleEntry"
121 # define V3_EXITFNNAME "ModuleExit"
122 typedef void (*V3_ENTRYFN)(void*);
123 typedef void (*V3_EXITFN)(void);
124 #endif
126 #define V3_GETFNNAME "GetPluginFactory"
127 typedef v3_plugin_factory** (*V3_GETFN)(void);
129 // --------------------------------------------------------------------------------------------------------------------
131 CARLA_BACKEND_START_NAMESPACE
133 // --------------------------------------------------------------------------------------------------------------------
135 static inline
136 PluginCategory getPluginCategoryFromV3SubCategories(const char* const subcategories) noexcept
138 if (std::strstr(subcategories, "Instrument") != nullptr)
139 return PLUGIN_CATEGORY_SYNTH;
141 return subcategories[0] != '\0' ? PLUGIN_CATEGORY_OTHER : PLUGIN_CATEGORY_NONE;
144 static inline constexpr
145 uint32_t v3_cconst(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) noexcept
147 return static_cast<uint32_t>((a << 24) | (b << 16) | (c << 8) | (d << 0));
150 static inline
151 const char* tuid2str(const v3_tuid iid) noexcept
153 static char buf[44];
154 std::snprintf(buf, sizeof(buf), "0x%08X,0x%08X,0x%08X,0x%08X",
155 v3_cconst(iid[ 0], iid[ 1], iid[ 2], iid[ 3]),
156 v3_cconst(iid[ 4], iid[ 5], iid[ 6], iid[ 7]),
157 v3_cconst(iid[ 8], iid[ 9], iid[10], iid[11]),
158 v3_cconst(iid[12], iid[13], iid[14], iid[15]));
159 return buf;
162 // --------------------------------------------------------------------------------------------------------------------
164 struct v3_bus_mini_info {
165 uint16_t offset;
166 int32_t bus_type;
167 uint32_t flags;
170 // --------------------------------------------------------------------------------------------------------------------
172 template<class T>
173 T** v3_create_class_ptr()
175 T** const clsptr = new T*;
176 *clsptr = new T;
177 return clsptr;
180 // --------------------------------------------------------------------------------------------------------------------
182 template<class v3_class, const v3_tuid cid>
183 static inline
184 v3_result V3_API v3_query_interface(void* const self, const v3_tuid iid, void** const iface)
186 v3_class* const cls = *static_cast<v3_class**>(self);
188 if (v3_tuid_match(iid, v3_funknown_iid) || v3_tuid_match(iid, cid))
190 ++cls->refcounter;
191 *iface = self;
192 return V3_OK;
195 *iface = nullptr;
196 return V3_NO_INTERFACE;
199 template<class v3_class>
200 static inline
201 uint32_t V3_API v3_ref(void* const self)
203 v3_class* const cls = *static_cast<v3_class**>(self);
204 return ++cls->refcounter;
207 template<class v3_class>
208 static inline
209 uint32_t V3_API v3_unref(void* const self)
211 v3_class** const clsptr = static_cast<v3_class**>(self);
212 v3_class* const cls = *clsptr;
214 if (const int refcount = --cls->refcounter)
215 return refcount;
217 delete cls;
218 delete clsptr;
219 return 0;
222 // --------------------------------------------------------------------------------------------------------------------
224 template<const v3_tuid cid>
225 static inline
226 v3_result V3_API v3_query_interface_static(void* const self, const v3_tuid iid, void** const iface)
228 if (v3_tuid_match(iid, v3_funknown_iid) || v3_tuid_match(iid, cid))
230 *iface = self;
231 return V3_OK;
234 *iface = nullptr;
235 return V3_NO_INTERFACE;
238 static inline
239 uint32_t V3_API v3_ref_static(void*) { return 1; }
241 static inline
242 uint32_t V3_API v3_unref_static(void*) { return 0; }
244 // --------------------------------------------------------------------------------------------------------------------
246 CARLA_BACKEND_END_NAMESPACE
248 #endif // CARLA_VST3_UTILS_HPP_INCLUDED