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"
47 #define V3_ARCHITECTURE "arm"
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 #define V3_ARCHITECTURE "ppc64"
63 #elif defined(__ppc) || defined(__ppc__) || defined(__powerpc__)
64 #define V3_ARCHITECTURE "ppc"
65 #elif defined(__riscv)
66 #if __riscv_xlen == 64
67 #define V3_ARCHITECTURE "riscv64"
69 #define V3_ARCHITECTURE "riscv"
72 #define V3_ARCHITECTURE "unknown"
74 #if defined(__HAIKU__)
75 #define V3_PLATFORM "haiku"
76 #elif defined(__linux__) || defined(__linux)
77 #define V3_PLATFORM "linux"
78 #elif defined(__FreeBSD__)
79 #define V3_PLATFORM "freebsd"
80 #elif defined(__NetBSD__)
81 #define V3_PLATFORM "netbsd"
82 #elif defined(__OpenBSD__)
83 #define V3_PLATFORM "openbsd"
84 #elif defined(__GNU__)
85 #define V3_PLATFORM "hurd"
87 #define V3_PLATFORM "unknown"
91 #if defined(CARLA_OS_MAC)
92 #define V3_CONTENT_DIR "MacOS"
93 #elif defined(_M_ARM64)
94 #define V3_CONTENT_DIR "aarch64-win" /* TBD */
96 #define V3_CONTENT_DIR "arm-win" /* TBD */
97 #elif defined(CARLA_OS_WIN64)
98 #define V3_CONTENT_DIR "x86_64-win"
99 #elif defined(CARLA_OS_WIN32)
100 #define V3_CONTENT_DIR "x86-win"
102 #define V3_CONTENT_DIR V3_ARCHITECTURE "-" V3_PLATFORM
105 #if defined(CARLA_OS_MAC)
106 # define V3_ENTRYFNNAME "bundleEntry"
107 # define V3_EXITFNNAME "bundleExit"
108 typedef void (*V3_ENTRYFN
)(void*);
109 typedef void (*V3_EXITFN
)(void);
110 #elif defined(CARLA_OS_WIN)
111 # define V3_ENTRYFNNAME "InitDll"
112 # define V3_EXITFNNAME "ExitDll"
113 typedef void (*V3_ENTRYFN
)(void);
114 typedef void (*V3_EXITFN
)(void);
116 # define V3_ENTRYFNNAME "ModuleEntry"
117 # define V3_EXITFNNAME "ModuleExit"
118 typedef void (*V3_ENTRYFN
)(void*);
119 typedef void (*V3_EXITFN
)(void);
122 #define V3_GETFNNAME "GetPluginFactory"
123 typedef v3_plugin_factory
** (*V3_GETFN
)(void);
125 // --------------------------------------------------------------------------------------------------------------------
127 CARLA_BACKEND_START_NAMESPACE
129 // --------------------------------------------------------------------------------------------------------------------
132 PluginCategory
getPluginCategoryFromV3SubCategories(const char* const subcategories
) noexcept
134 if (std::strstr(subcategories
, "Instrument") != nullptr)
135 return PLUGIN_CATEGORY_SYNTH
;
137 return subcategories
[0] != '\0' ? PLUGIN_CATEGORY_OTHER
: PLUGIN_CATEGORY_NONE
;
140 static inline constexpr
141 uint32_t v3_cconst(const uint8_t a
, const uint8_t b
, const uint8_t c
, const uint8_t d
) noexcept
143 return static_cast<uint32_t>((a
<< 24) | (b
<< 16) | (c
<< 8) | (d
<< 0));
147 const char* tuid2str(const v3_tuid iid
) noexcept
150 std::snprintf(buf
, sizeof(buf
), "0x%08X,0x%08X,0x%08X,0x%08X",
151 v3_cconst(iid
[ 0], iid
[ 1], iid
[ 2], iid
[ 3]),
152 v3_cconst(iid
[ 4], iid
[ 5], iid
[ 6], iid
[ 7]),
153 v3_cconst(iid
[ 8], iid
[ 9], iid
[10], iid
[11]),
154 v3_cconst(iid
[12], iid
[13], iid
[14], iid
[15]));
158 // --------------------------------------------------------------------------------------------------------------------
160 struct v3_bus_mini_info
{
166 // --------------------------------------------------------------------------------------------------------------------
169 T
** v3_create_class_ptr()
171 T
** const clsptr
= new T
*;
176 // --------------------------------------------------------------------------------------------------------------------
178 template<class v3_class
, const v3_tuid cid
>
180 v3_result V3_API
v3_query_interface(void* const self
, const v3_tuid iid
, void** const iface
)
182 v3_class
* const cls
= *static_cast<v3_class
**>(self
);
184 if (v3_tuid_match(iid
, v3_funknown_iid
) || v3_tuid_match(iid
, cid
))
192 return V3_NO_INTERFACE
;
195 template<class v3_class
>
197 uint32_t V3_API
v3_ref(void* const self
)
199 v3_class
* const cls
= *static_cast<v3_class
**>(self
);
200 return ++cls
->refcounter
;
203 template<class v3_class
>
205 uint32_t V3_API
v3_unref(void* const self
)
207 v3_class
** const clsptr
= static_cast<v3_class
**>(self
);
208 v3_class
* const cls
= *clsptr
;
210 if (const int refcount
= --cls
->refcounter
)
218 // --------------------------------------------------------------------------------------------------------------------
220 template<const v3_tuid cid
>
222 v3_result V3_API
v3_query_interface_static(void* const self
, const v3_tuid iid
, void** const iface
)
224 if (v3_tuid_match(iid
, v3_funknown_iid
) || v3_tuid_match(iid
, cid
))
231 return V3_NO_INTERFACE
;
235 uint32_t V3_API
v3_ref_static(void*) { return 1; }
238 uint32_t V3_API
v3_unref_static(void*) { return 0; }
240 // --------------------------------------------------------------------------------------------------------------------
242 CARLA_BACKEND_END_NAMESPACE
244 #endif // CARLA_VST3_UTILS_HPP_INCLUDED