Audacity 3.2.0
VST3Utils.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file VST3Utils.cpp
6
7 @author Vitaly Sverchinsky
8
9 @brief Part of Audacity VST3 module
10
11**********************************************************************/
12
13
14#include "VST3Utils.h"
15#include "Base64.h"
16
17#include <wx/string.h>
18#include <wx/filename.h>
19
20#include <pluginterfaces/vst/ivsteditcontroller.h>
21#include <pluginterfaces/vst/ivstparameterchanges.h>
22#include <wx/regex.h>
23
24#include "MemoryX.h"
25
26
27#ifdef __WXMSW__
28#include <shlobj.h>
29#endif
30
31namespace
32{
33
35{
36#ifdef __WXMSW__
37 PWSTR commonFolderPath { nullptr };
38 auto cleanup = finally([&](){ CoTaskMemFree(commonFolderPath); });
39 if(SHGetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT , NULL, &commonFolderPath) == S_OK)
40 return wxString(commonFolderPath) + "\\VST3 Presets\\";
41 return {};
42#elif __WXMAC__
43 return wxString("Library/Audio/Presets/");
44#elif __WXGTK__
45 return wxString("/usr/local/share/vst3/presets/");
46#endif
47}
48
49wxString GetPresetsPath(const wxString& basePath, const VST3::Hosting::ClassInfo& effectClassInfo)
50{
51 wxRegEx fixName(R"([\\*?/:<>|])");
52 wxString companyName = wxString (effectClassInfo.vendor()).Trim();
53 wxString pluginName = wxString (effectClassInfo.name()).Trim();
54
55 fixName.ReplaceAll( &companyName, { "_" });
56 fixName.ReplaceAll( &pluginName, { "_" });
57
58 wxFileName result;
59 result.SetPath(basePath);
60 result.AppendDir(companyName);
61 result.AppendDir(pluginName);
62 auto path = result.GetPath();
63
64 return path;
65}
66
67}
68
69wxString VST3Utils::MakePluginPathString(const wxString& modulePath, const std::string& effectUIDString)
70{
71 return wxString::Format("%s;%s", modulePath, effectUIDString);
72}
73
74bool VST3Utils::ParsePluginPath(const wxString& pluginPath, wxString* modulePath,
75 std::string* effectUIDString)
76{
77 const auto sep = pluginPath.Find(';', true);
78 if(sep != wxNOT_FOUND &&
79 //modulePath not empty
80 sep > 0 &&
81 //effectUIDString not empty
82 static_cast<size_t>(sep) < pluginPath.Length() - 1)
83 {
84 if(modulePath != nullptr)
85 *modulePath = pluginPath.Left(sep);
86 if(effectUIDString != nullptr)
87 *effectUIDString = pluginPath.Mid(static_cast<size_t>(sep) + 1);
88 return true;
89 }
90 return false;
91}
92
93wxString VST3Utils::ToWxString(const Steinberg::Vst::TChar* str)
94{
95 static const wxCSConv csConv { wxFONTENCODING_UTF16 };
96 return { reinterpret_cast<const char*>(str), csConv };
97}
98
99wxString VST3Utils::MakeAutomationParameterKey(const Steinberg::Vst::ParameterInfo& parameterInfo)
100{
101 auto suffix = ToWxString(parameterInfo.shortTitle);
102 if(suffix.empty())
103 suffix = ToWxString(parameterInfo.title);
104
105 if(!suffix.empty())
106 return wxString::Format("%lu_", static_cast<unsigned long>(parameterInfo.id)) + suffix;
107
108 return wxString::Format("%lu", static_cast<unsigned long>(parameterInfo.id));
109}
110
111bool VST3Utils::ParseAutomationParameterKey(const wxString& key, Steinberg::Vst::ParamID& paramId)
112{
113 const auto pos = key.Find('_');
114 const auto idStr = pos == wxNOT_FOUND ? key : key.Left(pos);
115 unsigned long value { };
116 if(idStr.ToULong(&value))
117 {
118 paramId = static_cast<Steinberg::Vst::ParamID>(value);
119 return true;
120 }
121 return false;
122}
123
124wxString VST3Utils::MakeFactoryPresetID(Steinberg::Vst::UnitID unitId, Steinberg::int32 programIndex)
125{
126 return wxString::Format("%d:%d",
127 static_cast<int>(unitId),
128 static_cast<int>(programIndex));
129}
130
131bool VST3Utils::ParseFactoryPresetID(const wxString& presetId, Steinberg::Vst::UnitID& unitId, Steinberg::int32& programIndex)
132{
133 auto parts = wxSplit(presetId, ':');
134 long nums[2]{};
135 if(parts.size() == 2 && parts[0].ToLong(&nums[0]) && parts[1].ToLong(&nums[1]))
136 {
137 unitId = static_cast<Steinberg::Vst::UnitID>(nums[0]);
138 programIndex = static_cast<Steinberg::int32>(nums[1]);
139 return true;
140 }
141 return false;
142}
143
144
145wxString VST3Utils::GetFactoryPresetsPath(const VST3::Hosting::ClassInfo& effectClassInfo)
146{
147 return GetPresetsPath(
149 effectClassInfo
150 );
151}
152
153Steinberg::IPtr<PresetsBufferStream> PresetsBufferStream::fromString(const wxString& str)
154{
155 Steinberg::Buffer buffer(str.length() / 4 * 3);
156 const auto numBytes = Base64::Decode(str, buffer);
157 //BufferStream uses fill size as a cursor position and size as a stream end position
158 //To prevent plugins from fetching bytes past the meaningful data we need to truncate
159 //end position
160 buffer.setSize(numBytes);
161
162 auto result = owned(safenew PresetsBufferStream);
163 result->mBuffer.take(buffer);
164 return result;
165}
166
168{
169 auto str = Base64::Encode(mBuffer, mBuffer.getFillSize());
170 return str;
171}
#define str(a)
#define safenew
Definition: MemoryX.h:9
static const AudacityProject::AttachedObjects::RegisteredFactory key
static Steinberg::IPtr< PresetsBufferStream > fromString(const wxString &str)
Definition: VST3Utils.cpp:153
wxString toString() const
Definition: VST3Utils.cpp:167
static wxString MakePluginPathString(const wxString &modulePath, const std::string &effectUIDString)
Definition: VST3Utils.cpp:69
static bool ParseFactoryPresetID(const wxString &presetId, Steinberg::Vst::UnitID &unitId, Steinberg::int32 &programIndex)
Definition: VST3Utils.cpp:131
static wxString GetFactoryPresetsPath(const VST3::Hosting::ClassInfo &effectClassInfo)
Definition: VST3Utils.cpp:145
static wxString MakeFactoryPresetID(Steinberg::Vst::UnitID unitId, Steinberg::int32 programIndex)
Definition: VST3Utils.cpp:124
static wxString ToWxString(const Steinberg::Vst::TChar *str)
Definition: VST3Utils.cpp:93
static bool ParseAutomationParameterKey(const wxString &key, Steinberg::Vst::ParamID &paramId)
Definition: VST3Utils.cpp:111
static wxString MakeAutomationParameterKey(const Steinberg::Vst::ParameterInfo &info)
Definition: VST3Utils.cpp:99
static bool ParsePluginPath(const wxString &pluginPath, wxString *modulePath, std::string *effectUIDString)
Definition: VST3Utils.cpp:74
STRINGS_API wxString Encode(const void *in, int len)
Definition: Base64.cpp:27
STRINGS_API int Decode(const wxString &in, void *out)
Definition: Base64.cpp:67
wxString GetPresetsPath(const wxString &basePath, const VST3::Hosting::ClassInfo &effectClassInfo)
Definition: VST3Utils.cpp:49