Audacity 3.2.0
VSTWrapper.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 VSTWrapper.h
6
7 Dominic Mazzoni
8
9 Paul Licameli split from VSTEffect.h
10
11**********************************************************************/
12#ifndef __AUDACITY_VST_WRAPPER__
13#define __AUDACITY_VST_WRAPPER__
14
15#include "EffectInterface.h"
16#include "CFResources.h"
17#include "XMLTagHandler.h"
18
19#include <wx/dynlib.h>
20#include <wx/string.h>
21
22#include <unordered_map>
23#include <vector>
24#include <mutex>
25#include <thread>
26
27#include "aeffectx.h"
28
29typedef intptr_t (*dispatcherFn)(AEffect * effect,
30 int opCode,
31 int index,
32 intptr_t value,
33 void *ptr,
34 float opt);
35
36typedef void (*processFn)(AEffect * effect,
37 float **inputs,
38 float **outputs,
39 int sampleframes);
40
41typedef void (*setParameterFn)(AEffect * effect,
42 int index,
43 float parameter);
44
45typedef float (*getParameterFn)(AEffect * effect,
46 int index);
47
48typedef AEffect *(*vstPluginMain)(audioMasterCallback audioMaster);
49
50class wxDynamicLibrary;
51
52#if defined(__WXMAC__)
53struct __CFBundle;
54typedef struct __CFBundle *CFBundleRef;
55#if __LP64__
56typedef int CFBundleRefNum;
57#else
58typedef signed short SInt16;
60#endif
61#endif
62
63class VST_API VSTLink /* not final */
64{
65public:
66 virtual ~VSTLink() {};
67 virtual intptr_t callDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt) = 0;
68};
69
71{
72 // These are saved in the Config and checked against when loading a preset, to make sure
73 // that we are loading a Config which is compatible.
74 //
75 int32_t mUniqueID{};
76 int32_t mVersion{};
77 int32_t mNumParams{};
78
79 // When loading a preset, the preferred way is to use the chunk; when not present in
80 // the Config or failing to load, we fall back to loading single parameters (ID, value) pairs.
81 //
82 // It looks like a plugin might not support this (if their effFlagsProgramChunks bit is off)
83 // If not, then hold an empty vector
84 //
85 std::vector<char> mChunk;
86
87 // Fallback data used when the chunk is not available.
88 std::unordered_map<wxString, std::optional<double> > mParamsMap;
89};
90
91struct VST_API VSTUIWrapper
92{
93 virtual void Idle();
94 virtual void NeedIdle();
95 virtual void SizeWindow(int w, int h);
96 virtual void Automate(int index, float value);
97 virtual void Flush();
98};
99
100struct VST_API VSTWrapper
101 : public VSTLink, public XMLTagHandler, public VSTUIWrapper
102{
104 {
105 auto pSettings = settings.cast<VSTSettings>();
106 assert(pSettings);
107 return *pSettings;
108 }
109
110 static inline const VSTSettings& GetSettings(const EffectSettings& settings)
111 {
112 auto pSettings = settings.cast<VSTSettings>();
113 assert(pSettings);
114 return *pSettings;
115 }
116
117 explicit VSTWrapper(const PluginPath& path)
118 : mPath(path)
119 , mMainThreadId{ std::this_thread::get_id() }
120 {}
121
122 ~VSTWrapper();
123
124 AEffect* mAEffect = nullptr;
126
127 intptr_t callDispatcher(int opcode, int index,
128 intptr_t value, void* ptr, float opt) override;
129
130 intptr_t constCallDispatcher(int opcode, int index,
131 intptr_t value, void* ptr, float opt) const;
132
133 std::recursive_mutex mDispatcherLock;
134
135 float callGetParameter(int index) const;
136
137 void callSetChunk(bool isPgm, int len, void* buf);
138 void callSetChunk(bool isPgm, int len, void* buf, VstPatchChunkInfo* info) const;
139
140
141 int GetString(wxString& outstr, int opcode, int index = 0) const;
142 wxString GetString(int opcode, int index = 0) const;
143
145 {
146 int mID;
147 wxString mName;
148 };
149
152 using ParameterVisitor = std::function< bool(const ParameterInfo& pi) >;
153
154 void ForEachParameter(ParameterVisitor visitor) const;
155
156 bool FetchSettings(VSTSettings& vst3Settings, bool doFetch=true) const;
157
158 bool StoreSettings(const VSTSettings& vst3settings) const;
159
160 VstPatchChunkInfo GetChunkInfo() const;
161
162 bool IsCompatible(const VstPatchChunkInfo&) const;
163
164 // These are here because they are used by the import/export methods
166 wxString mName;
167
168 // XML load/save
169 bool mInSet;
171 wxString mChunk;
174
175 bool LoadXML(const wxFileName& fn);
176 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
177 void HandleXMLEndTag(const std::string_view& tag) override;
178 void HandleXMLContent(const std::string_view& content) override;
179 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override;
180
181 void SetString(int opcode, const wxString& str, int index = 0);
182
183 ComponentInterfaceSymbol GetSymbol() const;
184
185 void callSetParameter(int index, float value) const;
186
187 void SaveXML(const wxFileName& fn) const;
188
189 // Other formats for import/export
190 bool LoadFXB(const wxFileName& fn);
191 bool LoadFXP(const wxFileName& fn);
192 bool LoadFXProgram(unsigned char** bptr, ssize_t& len, int index, bool dryrun);
193 void callSetProgram(int index);
194
195 void SaveFXB(const wxFileName& fn) const;
196 void SaveFXP(const wxFileName& fn) const;
197 void SaveFXProgram(wxMemoryBuffer& buf, int index) const;
198
199
200 intptr_t mCurrentEffectID {};
201
202 bool Load();
204
205 // Define a manager class for a handle to a module
206#if defined(__WXMSW__)
207 using ModuleHandle = std::unique_ptr<wxDynamicLibrary>;
208#else
209 struct ModuleDeleter {
210 void operator() (void*) const;
211 };
212 using ModuleHandle = std::unique_ptr < char, ModuleDeleter >;
213#endif
214 ModuleHandle mModule{};
215
216 wxString mVendor;
217 wxString mDescription;
219 bool mInteractive{ false };
220 unsigned mAudioIns{ 0 };
221 unsigned mAudioOuts{ 0 };
222 int mMidiIns{ 0 };
223 int mMidiOuts{ 0 };
225
226 void Unload();
227
228 void ResetModuleAndHandle();
229
230#if defined(__WXMAC__)
231 // These members must be ordered after mModule
232
233 using BundleHandle = CF_ptr<CFBundleRef>;
234
236
239 CFBundleRef pHandle = nullptr, CFBundleRefNum num = 0)
240 : mpHandle{ pHandle }, mNum{ num }
241 {}
243 {
244 if (this != &other) {
245 mpHandle = other.mpHandle;
246 mNum = other.mNum;
247 other.mpHandle = nullptr;
248 other.mNum = 0;
249 }
250 return *this;
251 }
252 ~ResourceHandle() { reset(); }
253 void reset();
254
255 CFBundleRef mpHandle{};
257 };
259#endif
260
261
262 VstTimeInfo* GetTimeInfo();
263 float GetSampleRate();
265
266 int mBufferDelay{ 0 };
267
268 int GetProcessLevel();
269 int mProcessLevel{ 1 }; // in GUI thread
270
271 // The vst callback is currently called both for the effect and for instances.
272 //
273 static intptr_t AudioMaster(AEffect *effect,
274 int32_t opcode,
275 int32_t index,
276 intptr_t value,
277 void * ptr,
278 float opt);
279
280 // Some of the methods called by the callback make sense for the Effect:
281 //
282 // - All GUI-related stuff
283
284 // Some other methods called by the callback make sense for Instances:
285 virtual void SetBufferDelay(int samples);
286
287
288 // Make message carrying all the information in settings, including chunks
289 // This is called only on the main thread
290 std::unique_ptr<EffectInstance::Message>
291 MakeMessageFS(const VSTSettings& settings) const;
292
293 // This is an immutable property determined once, when mAEffect is loaded
294 // Whether the effect is capable of fancy native UI
295 bool mGui{ false };
296};
297
299{
300 using ParamVector = std::vector<std::optional<double> >;
301
302 // Make a message from a chunk and ID-value pairs
303 explicit VSTMessage(std::vector<char> chunk, ParamVector params)
304 : mChunk(std::move(chunk)),
305 mParamsVec(std::move(params))
306 {
307 }
308
309 // Make a message from a single parameter
310 explicit VSTMessage(int id, double value, size_t numParams)
311 {
312 mParamsVec.resize(numParams, std::nullopt);
313 if (id < numParams)
314 mParamsVec[id] = value;
315 }
316
317 ~VSTMessage() override;
318
319 std::unique_ptr<Message> Clone() const override;
320 void Assign(Message&& src) override;
321 void Merge(Message&& src) override;
322
323
324 std::vector<char> mChunk;
326
327};
328
329#endif
Wrap resource pointers from Apple Core SDK for RAII.
#define str(a)
EffectDistortionSettings params
Definition: Distortion.cpp:77
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
static Settings & settings()
Definition: TrackInfo.cpp:47
signed short SInt16
Definition: VSTWrapper.h:58
void(* processFn)(AEffect *effect, float **inputs, float **outputs, int sampleframes)
Definition: VSTWrapper.h:36
SInt16 CFBundleRefNum
Definition: VSTWrapper.h:59
void(* setParameterFn)(AEffect *effect, int index, float parameter)
Definition: VSTWrapper.h:41
float(* getParameterFn)(AEffect *effect, int index)
Definition: VSTWrapper.h:45
intptr_t(* dispatcherFn)(AEffect *effect, int opCode, int index, intptr_t value, void *ptr, float opt)
Definition: VSTWrapper.h:29
struct __CFBundle * CFBundleRef
Definition: VSTWrapper.h:54
int id
static const auto fn
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
intptr_t(* audioMasterCallback)(AEffect *, int32_t, int32_t, intptr_t, void *, float)
Definition: aeffectx.h:337
VST Effects class, conforming to VST layout.
Definition: aeffectx.h:258
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Type of messages to send from main thread to processing.
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
THEME_RESOURCES_API void Load()
TranslatableString Message(unsigned trackCount)
STL namespace.
Externalized state of a plug-in.
VSTMessage(int id, double value, size_t numParams)
Definition: VSTWrapper.h:310
std::vector< std::optional< double > > ParamVector
Definition: VSTWrapper.h:300
ParamVector mParamsVec
Definition: VSTWrapper.h:325
std::unique_ptr< Message > Clone() const override
Definition: VSTWrapper.cpp:243
void Merge(Message &&src) override
Definition: VSTWrapper.cpp:270
VSTMessage(std::vector< char > chunk, ParamVector params)
Definition: VSTWrapper.h:303
~VSTMessage() override
void Assign(Message &&src) override
Definition: VSTWrapper.cpp:252
std::vector< char > mChunk
Definition: VSTWrapper.h:324
std::vector< char > mChunk
Definition: VSTWrapper.h:85
std::unordered_map< wxString, std::optional< double > > mParamsMap
Definition: VSTWrapper.h:88
int32_t mVersion
Definition: VSTWrapper.h:76
int32_t mNumParams
Definition: VSTWrapper.h:77
int32_t mUniqueID
Definition: VSTWrapper.h:75
ResourceHandle & operator=(ResourceHandle &&other)
Definition: VSTWrapper.h:242
ResourceHandle(CFBundleRef pHandle=nullptr, CFBundleRefNum num=0)
Definition: VSTWrapper.h:238
bool mAutomatable
Definition: VSTWrapper.h:224
int mVstVersion
Definition: VSTWrapper.h:165
wxString mName
Definition: VSTWrapper.h:166
wxString mChunk
Definition: VSTWrapper.h:171
static VSTSettings & GetSettings(EffectSettings &settings)
Definition: VSTWrapper.h:103
std::unique_ptr< wxDynamicLibrary > ModuleHandle
Definition: VSTWrapper.h:207
BundleHandle mBundleRef
Definition: VSTWrapper.h:235
long mXMLVersion
Definition: VSTWrapper.h:172
CF_ptr< CFBundleRef > BundleHandle
Definition: VSTWrapper.h:233
VstTimeInfo mTimeInfo
Definition: VSTWrapper.h:264
std::recursive_mutex mDispatcherLock
Definition: VSTWrapper.h:133
wxString mDescription
Definition: VSTWrapper.h:217
int mVersion
Definition: VSTWrapper.h:218
ResourceHandle mResource
Definition: VSTWrapper.h:258
VstPatchChunkInfo mXMLInfo
Definition: VSTWrapper.h:173
std::thread::id mMainThreadId
Definition: VSTWrapper.h:125
VSTWrapper(const PluginPath &path)
Definition: VSTWrapper.h:117
std::function< bool(const ParameterInfo &pi) > ParameterVisitor
Definition: VSTWrapper.h:152
static const VSTSettings & GetSettings(const EffectSettings &settings)
Definition: VSTWrapper.h:110
PluginPath mPath
Definition: VSTWrapper.h:203
bool mInSet
Definition: VSTWrapper.h:169
wxString mVendor
Definition: VSTWrapper.h:216
bool mInChunk
Definition: VSTWrapper.h:170