Audacity 3.2.0
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
VSTWrapper Struct Reference

#include <VSTWrapper.h>

Inheritance diagram for VSTWrapper:
[legend]
Collaboration diagram for VSTWrapper:
[legend]

Classes

struct  ParameterInfo
 
struct  ResourceHandle
 

Public Types

using ParameterVisitor = std::function< bool(const ParameterInfo &pi) >
 
using ModuleHandle = std::unique_ptr< wxDynamicLibrary >
 
using BundleHandle = CF_ptr< CFBundleRef >
 

Public Member Functions

 VSTWrapper (const PluginPath &path)
 
 ~VSTWrapper ()
 
intptr_t callDispatcher (int opcode, int index, intptr_t value, void *ptr, float opt) override
 
intptr_t constCallDispatcher (int opcode, int index, intptr_t value, void *ptr, float opt) const
 
float callGetParameter (int index) const
 
void callSetChunk (bool isPgm, int len, void *buf)
 
void callSetChunk (bool isPgm, int len, void *buf, VstPatchChunkInfo *info) const
 
int GetString (wxString &outstr, int opcode, int index=0) const
 
wxString GetString (int opcode, int index=0) const
 
void ForEachParameter (ParameterVisitor visitor) const
 
bool FetchSettings (VSTSettings &vst3Settings, bool doFetch=true) const
 
bool StoreSettings (const VSTSettings &vst3settings) const
 
VstPatchChunkInfo GetChunkInfo () const
 
bool IsCompatible (const VstPatchChunkInfo &) const
 
bool LoadXML (const wxFileName &fn)
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
void HandleXMLEndTag (const std::string_view &tag) override
 
void HandleXMLContent (const std::string_view &content) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void SetString (int opcode, const wxString &str, int index=0)
 
ComponentInterfaceSymbol GetSymbol () const
 
void callSetParameter (int index, float value) const
 
void SaveXML (const wxFileName &fn) const
 
bool LoadFXB (const wxFileName &fn)
 
bool LoadFXP (const wxFileName &fn)
 
bool LoadFXProgram (unsigned char **bptr, ssize_t &len, int index, bool dryrun)
 
void callSetProgram (int index)
 
void SaveFXB (const wxFileName &fn) const
 
void SaveFXP (const wxFileName &fn) const
 
void SaveFXProgram (wxMemoryBuffer &buf, int index) const
 
bool Load ()
 
void Unload ()
 
void ResetModuleAndHandle ()
 
VstTimeInfoGetTimeInfo ()
 
float GetSampleRate ()
 
int GetProcessLevel ()
 
virtual void SetBufferDelay (int samples)
 
std::unique_ptr< EffectInstance::MessageMakeMessageFS (const VSTSettings &settings) const
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 
- Public Member Functions inherited from VSTUIWrapper
virtual void Idle ()
 
virtual void NeedIdle ()
 
virtual void SizeWindow (int w, int h)
 
virtual void Automate (int index, float value)
 
virtual void Flush ()
 

Static Public Member Functions

static VSTSettingsGetSettings (EffectSettings &settings)
 
static const VSTSettingsGetSettings (const EffectSettings &settings)
 
static intptr_t AudioMaster (AEffect *effect, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
 

Public Attributes

AEffectmAEffect = nullptr
 
std::thread::id mMainThreadId
 
std::recursive_mutex mDispatcherLock
 
int mVstVersion
 
wxString mName
 
bool mInSet
 
bool mInChunk
 
wxString mChunk
 
long mXMLVersion
 
VstPatchChunkInfo mXMLInfo
 
intptr_t mCurrentEffectID {}
 
PluginPath mPath
 
ModuleHandle mModule {}
 
wxString mVendor
 
wxString mDescription
 
int mVersion
 
bool mInteractive { false }
 
unsigned mAudioIns { 0 }
 
unsigned mAudioOuts { 0 }
 
int mMidiIns { 0 }
 
int mMidiOuts { 0 }
 
bool mAutomatable
 
BundleHandle mBundleRef
 
ResourceHandle mResource
 
VstTimeInfo mTimeInfo
 
int mBufferDelay { 0 }
 
int mProcessLevel { 1 }
 
bool mGui { false }
 

Detailed Description

Definition at line 100 of file VSTWrapper.h.

Member Typedef Documentation

◆ BundleHandle

Definition at line 233 of file VSTWrapper.h.

◆ ModuleHandle

using VSTWrapper::ModuleHandle = std::unique_ptr<wxDynamicLibrary>

Definition at line 207 of file VSTWrapper.h.

◆ ParameterVisitor

using VSTWrapper::ParameterVisitor = std::function< bool(const ParameterInfo& pi) >
Returns
true continue visiting
false stop visiting

Definition at line 152 of file VSTWrapper.h.

Constructor & Destructor Documentation

◆ VSTWrapper()

VSTWrapper::VSTWrapper ( const PluginPath path)
inlineexplicit

Definition at line 117 of file VSTWrapper.h.

118 : mPath(path)
119 , mMainThreadId{ std::this_thread::get_id() }
120 {}
std::thread::id mMainThreadId
Definition: VSTWrapper.h:125
PluginPath mPath
Definition: VSTWrapper.h:203

◆ ~VSTWrapper()

VSTWrapper::~VSTWrapper ( )

Definition at line 597 of file VSTWrapper.cpp.

598{
599 Unload();
601}
void Unload()
Definition: VSTWrapper.cpp:571
void ResetModuleAndHandle()
Definition: VSTWrapper.cpp:583

References ResetModuleAndHandle(), and Unload().

Here is the call graph for this function:

Member Function Documentation

◆ AudioMaster()

intptr_t VSTWrapper::AudioMaster ( AEffect effect,
int32_t  opcode,
int32_t  index,
intptr_t  value,
void *  ptr,
float  opt 
)
static

Definition at line 59 of file VSTWrapper.cpp.

65{
66 VSTWrapper* vst = (effect ? static_cast<VSTWrapper*>(effect->ptr2) : nullptr);
67
68 // Handles operations during initialization...before VSTEffect has had a
69 // chance to set its instance pointer.
70 switch (opcode)
71 {
73 return (intptr_t) 2400;
74
76 return vst->mCurrentEffectID;
77
79 strcpy((char *) ptr, "Audacity Team"); // Do not translate, max 64 + 1 for null terminator
80 return 1;
81
83 strcpy((char *) ptr, "Audacity"); // Do not translate, max 64 + 1 for null terminator
84 return 1;
85
87 return (intptr_t) (AUDACITY_VERSION << 24 |
88 AUDACITY_RELEASE << 16 |
89 AUDACITY_REVISION << 8 |
90 AUDACITY_MODLEVEL);
91
92 // Some (older) effects depend on an effIdle call when requested. An
93 // example is the Antress Modern plugins which uses the call to update
94 // the editors display when the program (preset) changes.
96 if (vst)
97 {
98 vst->NeedIdle();
99 return 1;
100 }
101 return 0;
102
103 // We would normally get this if the effect editor is dipslayed and something "major"
104 // has changed (like a program change) instead of multiple automation calls.
105 // Since we don't do anything with the parameters while the editor is displayed,
106 // there's no need for us to do anything.
108 if (vst)
109 {
110 return 1;
111 }
112 return 0;
113
114 // Return the current time info.
116 if (vst)
117 {
118 return (intptr_t) vst->GetTimeInfo();
119 }
120 return 0;
121
122 // Inputs, outputs, or initial delay has changed...all we care about is initial delay.
124 if (vst)
125 {
126 vst->SetBufferDelay(effect->initialDelay);
127 return 1;
128 }
129 return 0;
130
132 if (vst)
133 {
134 return (intptr_t) vst->GetSampleRate();
135 }
136 return 0;
137
138 case audioMasterIdle:
139 if (vst)
140 vst->Idle();
141 return 1;
142
144 if (vst)
145 {
146 return vst->GetProcessLevel();
147 }
148 return 0;
149
151 return kVstLangEnglish;
152
153 // We always replace, never accumulate
155 return 1;
156
157 // Resize the window to accommodate the effect size
159 if (vst)
160 {
161 vst->SizeWindow(index, value);
162 }
163 return 1;
164
165 case audioMasterCanDo:
166 {
167 char *s = (char *) ptr;
168 if (strcmp(s, "acceptIOChanges") == 0 ||
169 strcmp(s, "sendVstTimeInfo") == 0 ||
170 strcmp(s, "startStopProcess") == 0 ||
171 strcmp(s, "shellCategory") == 0 ||
172 strcmp(s, "sizeWindow") == 0)
173 {
174 return 1;
175 }
176
177#if defined(VST_DEBUG)
178#if defined(__WXMSW__)
179 wxLogDebug(wxT("VST canDo: %s"), wxString::FromAscii((char *)ptr));
180#else
181 wxPrintf(wxT("VST canDo: %s\n"), wxString::FromAscii((char *)ptr));
182#endif
183#endif
184
185 return 0;
186 }
187
190 return 0;
191
193 if (vst)
194 {
195 vst->Automate(index, opt);
196 }
197 return 0;
198
199 // We're always connected (sort of)
201
202 // We don't do MIDI yet
205
206 // Don't need to see any messages about these
207 return 0;
208 }
209
210#if defined(VST_DEBUG)
211#if defined(__WXMSW__)
212 wxLogDebug(wxT("vst: %p opcode: %d index: %d value: %p ptr: %p opt: %f user: %p"),
213 effect, (int) opcode, (int) index, (void *) value, ptr, opt, vst);
214#else
215 wxPrintf(wxT("vst: %p opcode: %d index: %d value: %p ptr: %p opt: %f user: %p\n"),
216 effect, (int) opcode, (int) index, (void *) value, ptr, opt, vst);
217#endif
218#endif
219
220 return 0;
221}
wxT("CloseDown"))
const int kVstLangEnglish
Definition: aeffectx.h:145
const int audioMasterGetVendorVersion
Definition: aeffectx.h:69
const int audioMasterGetCurrentProcessLevel
Definition: aeffectx.h:57
const int audioMasterNeedIdle
Definition: aeffectx.h:48
const int audioMasterGetProductString
Definition: aeffectx.h:68
const int audioMasterWantMidi
Definition: aeffectx.h:40
const int audioMasterPinConnected
Definition: aeffectx.h:38
const int audioMasterWillReplaceOrAccumulate
Definition: aeffectx.h:56
const int audioMasterUpdateDisplay
Definition: aeffectx.h:77
const int audioMasterGetTime
Definition: aeffectx.h:41
const int audioMasterEndEdit
Definition: aeffectx.h:79
const int audioMasterIdle
Definition: aeffectx.h:37
const int audioMasterIOChanged
Definition: aeffectx.h:47
const int audioMasterProcessEvents
Definition: aeffectx.h:42
const int audioMasterCurrentId
Definition: aeffectx.h:36
const int audioMasterAutomate
Definition: aeffectx.h:34
const int audioMasterVersion
Definition: aeffectx.h:35
const int audioMasterBeginEdit
Definition: aeffectx.h:78
const int audioMasterGetVendorString
Definition: aeffectx.h:67
const int audioMasterGetSampleRate
Definition: aeffectx.h:50
const int audioMasterGetLanguage
Definition: aeffectx.h:73
const int audioMasterSizeWindow
Definition: aeffectx.h:49
const int audioMasterCanDo
Definition: aeffectx.h:72
void * ptr2
Definition: aeffectx.h:283
int initialDelay
Definition: aeffectx.h:284
virtual void SizeWindow(int w, int h)
Definition: VSTWrapper.cpp:643
virtual void Automate(int index, float value)
virtual void Idle()
Definition: VSTWrapper.cpp:619
virtual void NeedIdle()
Definition: VSTWrapper.cpp:623
float GetSampleRate()
Definition: VSTWrapper.cpp:633
int GetProcessLevel()
Definition: VSTWrapper.cpp:638
intptr_t mCurrentEffectID
Definition: VSTWrapper.h:200
virtual void SetBufferDelay(int samples)
Definition: VSTWrapper.cpp:647
VstTimeInfo * GetTimeInfo()
Definition: VSTWrapper.cpp:627

References audioMasterAutomate, audioMasterBeginEdit, audioMasterCanDo, audioMasterCurrentId, audioMasterEndEdit, audioMasterGetCurrentProcessLevel, audioMasterGetLanguage, audioMasterGetProductString, audioMasterGetSampleRate, audioMasterGetTime, audioMasterGetVendorString, audioMasterGetVendorVersion, audioMasterIdle, audioMasterIOChanged, audioMasterNeedIdle, audioMasterPinConnected, audioMasterProcessEvents, audioMasterSizeWindow, audioMasterUpdateDisplay, audioMasterVersion, audioMasterWantMidi, audioMasterWillReplaceOrAccumulate, VSTUIWrapper::Automate(), GetProcessLevel(), GetSampleRate(), GetTimeInfo(), VSTUIWrapper::Idle(), AEffect::initialDelay, kVstLangEnglish, mCurrentEffectID, VSTUIWrapper::NeedIdle(), AEffect::ptr2, SetBufferDelay(), VSTUIWrapper::SizeWindow(), and wxT().

Referenced by Load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ callDispatcher()

intptr_t VSTWrapper::callDispatcher ( int  opcode,
int  index,
intptr_t  value,
void *  ptr,
float  opt 
)
overridevirtual

Implements VSTLink.

Definition at line 682 of file VSTWrapper.cpp.

684{
685 // Needed since we might be in the dispatcher when the timer pops
686 std::lock_guard guard(mDispatcherLock);
687
688 return mAEffect->dispatcher(mAEffect, opcode, index, value, ptr, opt);
689}
intptr_t(* dispatcher)(AEffect *, int, int, intptr_t, void *, float)
Definition: aeffectx.h:264
AEffect * mAEffect
Definition: VSTWrapper.h:124
std::recursive_mutex mDispatcherLock
Definition: VSTWrapper.h:133

References AEffect::dispatcher, mAEffect, and mDispatcherLock.

Referenced by callSetProgram(), constCallDispatcher(), VSTInstance::DoProcessInitialize(), VSTEffectBase::GetEffectIDs(), HandleXMLEndTag(), HandleXMLTag(), Load(), LoadFXB(), LoadFXProgram(), LoadXML(), VSTEditor::OnTimer(), VSTInstance::PowerOff(), VSTInstance::PowerOn(), SetString(), and Unload().

Here is the caller graph for this function:

◆ callGetParameter()

float VSTWrapper::callGetParameter ( int  index) const

Definition at line 699 of file VSTWrapper.cpp.

700{
701 return mAEffect->getParameter(mAEffect, index);
702}
float(* getParameter)(AEffect *, int)
Definition: aeffectx.h:270

References AEffect::getParameter, and mAEffect.

Referenced by FetchSettings(), SaveFXProgram(), and SaveXML().

Here is the caller graph for this function:

◆ callSetChunk() [1/2]

void VSTWrapper::callSetChunk ( bool  isPgm,
int  len,
void *  buf 
)

Definition at line 721 of file VSTWrapper.cpp.

722{
724
725 memset(&info, 0, sizeof(info));
726 info.version = 1;
730
731 callSetChunk(isPgm, len, buf, &info);
732}
int numParams
Definition: aeffectx.h:274
int32_t version
Definition: aeffectx.h:296
int numPrograms
Definition: aeffectx.h:272
int32_t uniqueID
Definition: aeffectx.h:295
void callSetChunk(bool isPgm, int len, void *buf)
Definition: VSTWrapper.cpp:721
int32_t version
Definition: aeffectx.h:355
int32_t pluginUniqueID
Definition: aeffectx.h:356
int32_t numElements
Definition: aeffectx.h:358
int32_t pluginVersion
Definition: aeffectx.h:357

References callSetChunk(), mAEffect, VstPatchChunkInfo::numElements, AEffect::numParams, AEffect::numPrograms, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, AEffect::uniqueID, AEffect::version, and VstPatchChunkInfo::version.

Referenced by VSTInstance::ApplyChunk(), callSetChunk(), HandleXMLEndTag(), LoadFXB(), LoadFXProgram(), VSTEffectBase::LoadUserPreset(), and StoreSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ callSetChunk() [2/2]

void VSTWrapper::callSetChunk ( bool  isPgm,
int  len,
void *  buf,
VstPatchChunkInfo info 
) const

Definition at line 734 of file VSTWrapper.cpp.

735{
736 if (isPgm)
737 {
738 // Ask the effect if this is an acceptable program
739 if (constCallDispatcher(effBeginLoadProgram, 0, 0, info, 0.0) == -1)
740 {
741 return;
742 }
743 }
744 else
745 {
746 // Ask the effect if this is an acceptable bank
747 if (constCallDispatcher(effBeginLoadBank, 0, 0, info, 0.0) == -1)
748 {
749 return;
750 }
751 }
752
753 constCallDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
754 constCallDispatcher(effSetChunk, isPgm ? 1 : 0, len, buf, 0.0);
755 constCallDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
756}
const int effBeginSetProgram
Definition: aeffectx.h:130
const int effBeginLoadBank
Definition: aeffectx.h:136
const int effBeginLoadProgram
Definition: aeffectx.h:138
const int effEndSetProgram
Definition: aeffectx.h:132
const int effSetChunk
Definition: aeffectx.h:112
intptr_t constCallDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt) const
Definition: VSTWrapper.cpp:691

References constCallDispatcher(), effBeginLoadBank, effBeginLoadProgram, effBeginSetProgram, effEndSetProgram, and effSetChunk.

Here is the call graph for this function:

◆ callSetParameter()

void VSTWrapper::callSetParameter ( int  index,
float  value 
) const

Definition at line 704 of file VSTWrapper.cpp.

705{
706 if (mVstVersion == 0 || constCallDispatcher(effCanBeAutomated, 0, index, NULL, 0.0))
707 {
708 mAEffect->setParameter(mAEffect, index, value);
709 }
710}
const int effCanBeAutomated
Definition: aeffectx.h:115
void(* setParameter)(AEffect *, int, float)
Definition: aeffectx.h:268
int mVstVersion
Definition: VSTWrapper.h:165

References constCallDispatcher(), effCanBeAutomated, mAEffect, mVstVersion, and AEffect::setParameter.

Referenced by HandleXMLTag(), LoadFXProgram(), and VSTInstance::RealtimeProcessStart().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ callSetProgram()

void VSTWrapper::callSetProgram ( int  index)

Definition at line 712 of file VSTWrapper.cpp.

713{
714 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
715
716 callDispatcher(effSetProgram, 0, index, NULL, 0.0);
717
718 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
719}
const int effSetProgram
Definition: aeffectx.h:93
intptr_t callDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt) override
Definition: VSTWrapper.cpp:682

References callDispatcher(), effBeginSetProgram, effEndSetProgram, and effSetProgram.

Referenced by VSTEffectBase::DoLoadFactoryPreset(), Load(), and LoadFXB().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ constCallDispatcher()

intptr_t VSTWrapper::constCallDispatcher ( int  opcode,
int  index,
intptr_t  value,
void *  ptr,
float  opt 
) const

Definition at line 691 of file VSTWrapper.cpp.

693{
694 // Assume we are passed a read-only dispatcher function code
695 return const_cast<VSTWrapper*>(this)
696 ->callDispatcher(opcode, index, value, ptr, opt);
697}

References callDispatcher().

Referenced by callSetChunk(), callSetParameter(), FetchSettings(), GetString(), SaveFXB(), SaveFXP(), SaveFXProgram(), VSTEffectBase::SaveUserPreset(), SaveXML(), and StoreSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FetchSettings()

bool VSTWrapper::FetchSettings ( VSTSettings vst3Settings,
bool  doFetch = true 
) const

Definition at line 1714 of file VSTWrapper.cpp.

1715{
1716 // Get the fallback ID-value parameters
1718 (
1719 [&](const ParameterInfo& pi)
1720 {
1721 if (doFetch)
1722 {
1723 float val = callGetParameter(pi.mID);
1724 vstSettings.mParamsMap[pi.mName] = val;
1725 }
1726 else
1727 {
1728 vstSettings.mParamsMap[pi.mName] = std::nullopt;
1729 }
1730 return true;
1731 }
1732 );
1733
1734 // These are here to be checked against for compatibility later
1735 vstSettings.mVersion = mAEffect->version;
1736 vstSettings.mUniqueID = mAEffect->uniqueID;
1737 vstSettings.mNumParams = mAEffect->numParams;
1738
1739 // Get the chunk (if supported)
1740 vstSettings.mChunk.resize(0);
1741
1743 {
1744 void* chunk = nullptr;
1745 int clen = (int)constCallDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
1746 if (clen > 0 && chunk) {
1747 vstSettings.mChunk.resize(clen);
1748 memcpy(vstSettings.mChunk.data(), chunk, clen);
1749 }
1750
1751 if (!doFetch)
1752 {
1753 // Don't keep the contents, but keep a sufficiently allocated string,
1754 // with some extra space in case chunk length might vary
1755 auto size = vstSettings.mChunk.size();
1756 vstSettings.mChunk.resize(0);
1757 vstSettings.mChunk.reserve(2 * size);
1758 }
1759 }
1760
1761 return true;
1762}
const int effGetChunk
Definition: aeffectx.h:111
const int effFlagsProgramChunks
Definition: aeffectx.h:88
int flags
Definition: aeffectx.h:280
void ForEachParameter(ParameterVisitor visitor) const
float callGetParameter(int index) const
Definition: VSTWrapper.cpp:699

References callGetParameter(), constCallDispatcher(), effFlagsProgramChunks, effGetChunk, AEffect::flags, ForEachParameter(), mAEffect, VSTSettings::mChunk, VSTSettings::mNumParams, VSTSettings::mParamsMap, VSTSettings::mUniqueID, VSTSettings::mVersion, AEffect::numParams, MIR::anonymous_namespace{MirUtils.cpp}::pi, size, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEditor::FetchSettingsFromInstance(), VSTEffect::ImportPresetsNC(), VSTEffectBase::LoadFactoryPreset(), VSTEffectBase::LoadUserPreset(), VSTInstance::MakeMessage(), and VSTEffectBase::MakeSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ForEachParameter()

void VSTWrapper::ForEachParameter ( ParameterVisitor  visitor) const

Definition at line 1688 of file VSTWrapper.cpp.

1689{
1690 for (int i = 0; i < mAEffect->numParams; i++)
1691 {
1692 wxString name = GetString(effGetParamName, i);
1693 if (name.empty())
1694 {
1695 name.Printf(wxT("parm_%d"), i);
1696 }
1697 else
1698 /* Easy fix for now for issue 3854, but this should be reconsidered
1699 There is the possibility that two parameter names might collide
1700 after normalizing. A question is whether the normalizing was ever
1701 really needed for saving in a wxConfigFile. Maybe not. But then
1702 redefinition of the keys stored in the file may introduce versioning
1703 difficulties if there is an attempt to fix this in future Audacity.
1704 */
1706
1707 ParameterInfo pi{ i, name };
1708
1709 if (!visitor(pi))
1710 break;
1711 }
1712}
const TranslatableString name
Definition: Distortion.cpp:76
const int effGetParamName
Definition: aeffectx.h:101
static wxString NormalizeName(const wxString &name)
int GetString(wxString &outstr, int opcode, int index=0) const
Definition: VSTWrapper.cpp:651

References effGetParamName, TranslatableString::empty(), GetString(), mAEffect, name, CommandParameters::NormalizeName(), AEffect::numParams, MIR::anonymous_namespace{MirUtils.cpp}::pi, and wxT().

Referenced by FetchSettings(), MakeMessageFS(), VSTEditor::NotifyParameterChanged(), StoreSettings(), and VSTEditor::VSTEditor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetChunkInfo()

VstPatchChunkInfo VSTWrapper::GetChunkInfo ( ) const

Definition at line 603 of file VSTWrapper.cpp.

604{
606 return info;
607}

References mAEffect, AEffect::numParams, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEffectBase::LoadUserPreset().

Here is the caller graph for this function:

◆ GetProcessLevel()

int VSTWrapper::GetProcessLevel ( )

Definition at line 638 of file VSTWrapper.cpp.

639{
640 return mProcessLevel;
641}
int mProcessLevel
Definition: VSTWrapper.h:269

References mProcessLevel.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ GetSampleRate()

float VSTWrapper::GetSampleRate ( )

Definition at line 633 of file VSTWrapper.cpp.

634{
635 return mTimeInfo.sampleRate;
636}
double sampleRate
Definition: aeffectx.h:311
VstTimeInfo mTimeInfo
Definition: VSTWrapper.h:264

References mTimeInfo, and VstTimeInfo::sampleRate.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ GetSettings() [1/2]

static const VSTSettings & VSTWrapper::GetSettings ( const EffectSettings settings)
inlinestatic

Definition at line 110 of file VSTWrapper.h.

111 {
112 auto pSettings = settings.cast<VSTSettings>();
113 assert(pSettings);
114 return *pSettings;
115 }
static Settings & settings()
Definition: TrackInfo.cpp:69

References settings().

Here is the call graph for this function:

◆ GetSettings() [2/2]

static VSTSettings & VSTWrapper::GetSettings ( EffectSettings settings)
inlinestatic

Definition at line 103 of file VSTWrapper.h.

104 {
105 auto pSettings = settings.cast<VSTSettings>();
106 assert(pSettings);
107 return *pSettings;
108 }

References settings().

Referenced by VSTEffect::ExportPresets(), VSTEditor::FetchSettingsFromInstance(), VSTEffect::ImportPresetsNC(), VSTEffectBase::LoadFactoryPreset(), VSTEffectBase::LoadSettings(), VSTEffectBase::LoadUserPreset(), VSTEditor::NotifyParameterChanged(), VSTInstance::ProcessInitialize(), VSTEffectBase::SaveSettings(), VSTEffectBase::SaveUserPreset(), VSTEditor::StoreSettingsToInstance(), and VSTEditor::VSTEditor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetString() [1/2]

wxString VSTWrapper::GetString ( int  opcode,
int  index = 0 
) const

Definition at line 665 of file VSTWrapper.cpp.

666{
667 wxString str;
668
669 GetString(str, opcode, index);
670
671 return str;
672}
#define str(a)

References GetString(), and str.

Here is the call graph for this function:

◆ GetString() [2/2]

int VSTWrapper::GetString ( wxString &  outstr,
int  opcode,
int  index = 0 
) const

Definition at line 651 of file VSTWrapper.cpp.

652{
653 char buf[256];
654
655 memset(buf, 0, sizeof(buf));
656
657 // Assume we are passed a read-only dispatcher function code
658 constCallDispatcher(opcode, index, 0, buf, 0.0);
659
660 outstr = wxString::FromUTF8(buf);
661
662 return 0;
663}

References constCallDispatcher().

Referenced by VSTEditor::BuildPlain(), ForEachParameter(), VSTEffectBase::GetFactoryPresets(), GetString(), Load(), VSTEditor::RefreshParameters(), and SaveXML().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSymbol()

ComponentInterfaceSymbol VSTWrapper::GetSymbol ( ) const

Definition at line 1813 of file VSTWrapper.cpp.

1814{
1815 return mName;
1816}
wxString mName
Definition: VSTWrapper.h:166

References mName.

Referenced by VSTEffectBase::GetSymbol(), HandleXMLTag(), and SaveXML().

Here is the caller graph for this function:

◆ GetTimeInfo()

VstTimeInfo * VSTWrapper::GetTimeInfo ( )

Definition at line 627 of file VSTWrapper.cpp.

628{
629 mTimeInfo.nanoSeconds = wxGetUTCTimeMillis().ToDouble();
630 return &mTimeInfo;
631}
double nanoSeconds
Definition: aeffectx.h:313

References mTimeInfo, and VstTimeInfo::nanoSeconds.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * VSTWrapper::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 1658 of file VSTWrapper.cpp.

1659{
1660 if (tag == "vstprogrampersistence")
1661 {
1662 return this;
1663 }
1664
1665 if (tag == "effect")
1666 {
1667 return this;
1668 }
1669
1670 if (tag == "program")
1671 {
1672 return this;
1673 }
1674
1675 if (tag == "param")
1676 {
1677 return this;
1678 }
1679
1680 if (tag == "chunk")
1681 {
1682 return this;
1683 }
1684
1685 return NULL;
1686}

◆ HandleXMLContent()

void VSTWrapper::HandleXMLContent ( const std::string_view &  content)
override

Definition at line 1650 of file VSTWrapper.cpp.

1651{
1652 if (mInChunk)
1653 {
1654 mChunk += wxString(std::string(content)).Trim(true).Trim(false);
1655 }
1656}
wxString mChunk
Definition: VSTWrapper.h:171
bool mInChunk
Definition: VSTWrapper.h:170

References mChunk, and mInChunk.

◆ HandleXMLEndTag()

void VSTWrapper::HandleXMLEndTag ( const std::string_view &  tag)
override

Definition at line 1620 of file VSTWrapper.cpp.

1621{
1622 if (tag == "chunk")
1623 {
1624 if (mChunk.length())
1625 {
1626 ArrayOf<char> buf{ mChunk.length() / 4 * 3 };
1627
1628 int len = Base64::Decode(mChunk, buf.get());
1629 if (len)
1630 {
1631 callSetChunk(true, len, buf.get(), &mXMLInfo);
1632 }
1633
1634 mChunk.clear();
1635 }
1636 mInChunk = false;
1637 }
1638
1639 if (tag == "program")
1640 {
1641 if (mInSet)
1642 {
1643 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
1644
1645 mInSet = false;
1646 }
1647 }
1648}
STRINGS_API int Decode(const wxString &in, void *out)
Definition: Base64.cpp:67
VstPatchChunkInfo mXMLInfo
Definition: VSTWrapper.h:173
bool mInSet
Definition: VSTWrapper.h:169

References callDispatcher(), callSetChunk(), Base64::Decode(), effEndSetProgram, mChunk, mInChunk, mInSet, and mXMLInfo.

Here is the call graph for this function:

◆ HandleXMLTag()

bool VSTWrapper::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 1413 of file VSTWrapper.cpp.

1414{
1415 if (tag == "vstprogrampersistence")
1416 {
1417 for (auto pair : attrs)
1418 {
1419 auto attr = pair.first;
1420 auto value = pair.second;
1421
1422 if (attr == "version")
1423 {
1424 if (!value.TryGet(mXMLVersion))
1425 {
1426 return false;
1427 }
1428
1429 if (mXMLVersion < 1 || mXMLVersion > 2)
1430 {
1431 return false;
1432 }
1433 }
1434 else
1435 {
1436 return false;
1437 }
1438 }
1439
1440 return true;
1441 }
1442
1443 if (tag == "effect")
1444 {
1445 memset(&mXMLInfo, 0, sizeof(mXMLInfo));
1446 mXMLInfo.version = 1;
1450
1451 for (auto pair : attrs)
1452 {
1453 auto attr = pair.first;
1454 auto value = pair.second;
1455
1456 if (attr == "name")
1457 {
1458 wxString strValue = value.ToWString();
1459
1460 if (strValue != GetSymbol().Internal())
1461 {
1462 using namespace BasicUI;
1463 auto msg = XO("This parameter file was saved from %s. Continue?")
1464 .Format( strValue );
1465 auto result = ShowMessageBox(
1466 msg,
1468 .Caption(XO("Confirm"))
1469 .ButtonStyle(Button::YesNo));
1470 if (result == MessageBoxResult::No)
1471 return false;
1472 }
1473 }
1474 else if (attr == "version")
1475 {
1476 long version;
1477 if (!value.TryGet(version))
1478 {
1479 return false;
1480 }
1481
1482 mXMLInfo.pluginVersion = (int) version;
1483 }
1484 else if (mXMLVersion > 1 && attr == "uniqueID")
1485 {
1486 long uniqueID;
1487 if (!value.TryGet(uniqueID))
1488 {
1489 return false;
1490 }
1491
1492 mXMLInfo.pluginUniqueID = (int) uniqueID;
1493 }
1494 else if (mXMLVersion > 1 && attr == "numParams")
1495 {
1496 long numParams;
1497 if (!value.TryGet(numParams))
1498 {
1499 return false;
1500 }
1501
1502 mXMLInfo.numElements = (int) numParams;
1503 }
1504 else
1505 {
1506 return false;
1507 }
1508 }
1509
1510 return true;
1511 }
1512
1513 if (tag == "program")
1514 {
1515 for (auto pair : attrs)
1516 {
1517 auto attr = pair.first;
1518 auto value = pair.second;
1519
1520 if (attr == "name")
1521 {
1522 const wxString strValue = value.ToWString();
1523
1524 if (strValue.length() > 24)
1525 {
1526 return false;
1527 }
1528
1529 int ndx = 0; //mProgram->GetCurrentSelection();
1530 if (ndx == wxNOT_FOUND)
1531 {
1532 ndx = 0;
1533 }
1534
1535 SetString(effSetProgramName, strValue, ndx);
1536 }
1537 else
1538 {
1539 return false;
1540 }
1541 }
1542
1543 mInChunk = false;
1544
1545 if (callDispatcher(effBeginLoadProgram, 0, 0, &mXMLInfo, 0.0) == -1)
1546 {
1547 return false;
1548 }
1549
1550 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
1551
1552 mInSet = true;
1553
1554 return true;
1555 }
1556
1557 if (tag == "param")
1558 {
1559 long ndx = -1;
1560 double val = -1.0;
1561
1562 for (auto pair : attrs)
1563 {
1564 auto attr = pair.first;
1565 auto value = pair.second;
1566
1567 if (attr == "index")
1568 {
1569 if (!value.TryGet(ndx))
1570 {
1571 return false;
1572 }
1573
1574 if (ndx < 0 || ndx >= mAEffect->numParams)
1575 {
1576 // Could be a different version of the effect...probably should
1577 // tell the user
1578 return false;
1579 }
1580 }
1581 // "name" attribute is ignored for params
1582 /* else if (attr == "name")
1583 {
1584
1585 // Nothing to do with it for now
1586 }*/
1587 else if (attr == "value")
1588 {
1589 if (!value.TryGet(val))
1590 {
1591 return false;
1592 }
1593
1594 if (val < 0.0 || val > 1.0)
1595 {
1596 return false;
1597 }
1598 }
1599 }
1600
1601 if (ndx == -1 || val == -1.0)
1602 {
1603 return false;
1604 }
1605
1606 callSetParameter(ndx, val);
1607
1608 return true;
1609 }
1610
1611 if (tag == "chunk")
1612 {
1613 mInChunk = true;
1614 return true;
1615 }
1616
1617 return false;
1618}
@ Internal
Indicates internal failure from Audacity.
XO("Cut/Copy/Paste")
const int effSetProgramName
Definition: aeffectx.h:96
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:277
MessageBoxOptions && Caption(TranslatableString caption_) &&
Definition: BasicUI.h:101
long mXMLVersion
Definition: VSTWrapper.h:172
void SetString(int opcode, const wxString &str, int index=0)
Definition: VSTWrapper.cpp:674
void callSetParameter(int index, float value) const
Definition: VSTWrapper.cpp:704
ComponentInterfaceSymbol GetSymbol() const

References callDispatcher(), callSetParameter(), BasicUI::MessageBoxOptions::Caption(), effBeginLoadProgram, effBeginSetProgram, effSetProgramName, GetSymbol(), Internal, mAEffect, mInChunk, mInSet, mXMLInfo, mXMLVersion, VstPatchChunkInfo::numElements, AEffect::numParams, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, SetString(), BasicUI::ShowMessageBox(), AEffect::uniqueID, AEffect::version, VstPatchChunkInfo::version, and XO().

Here is the call graph for this function:

◆ IsCompatible()

bool VSTWrapper::IsCompatible ( const VstPatchChunkInfo info) const

Definition at line 609 of file VSTWrapper.cpp.

610{
611 return (info.pluginUniqueID == mAEffect->uniqueID) &&
612 (info.pluginVersion == mAEffect->version) &&
613 (info.numElements == mAEffect->numParams);
614}

References mAEffect, VstPatchChunkInfo::numElements, AEffect::numParams, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEffectBase::LoadUserPreset().

Here is the caller graph for this function:

◆ Load()

bool VSTWrapper::Load ( )

Definition at line 307 of file VSTWrapper.cpp.

308{
309 vstPluginMain pluginMain;
310 bool success = false;
311
312 long effectID = 0;
313 wxString realPath = mPath.BeforeFirst(wxT(';'));
314 mPath.AfterFirst(wxT(';')).ToLong(&effectID);
315 mCurrentEffectID = (intptr_t) effectID;
316
317 mModule = NULL;
318 mAEffect = NULL;
319
320#if defined(__WXMAC__)
321 // Start clean
322 mBundleRef.reset();
323
324 mResource = ResourceHandle{};
325
326 // Convert the path to a CFSTring
327 wxCFStringRef path(realPath);
328
329 // Create the bundle using the URL
330 BundleHandle bundleRef{ CFBundleCreate(kCFAllocatorDefault,
331 // Convert the path to a URL
332 CF_ptr<CFURLRef>{
333 CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
334 path, kCFURLPOSIXPathStyle, true)
335 }.get()
336 )};
337
338 // Bail if the bundle wasn't created
339 if (!bundleRef)
340 return false;
341
342
343 // Convert back to path
344 UInt8 exePath[PLATFORM_MAX_PATH];
345 Boolean good = CFURLGetFileSystemRepresentation(
346 // Retrieve a reference to the executable
347 CF_ptr<CFURLRef>{ CFBundleCopyExecutableURL(bundleRef.get()) }.get(),
348 true, exePath, sizeof(exePath)
349 );
350
351 // Bail if we couldn't resolve the executable path
352 if (good == FALSE)
353 return false;
354
355 // Attempt to open it
356 mModule.reset((char*)dlopen((char *) exePath, RTLD_NOW | RTLD_LOCAL));
357 if (!mModule)
358 return false;
359
360 // Try to locate the NEW plugin entry point
361 pluginMain = (vstPluginMain) dlsym(mModule.get(), "VSTPluginMain");
362
363 // If not found, try finding the old entry point
364 if (pluginMain == NULL)
365 {
366 pluginMain = (vstPluginMain) dlsym(mModule.get(), "main_macho");
367 }
368
369 // Must not be a VST plugin
370 if (pluginMain == NULL)
371 {
372 mModule.reset();
373 return false;
374 }
375
376 // Need to keep the bundle reference around so we can map the
377 // resources.
378 mBundleRef = std::move(bundleRef);
379
380 // Open the resource map ... some plugins (like GRM Tools) need this.
381 mResource = ResourceHandle{
382 mBundleRef.get(), CFBundleOpenBundleResourceMap(mBundleRef.get())
383 };
384
385#elif defined(__WXMSW__)
386
387 {
388 wxLogNull nolog;
389
390 // Try to load the library
391 auto lib = std::make_unique<wxDynamicLibrary>(realPath);
392 if (!lib)
393 return false;
394
395 // Bail if it wasn't successful
396 if (!lib->IsLoaded())
397 return false;
398
399 // Try to find the entry point, while suppressing error messages
400 pluginMain = (vstPluginMain) lib->GetSymbol(wxT("VSTPluginMain"));
401 if (pluginMain == NULL)
402 {
403 pluginMain = (vstPluginMain) lib->GetSymbol(wxT("main"));
404 if (pluginMain == NULL)
405 return false;
406 }
407
408 // Save the library reference
409 mModule = std::move(lib);
410 }
411
412#else
413
414 // Attempt to load it
415 //
416 // Spent a few days trying to figure out why some VSTs where running okay and
417 // others were hit or miss. The cause was that we export all of Audacity's
418 // symbols and some of the loaded libraries were picking up Audacity's and
419 // not their own.
420 //
421 // So far, I've only seen this issue on Linux, but we might just be getting
422 // lucky on the Mac and Windows. The sooner we stop exporting everything
423 // the better.
424 //
425 // To get around the problem, I just added the RTLD_DEEPBIND flag to the load
426 // and that "basically" puts Audacity last when the loader needs to resolve
427 // symbols.
428 //
429 // Once we define a proper external API, the flags can be removed.
430#ifndef RTLD_DEEPBIND
431#define RTLD_DEEPBIND 0
432#endif
433 ModuleHandle lib {
434 (char*) dlopen((const char *)wxString(realPath).ToUTF8(),
435 RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND)
436 };
437 if (!lib)
438 {
439 return false;
440 }
441
442 // Try to find the entry point, while suppressing error messages
443 pluginMain = (vstPluginMain) dlsym(lib.get(), "VSTPluginMain");
444 if (pluginMain == NULL)
445 {
446 pluginMain = (vstPluginMain) dlsym(lib.get(), "main");
447 if (pluginMain == NULL)
448 return false;
449 }
450
451 // Save the library reference
452 mModule = std::move(lib);
453
454#endif
455
456 // Initialize the plugin
457 try
458 {
459 mAEffect = pluginMain(VSTWrapper::AudioMaster);
460 }
461 catch (...)
462 {
463 wxLogMessage(wxT("VST plugin initialization failed\n"));
464 mAEffect = NULL;
465 }
466
467 // Was it successful?
468 if (mAEffect)
469 {
471
472 // Must use the GUI editor if parameters aren't provided
473 if (mAEffect->numParams == 0)
474 {
475 mGui = true;
476 }
477
478 // Save a reference to ourselves
479 //
480 // Note: Some hosts use "user" and some use "ptr2/resvd2". It might
481 // be worthwhile to check if user is NULL before using it and
482 // then falling back to "ptr2/resvd2".
483 mAEffect->ptr2 = static_cast<VSTWrapper*>(this);
484
485 // Give the plugin an initial sample rate and blocksize
486 callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0);
487 callDispatcher(effSetBlockSize, 0, 512, NULL, 0);
488
489 // Ask the plugin to identify itself...might be needed for older plugins
490 callDispatcher(effIdentify, 0, 0, NULL, 0);
491
492 // Open the plugin
493 callDispatcher(effOpen, 0, 0, NULL, 0.0);
494
495 // Get the VST version the plugin understands
497
498 // Set it again in case plugin ignored it before the effOpen
499 callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0);
500 callDispatcher(effSetBlockSize, 0, 512, NULL, 0);
501
502 // Ensure that it looks like a plugin and can deal with ProcessReplacing
503 // calls. Also exclude synths for now.
504 if (mAEffect->magic == kEffectMagic &&
507 {
508 if (mVstVersion >= 2)
509 {
511 if (mName.length() == 0)
512 {
514 }
515 }
516 if (mName.length() == 0)
517 {
518 mName = wxFileName{realPath}.GetName();
519 }
520
521 if (mVstVersion >= 2)
522 {
524 mVersion = wxINT32_SWAP_ON_LE(callDispatcher(effGetVendorVersion, 0, 0, NULL, 0));
525 }
526 if (mVersion == 0)
527 {
528 mVersion = wxINT32_SWAP_ON_LE(mAEffect->version);
529 }
530
532 {
533 mInteractive = true;
534 }
535
538
539 // Check to see if parameters can be automated. This isn't a guarantee
540 // since it could be that the effect simply doesn't support the opcode.
541 mAutomatable = false;
542 for (int i = 0; i < mAEffect->numParams; i++)
543 {
544 if (callDispatcher(effCanBeAutomated, 0, i, NULL, 0.0))
545 {
546 mAutomatable = true;
547 break;
548 }
549 }
550
551 // Make sure we start out with a valid program selection
552 // I've found one plugin (SoundHack +morphfilter) that will
553 // crash Audacity when saving the initial default parameters
554 // with this.
556
557 // Pretty confident that we're good to go
558 success = true;
559 }
560 }
561
562 if (!success)
563 {
564 Unload();
566 }
567
568 return success;
569}
#define PLATFORM_MAX_PATH
Definition: FileNames.h:42
AEffect *(* vstPluginMain)(audioMasterCallback audioMaster)
Definition: VSTWrapper.cpp:57
const int effGetVendorVersion
Definition: aeffectx.h:124
const int effGetVstVersion
Definition: aeffectx.h:128
const int kEffectMagic
Definition: aeffectx.h:144
const int effGetProductString
Definition: aeffectx.h:123
const int effSetBlockSize
Definition: aeffectx.h:103
const int effGetVendorString
Definition: aeffectx.h:122
const int effFlagsIsSynth
Definition: aeffectx.h:89
const int effGetEffectName
Definition: aeffectx.h:120
const int effFlagsCanReplacing
Definition: aeffectx.h:87
const int effOpen
Definition: aeffectx.h:91
const int effSetSampleRate
Definition: aeffectx.h:102
const int effFlagsHasEditor
Definition: aeffectx.h:86
const int effIdentify
Definition: aeffectx.h:110
int numOutputs
Definition: aeffectx.h:278
int numInputs
Definition: aeffectx.h:276
int magic
Definition: aeffectx.h:262
bool mAutomatable
Definition: VSTWrapper.h:224
unsigned mAudioOuts
Definition: VSTWrapper.h:221
std::unique_ptr< wxDynamicLibrary > ModuleHandle
Definition: VSTWrapper.h:207
BundleHandle mBundleRef
Definition: VSTWrapper.h:235
static intptr_t AudioMaster(AEffect *effect, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
Definition: VSTWrapper.cpp:59
CF_ptr< CFBundleRef > BundleHandle
Definition: VSTWrapper.h:233
bool mInteractive
Definition: VSTWrapper.h:219
int mVersion
Definition: VSTWrapper.h:218
ResourceHandle mResource
Definition: VSTWrapper.h:258
void callSetProgram(int index)
Definition: VSTWrapper.cpp:712
unsigned mAudioIns
Definition: VSTWrapper.h:220
ModuleHandle mModule
Definition: VSTWrapper.h:214
wxString mVendor
Definition: VSTWrapper.h:216

References AudioMaster(), callDispatcher(), callSetProgram(), effCanBeAutomated, effFlagsCanReplacing, effFlagsHasEditor, effFlagsIsSynth, effGetEffectName, effGetProductString, effGetVendorString, effGetVendorVersion, effGetVstVersion, effIdentify, effOpen, effSetBlockSize, effSetSampleRate, AEffect::flags, GetString(), kEffectMagic, mAEffect, AEffect::magic, mAudioIns, mAudioOuts, mAutomatable, mBundleRef, mCurrentEffectID, mGui, mInteractive, mModule, mName, mPath, mResource, mVendor, mVersion, mVstVersion, AEffect::numInputs, AEffect::numOutputs, AEffect::numParams, PLATFORM_MAX_PATH, AEffect::ptr2, ResetModuleAndHandle(), Unload(), AEffect::version, and wxT().

Referenced by VSTEffectsModule::DiscoverPluginsAtPath(), VSTEffectBase::InitializePlugin(), and VSTInstance::VSTInstance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadFXB()

bool VSTWrapper::LoadFXB ( const wxFileName &  fn)

Definition at line 758 of file VSTWrapper.cpp.

759{
760 bool ret = false;
761
762 // Try to open the file...will be closed automatically when method returns
763 wxFFile f(fn.GetFullPath(), wxT("rb"));
764 if (!f.IsOpened())
765 {
766 return false;
767 }
768
769 // Allocate memory for the contents
770 ArrayOf<unsigned char> data{ size_t(f.Length()) };
771 if (!data)
772 {
773 using namespace BasicUI;
775 XO("Unable to allocate memory when loading presets file."),
777 .Caption(XO("Error Loading VST Presets")));
778 return false;
779 }
780 unsigned char *bptr = data.get();
781
782 do
783 {
784 // Read in the whole file
785 ssize_t len = f.Read((void *) bptr, f.Length());
786 if (f.Error())
787 {
788 using namespace BasicUI;
790 XO("Unable to read presets file."),
792 .Caption(XO("Error Loading VST Presets")));
793 break;
794 }
795
796 // Most references to the data are via an "int" array
797 int32_t *iptr = (int32_t *) bptr;
798
799 // Verify that we have at least enough for the header
800 if (len < 156)
801 {
802 break;
803 }
804
805 // Verify that we probably have an FX file
806 if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K'))
807 {
808 break;
809 }
810
811 // Ignore the size...sometimes it's there, other times it's zero
812
813 // Get the version and verify
814 int version = wxINT32_SWAP_ON_LE(iptr[3]);
815 if (version != 1 && version != 2)
816 {
817 break;
818 }
819
820 VstPatchChunkInfo info =
821 {
822 1,
823 wxINT32_SWAP_ON_LE(iptr[4]),
824 wxINT32_SWAP_ON_LE(iptr[5]),
825 wxINT32_SWAP_ON_LE(iptr[6]),
826 ""
827 };
828
829 // Ensure this program looks to belong to the current plugin
830 if ((info.pluginUniqueID != mAEffect->uniqueID) &&
831 (info.pluginVersion != mAEffect->version) &&
833 {
834 break;
835 }
836
837 // Get the number of programs
838 int numProgs = info.numElements;
839
840 // Get the current program index
841 int curProg = 0;
842 if (version >= 2)
843 {
844 curProg = wxINT32_SWAP_ON_LE(iptr[7]);
845 if (curProg < 0 || curProg >= numProgs)
846 {
847 break;
848 }
849 }
850
851 // Is it a bank of programs?
852 if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'B', 'k'))
853 {
854 // Drop the header
855 bptr += 156;
856 len -= 156;
857
858 unsigned char *tempPtr = bptr;
859 ssize_t tempLen = len;
860
861 // Validate all of the programs
862 for (int i = 0; i < numProgs; i++)
863 {
864 if (!LoadFXProgram(&tempPtr, tempLen, i, true))
865 {
866 break;
867 }
868 }
869
870 // Ask the effect if this is an acceptable bank
871 if (callDispatcher(effBeginLoadBank, 0, 0, &info, 0.0) == -1)
872 {
873 return false;
874 }
875
876 // Start loading the individual programs
877 for (int i = 0; i < numProgs; i++)
878 {
879 ret = LoadFXProgram(&bptr, len, i, false);
880 }
881 }
882 // Or maybe a bank chunk?
883 else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'B', 'C', 'h'))
884 {
885 // Can't load programs chunks if the plugin doesn't support it
887 {
888 break;
889 }
890
891 // Verify that we have enough to grab the chunk size
892 if (len < 160)
893 {
894 break;
895 }
896
897 // Get the chunk size
898 int size = wxINT32_SWAP_ON_LE(iptr[39]);
899
900 // We finally know the full length of the program
901 int proglen = 160 + size;
902
903 // Verify that we have enough for the entire program
904 if (len < proglen)
905 {
906 break;
907 }
908
909 // Set the entire bank in one shot
910 callSetChunk(false, size, &iptr[40], &info);
911
912 // Success
913 ret = true;
914 }
915 // Unrecognizable type
916 else
917 {
918 break;
919 }
920
921 // Set the active program
922 if (ret && version >= 2)
923 {
924 callSetProgram(curProg);
925 }
926 } while (false);
927
928 return ret;
929}
static const auto fn
#define CCONST(a, b, c, d)
Definition: aeffectx.h:29
bool LoadFXProgram(unsigned char **bptr, ssize_t &len, int index, bool dryrun)
Definition: VSTWrapper.cpp:983

References callDispatcher(), callSetChunk(), callSetProgram(), BasicUI::MessageBoxOptions::Caption(), CCONST, effBeginLoadBank, effFlagsProgramChunks, AEffect::flags, fn, LoadFXProgram(), mAEffect, VstPatchChunkInfo::numElements, AEffect::numPrograms, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, BasicUI::ShowMessageBox(), size, AEffect::uniqueID, AEffect::version, wxT(), and XO().

Referenced by VSTEffect::ImportPresetsNC().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadFXP()

bool VSTWrapper::LoadFXP ( const wxFileName &  fn)

Definition at line 931 of file VSTWrapper.cpp.

932{
933 bool ret = false;
934
935 // Try to open the file...will be closed automatically when method returns
936 wxFFile f(fn.GetFullPath(), wxT("rb"));
937 if (!f.IsOpened())
938 {
939 return false;
940 }
941
942 // Allocate memory for the contents
943 ArrayOf<unsigned char> data{ size_t(f.Length()) };
944 if (!data)
945 {
946 using namespace BasicUI;
948 XO("Unable to allocate memory when loading presets file."),
950 .Caption(XO("Error Loading VST Presets")));
951 return false;
952 }
953 unsigned char *bptr = data.get();
954
955 do
956 {
957 // Read in the whole file
958 ssize_t len = f.Read((void *) bptr, f.Length());
959 if (f.Error())
960 {
961 using namespace BasicUI;
963 XO("Unable to read presets file."),
965 .Caption(XO("Error Loading VST Presets")));
966 break;
967 }
968
969 // Get (or default) currently selected program
970 int i = 0; //mProgram->GetCurrentSelection();
971 if (i < 0)
972 {
973 i = 0; // default to first program
974 }
975
976 // Go verify and set the program
977 ret = LoadFXProgram(&bptr, len, i, false);
978 } while (false);
979
980 return ret;
981}

References BasicUI::MessageBoxOptions::Caption(), fn, LoadFXProgram(), BasicUI::ShowMessageBox(), wxT(), and XO().

Referenced by VSTEffect::ImportPresetsNC().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadFXProgram()

bool VSTWrapper::LoadFXProgram ( unsigned char **  bptr,
ssize_t &  len,
int  index,
bool  dryrun 
)

Definition at line 983 of file VSTWrapper.cpp.

984{
985 // Most references to the data are via an "int" array
986 int32_t *iptr = (int32_t *) *bptr;
987
988 // Verify that we have at least enough for a program without parameters
989 if (len < 28)
990 {
991 return false;
992 }
993
994 // Verify that we probably have an FX file
995 if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K'))
996 {
997 return false;
998 }
999
1000 // Ignore the size...sometimes it's there, other times it's zero
1001
1002 // Get the version and verify
1003#if defined(IS_THIS_AN_FXP_ARTIFICAL_LIMITATION)
1004 int version = wxINT32_SWAP_ON_LE(iptr[3]);
1005 if (version != 1)
1006 {
1007 return false;
1008 }
1009#endif
1010
1011 VstPatchChunkInfo info =
1012 {
1013 1,
1014 wxINT32_SWAP_ON_LE(iptr[4]),
1015 wxINT32_SWAP_ON_LE(iptr[5]),
1016 wxINT32_SWAP_ON_LE(iptr[6]),
1017 ""
1018 };
1019
1020 // Ensure this program looks to belong to the current plugin
1021 if ((info.pluginUniqueID != mAEffect->uniqueID) &&
1022 (info.pluginVersion != mAEffect->version) &&
1023 (info.numElements != mAEffect->numParams))
1024 {
1025 return false;
1026 }
1027
1028 // Get the number of parameters
1029 int numParams = info.numElements;
1030
1031 // At this point, we have to have enough to include the program name as well
1032 if (len < 56)
1033 {
1034 return false;
1035 }
1036
1037 // Get the program name
1038 wxString progName(wxString::From8BitData((char *)&iptr[7]));
1039
1040 // Might be a regular program
1041 if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'C', 'k'))
1042 {
1043 // We finally know the full length of the program
1044 int proglen = 56 + (numParams * sizeof(float));
1045
1046 // Verify that we have enough for all of the parameter values
1047 if (len < proglen)
1048 {
1049 return false;
1050 }
1051
1052 // Validate all of the parameter values
1053 for (int i = 0; i < numParams; i++)
1054 {
1055 uint32_t ival = wxUINT32_SWAP_ON_LE(iptr[14 + i]);
1056 float val = reinterpretAsFloat(ival);
1057 if (val < 0.0 || val > 1.0)
1058 {
1059 return false;
1060 }
1061 }
1062
1063 // They look okay...time to start changing things
1064 if (!dryrun)
1065 {
1066 // Ask the effect if this is an acceptable program
1067 if (callDispatcher(effBeginLoadProgram, 0, 0, &info, 0.0) == -1)
1068 {
1069 return false;
1070 }
1071
1072 // Load all of the parameters
1073 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
1074 for (int i = 0; i < numParams; i++)
1075 {
1076 wxUint32 val = wxUINT32_SWAP_ON_LE(iptr[14 + i]);
1078 }
1079 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
1080 }
1081
1082 // Update in case we're loading an "FxBk" format bank file
1083 *bptr += proglen;
1084 len -= proglen;
1085 }
1086 // Maybe we have a program chunk
1087 else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'P', 'C', 'h'))
1088 {
1089 // Can't load programs chunks if the plugin doesn't support it
1091 {
1092 return false;
1093 }
1094
1095 // Verify that we have enough to grab the chunk size
1096 if (len < 60)
1097 {
1098 return false;
1099 }
1100
1101 // Get the chunk size
1102 int size = wxINT32_SWAP_ON_LE(iptr[14]);
1103
1104 // We finally know the full length of the program
1105 int proglen = 60 + size;
1106
1107 // Verify that we have enough for the entire program
1108 if (len < proglen)
1109 {
1110 return false;
1111 }
1112
1113 // Set the entire program in one shot
1114 if (!dryrun)
1115 {
1116 callSetChunk(true, size, &iptr[15], &info);
1117 }
1118
1119 // Update in case we're loading an "FxBk" format bank file
1120 *bptr += proglen;
1121 len -= proglen;
1122 }
1123 else
1124 {
1125 // Unknown type
1126 return false;
1127 }
1128
1129 if (!dryrun)
1130 {
1131 SetString(effSetProgramName, wxString(progName), index);
1132 }
1133
1134 return true;
1135}
static float reinterpretAsFloat(uint32_t x)
Definition: VSTWrapper.cpp:40

References callDispatcher(), callSetChunk(), callSetParameter(), CCONST, effBeginLoadProgram, effBeginSetProgram, effEndSetProgram, effFlagsProgramChunks, effSetProgramName, AEffect::flags, mAEffect, VstPatchChunkInfo::numElements, AEffect::numParams, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, reinterpretAsFloat(), SetString(), size, AEffect::uniqueID, and AEffect::version.

Referenced by LoadFXB(), and LoadFXP().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadXML()

bool VSTWrapper::LoadXML ( const wxFileName &  fn)

Definition at line 1137 of file VSTWrapper.cpp.

1138{
1139 mInChunk = false;
1140 mInSet = false;
1141
1142 // default to read as XML file
1143 // Load the program
1144 XMLFileReader reader;
1145 bool ok = reader.Parse(this, fn.GetFullPath());
1146
1147 // Something went wrong with the file, clean up
1148 if (mInSet)
1149 {
1150 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
1151
1152 mInSet = false;
1153 }
1154
1155 if (!ok)
1156 {
1157 using namespace BasicUI;
1158 // Inform user of load failure
1160 reader.GetErrorStr(),
1162 .Caption(XO("Error Loading VST Presets")));
1163 return false;
1164 }
1165
1166 return true;
1167}
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
const TranslatableString & GetErrorStr() const
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)

References callDispatcher(), BasicUI::MessageBoxOptions::Caption(), effEndSetProgram, fn, XMLFileReader::GetErrorStr(), mInChunk, mInSet, XMLFileReader::Parse(), BasicUI::ShowMessageBox(), and XO().

Referenced by VSTEffect::ImportPresetsNC().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMessageFS()

std::unique_ptr< EffectInstance::Message > VSTWrapper::MakeMessageFS ( const VSTSettings settings) const

Definition at line 1819 of file VSTWrapper.cpp.

1820{
1821 VSTMessage::ParamVector paramVector;
1822 paramVector.resize(mAEffect->numParams, std::nullopt);
1823
1825 (
1826 [&](const VSTWrapper::ParameterInfo& pi)
1827 {
1828 auto &slot = paramVector[pi.mID]; // operator [] may make a nullopt
1829 const auto iter = settings.mParamsMap.find(pi.mName),
1830 end = settings.mParamsMap.end();
1831 if (iter != end)
1832 slot = iter->second;
1833 return true;
1834 }
1835 );
1836
1837 return std::make_unique<VSTMessage>(
1838 settings.mChunk /* vector copy */, std::move(paramVector));
1839}
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
std::vector< std::optional< double > > ParamVector
Definition: VSTWrapper.h:300

References PackedArray::end(), ForEachParameter(), mAEffect, AEffect::numParams, MIR::anonymous_namespace{MirUtils.cpp}::pi, and settings().

Referenced by VSTEffect::ImportPresetsNC(), VSTEffectBase::LoadFactoryPreset(), VSTEffectBase::LoadUserPreset(), and VSTEditor::VSTEditor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ResetModuleAndHandle()

void VSTWrapper::ResetModuleAndHandle ( )

Definition at line 583 of file VSTWrapper.cpp.

584{
585 if (mModule)
586 {
587#if defined(__WXMAC__)
589 mBundleRef.reset();
590#endif
591
592 mModule.reset();
593 mAEffect = NULL;
594 }
595}

References mAEffect, mBundleRef, mModule, mResource, and VSTWrapper::ResourceHandle::reset().

Referenced by Load(), and ~VSTWrapper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveFXB()

void VSTWrapper::SaveFXB ( const wxFileName &  fn) const

Definition at line 1169 of file VSTWrapper.cpp.

1170{
1171 // Create/Open the file
1172 const wxString fullPath{fn.GetFullPath()};
1173 wxFFile f(fullPath, wxT("wb"));
1174 if (!f.IsOpened())
1175 {
1176 using namespace BasicUI;
1178 XO("Could not open file: \"%s\"").Format( fullPath ),
1180 .Caption(XO("Error Saving VST Presets")));
1181 return;
1182 }
1183
1184 wxMemoryBuffer buf;
1185 wxInt32 subType;
1186 void *chunkPtr = nullptr;
1187 int chunkSize = 0;
1188 int dataSize = 148;
1189 wxInt32 tab[8];
1190 int curProg = 0 ; //mProgram->GetCurrentSelection();
1191
1193 {
1194 subType = CCONST('F', 'B', 'C', 'h');
1195
1196 // read-only dispatcher function
1197 chunkSize = constCallDispatcher(effGetChunk, 0, 0, &chunkPtr, 0.0);
1198 dataSize += 4 + chunkSize;
1199 }
1200 else
1201 {
1202 subType = CCONST('F', 'x', 'B', 'k');
1203
1204 for (int i = 0; i < mAEffect->numPrograms; i++)
1205 {
1206 SaveFXProgram(buf, i);
1207 }
1208
1209 dataSize += buf.GetDataLen();
1210 }
1211
1212 tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K'));
1213 tab[1] = wxINT32_SWAP_ON_LE(dataSize);
1214 tab[2] = wxINT32_SWAP_ON_LE(subType);
1215 tab[3] = wxINT32_SWAP_ON_LE(curProg >= 0 ? 2 : 1);
1216 tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID);
1217 tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version);
1218 tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numPrograms);
1219 tab[7] = wxINT32_SWAP_ON_LE(curProg >= 0 ? curProg : 0);
1220
1221 f.Write(tab, sizeof(tab));
1222 if (!f.Error())
1223 {
1224 char padding[124];
1225 memset(padding, 0, sizeof(padding));
1226 f.Write(padding, sizeof(padding));
1227
1228 if (!f.Error())
1229 {
1231 {
1232 wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize);
1233 f.Write(&size, sizeof(size));
1234 f.Write(chunkPtr, chunkSize);
1235 }
1236 else
1237 {
1238 f.Write(buf.GetData(), buf.GetDataLen());
1239 }
1240 }
1241 }
1242
1243 if (f.Error())
1244 {
1245 using namespace BasicUI;
1247 XO("Error writing to file: \"%s\"").Format( fullPath ),
1249 .Caption(XO("Error Saving VST Presets")));
1250 }
1251
1252 f.Close();
1253
1254 return;
1255}
Abstract base class used in importing a file.
void SaveFXProgram(wxMemoryBuffer &buf, int index) const

References BasicUI::MessageBoxOptions::Caption(), CCONST, constCallDispatcher(), effFlagsProgramChunks, effGetChunk, AEffect::flags, fn, mAEffect, AEffect::numPrograms, SaveFXProgram(), BasicUI::ShowMessageBox(), size, AEffect::uniqueID, AEffect::version, wxT(), and XO().

Referenced by VSTEffect::ExportPresets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveFXP()

void VSTWrapper::SaveFXP ( const wxFileName &  fn) const

Definition at line 1257 of file VSTWrapper.cpp.

1258{
1259 // Create/Open the file
1260 const wxString fullPath{ fn.GetFullPath() };
1261 wxFFile f(fullPath, wxT("wb"));
1262 if (!f.IsOpened())
1263 {
1264 using namespace BasicUI;
1266 XO("Could not open file: \"%s\"").Format( fullPath ),
1268 .Caption(XO("Error Saving VST Presets")));
1269 return;
1270 }
1271
1272 wxMemoryBuffer buf;
1273
1274 // read-only dispatcher function
1275 int ndx = constCallDispatcher(effGetProgram, 0, 0, NULL, 0.0);
1276 SaveFXProgram(buf, ndx);
1277
1278 f.Write(buf.GetData(), buf.GetDataLen());
1279 if (f.Error())
1280 {
1281 using namespace BasicUI;
1283 XO("Error writing to file: \"%s\"").Format( fullPath ),
1285 .Caption(XO("Error Saving VST Presets")));
1286 }
1287
1288 f.Close();
1289
1290 return;
1291}
const int effGetProgram
Definition: aeffectx.h:94

References BasicUI::MessageBoxOptions::Caption(), constCallDispatcher(), effGetProgram, fn, SaveFXProgram(), BasicUI::ShowMessageBox(), wxT(), and XO().

Referenced by VSTEffect::ExportPresets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveFXProgram()

void VSTWrapper::SaveFXProgram ( wxMemoryBuffer &  buf,
int  index 
) const

Definition at line 1293 of file VSTWrapper.cpp.

1294{
1295 wxInt32 subType;
1296 void *chunkPtr;
1297 int chunkSize;
1298 int dataSize = 48;
1299 char progName[28];
1300 wxInt32 tab[7];
1301
1302 // read-only dispatcher function
1303 constCallDispatcher(effGetProgramNameIndexed, index, 0, &progName, 0.0);
1304 progName[27] = '\0';
1305 chunkSize = strlen(progName);
1306 memset(&progName[chunkSize], 0, sizeof(progName) - chunkSize);
1307
1309 {
1310 subType = CCONST('F', 'P', 'C', 'h');
1311
1312 // read-only dispatcher function
1313 chunkSize = constCallDispatcher(effGetChunk, 1, 0, &chunkPtr, 0.0);
1314 dataSize += 4 + chunkSize;
1315 }
1316 else
1317 {
1318 subType = CCONST('F', 'x', 'C', 'k');
1319
1320 dataSize += (mAEffect->numParams << 2);
1321 }
1322
1323 tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K'));
1324 tab[1] = wxINT32_SWAP_ON_LE(dataSize);
1325 tab[2] = wxINT32_SWAP_ON_LE(subType);
1326 tab[3] = wxINT32_SWAP_ON_LE(1);
1327 tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID);
1328 tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version);
1329 tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numParams);
1330
1331 buf.AppendData(tab, sizeof(tab));
1332 buf.AppendData(progName, sizeof(progName));
1333
1335 {
1336 wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize);
1337 buf.AppendData(&size, sizeof(size));
1338 buf.AppendData(chunkPtr, chunkSize);
1339 }
1340 else
1341 {
1342 for (int i = 0; i < mAEffect->numParams; i++)
1343 {
1344 float val = callGetParameter(i);
1345 wxUint32 ival = wxUINT32_SWAP_ON_LE(reinterpretAsUint32(val));
1346 buf.AppendData(&ival, sizeof(ival));
1347 }
1348 }
1349
1350 return;
1351}
static uint32_t reinterpretAsUint32(float f)
Definition: VSTWrapper.cpp:48
const int effGetProgramNameIndexed
Definition: aeffectx.h:117

References callGetParameter(), CCONST, constCallDispatcher(), effFlagsProgramChunks, effGetChunk, effGetProgramNameIndexed, AEffect::flags, mAEffect, AEffect::numParams, reinterpretAsUint32(), size, AEffect::uniqueID, and AEffect::version.

Referenced by SaveFXB(), and SaveFXP().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveXML()

void VSTWrapper::SaveXML ( const wxFileName &  fn) const

Definition at line 1354 of file VSTWrapper.cpp.

1356{
1357 XMLFileWriter xmlFile{ fn.GetFullPath(), XO("Error Saving Effect Presets") };
1358
1359 xmlFile.StartTag(wxT("vstprogrampersistence"));
1360 xmlFile.WriteAttr(wxT("version"), wxT("2"));
1361
1362 xmlFile.StartTag(wxT("effect"));
1363 // Use internal name only in persistent information
1364 xmlFile.WriteAttr(wxT("name"), GetSymbol().Internal());
1365 xmlFile.WriteAttr(wxT("uniqueID"), mAEffect->uniqueID);
1366 xmlFile.WriteAttr(wxT("version"), mAEffect->version);
1367 xmlFile.WriteAttr(wxT("numParams"), mAEffect->numParams);
1368
1369 xmlFile.StartTag(wxT("program"));
1370 xmlFile.WriteAttr(wxT("name"), wxEmptyString); //mProgram->GetValue());
1371
1372 int clen = 0;
1374 {
1375 void *chunk = NULL;
1376
1377 // read-only dispatcher function
1378 clen = (int) constCallDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
1379 if (clen != 0)
1380 {
1381 xmlFile.StartTag(wxT("chunk"));
1382 xmlFile.WriteSubTree(Base64::Encode(chunk, clen) + wxT('\n'));
1383 xmlFile.EndTag(wxT("chunk"));
1384 }
1385 }
1386
1387 if (clen == 0)
1388 {
1389 for (int i = 0; i < mAEffect->numParams; i++)
1390 {
1391 xmlFile.StartTag(wxT("param"));
1392
1393 xmlFile.WriteAttr(wxT("index"), i);
1394 xmlFile.WriteAttr(wxT("name"),
1396 xmlFile.WriteAttr(wxT("value"),
1397 wxString::Format(wxT("%f"),
1398 callGetParameter(i)));
1399
1400 xmlFile.EndTag(wxT("param"));
1401 }
1402 }
1403
1404 xmlFile.EndTag(wxT("program"));
1405
1406 xmlFile.EndTag(wxT("effect"));
1407
1408 xmlFile.EndTag(wxT("vstprogrampersistence"));
1409
1410 xmlFile.Commit();
1411}
Wrapper to output XML data to files.
Definition: XMLWriter.h:84
STRINGS_API wxString Encode(const void *in, int len)
Definition: Base64.cpp:27

References callGetParameter(), constCallDispatcher(), effFlagsProgramChunks, effGetChunk, effGetParamName, Base64::Encode(), AEffect::flags, fn, GetString(), GetSymbol(), Internal, mAEffect, AEffect::numParams, AEffect::uniqueID, AEffect::version, wxT(), and XO().

Referenced by VSTEffect::ExportPresets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetBufferDelay()

void VSTWrapper::SetBufferDelay ( int  samples)
virtual

Reimplemented in VSTInstance.

Definition at line 647 of file VSTWrapper.cpp.

648{
649}

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ SetString()

void VSTWrapper::SetString ( int  opcode,
const wxString &  str,
int  index = 0 
)

Definition at line 674 of file VSTWrapper.cpp.

675{
676 char buf[256];
677 strcpy(buf, str.Left(255).ToUTF8());
678
679 callDispatcher(opcode, index, 0, buf, 0.0);
680}

References callDispatcher(), and str.

Referenced by HandleXMLTag(), and LoadFXProgram().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StoreSettings()

bool VSTWrapper::StoreSettings ( const VSTSettings vst3settings) const

Definition at line 1764 of file VSTWrapper.cpp.

1765{
1766 // First, make sure settings are compatibile with the plugin
1767 if ((vstSettings.mUniqueID != mAEffect->uniqueID) ||
1768// (vstSettings.mVersion != mAEffect->version) ||
1769 (vstSettings.mNumParams != mAEffect->numParams) )
1770 {
1771 return false;
1772 }
1773
1774
1775 // Try using the chunk first (if available)
1776 auto &chunk = vstSettings.mChunk;
1777 if (!chunk.empty())
1778 {
1780 callSetChunk(true, chunk.size(), const_cast<char *>(chunk.data()), &info);
1781 }
1782
1783
1784 // Settings (like the message) may store both a chunk, and also accumulated
1785 // slider movements to reapply after the chunk change. Or it might be
1786 // no chunk and id-value pairs only
1787
1788 constCallDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
1789
1791 (
1792 [&](const ParameterInfo& pi)
1793 {
1794 const auto itr = vstSettings.mParamsMap.find(pi.mName);
1795 if (itr != vstSettings.mParamsMap.end())
1796 {
1797 const float& value = *(itr->second);
1798
1799 if (value >= -1.0 && value <= 1.0)
1800 {
1801 callSetParameter(pi.mID, value);
1802 }
1803 }
1804 return true;
1805 }
1806 );
1807
1808 constCallDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
1809
1810 return true;
1811}

References callSetChunk(), constCallDispatcher(), effBeginSetProgram, ForEachParameter(), mAEffect, VSTSettings::mChunk, VSTSettings::mNumParams, VSTSettings::mParamsMap, VSTSettings::mUniqueID, AEffect::numParams, MIR::anonymous_namespace{MirUtils.cpp}::pi, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEffect::ExportPresets(), VSTInstance::ProcessInitialize(), VSTEffectBase::SaveUserPreset(), and VSTEditor::StoreSettingsToInstance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Unload()

void VSTWrapper::Unload ( )

Definition at line 571 of file VSTWrapper.cpp.

572{
573 if (mAEffect)
574 {
575 // Finally, close the plugin
576 callDispatcher(effClose, 0, 0, NULL, 0.0);
577 mAEffect = NULL;
578 }
579
580 //ResetModuleAndHandle();
581}
const int effClose
Definition: aeffectx.h:92

References callDispatcher(), effClose, and mAEffect.

Referenced by Load(), and ~VSTWrapper().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mAEffect

AEffect* VSTWrapper::mAEffect = nullptr

◆ mAudioIns

unsigned VSTWrapper::mAudioIns { 0 }

◆ mAudioOuts

unsigned VSTWrapper::mAudioOuts { 0 }

◆ mAutomatable

bool VSTWrapper::mAutomatable

Definition at line 224 of file VSTWrapper.h.

Referenced by Load(), and VSTEffectBase::SupportsAutomation().

◆ mBufferDelay

int VSTWrapper::mBufferDelay { 0 }

Definition at line 266 of file VSTWrapper.h.

Referenced by VSTInstance::SetBufferDelay().

◆ mBundleRef

BundleHandle VSTWrapper::mBundleRef

Definition at line 235 of file VSTWrapper.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mChunk

wxString VSTWrapper::mChunk

◆ mCurrentEffectID

intptr_t VSTWrapper::mCurrentEffectID {}

Definition at line 200 of file VSTWrapper.h.

Referenced by AudioMaster(), and Load().

◆ mDescription

wxString VSTWrapper::mDescription

Definition at line 217 of file VSTWrapper.h.

◆ mDispatcherLock

std::recursive_mutex VSTWrapper::mDispatcherLock

Definition at line 133 of file VSTWrapper.h.

Referenced by callDispatcher().

◆ mGui

bool VSTWrapper::mGui { false }

Definition at line 295 of file VSTWrapper.h.

Referenced by VSTInstance::HasGUI(), Load(), and VSTEffect::PopulateUI().

◆ mInChunk

bool VSTWrapper::mInChunk

Definition at line 170 of file VSTWrapper.h.

Referenced by HandleXMLContent(), HandleXMLEndTag(), HandleXMLTag(), and LoadXML().

◆ mInSet

bool VSTWrapper::mInSet

Definition at line 169 of file VSTWrapper.h.

Referenced by HandleXMLEndTag(), HandleXMLTag(), and LoadXML().

◆ mInteractive

bool VSTWrapper::mInteractive { false }

Definition at line 219 of file VSTWrapper.h.

Referenced by VSTEffectBase::IsInteractive(), and Load().

◆ mMainThreadId

std::thread::id VSTWrapper::mMainThreadId

◆ mMidiIns

int VSTWrapper::mMidiIns { 0 }

Definition at line 222 of file VSTWrapper.h.

◆ mMidiOuts

int VSTWrapper::mMidiOuts { 0 }

Definition at line 223 of file VSTWrapper.h.

◆ mModule

ModuleHandle VSTWrapper::mModule {}

Definition at line 214 of file VSTWrapper.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mName

wxString VSTWrapper::mName

Definition at line 166 of file VSTWrapper.h.

Referenced by GetSymbol(), and Load().

◆ mPath

PluginPath VSTWrapper::mPath

◆ mProcessLevel

int VSTWrapper::mProcessLevel { 1 }

Definition at line 269 of file VSTWrapper.h.

Referenced by GetProcessLevel().

◆ mResource

ResourceHandle VSTWrapper::mResource

Definition at line 258 of file VSTWrapper.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mTimeInfo

VstTimeInfo VSTWrapper::mTimeInfo

◆ mVendor

wxString VSTWrapper::mVendor

Definition at line 216 of file VSTWrapper.h.

Referenced by VSTEffectBase::GetVendor(), Load(), and VSTInstance::VSTInstance().

◆ mVersion

int VSTWrapper::mVersion

Definition at line 218 of file VSTWrapper.h.

Referenced by VSTEffectBase::GetVersion(), Load(), and VSTEffectBase::LoadSettings().

◆ mVstVersion

int VSTWrapper::mVstVersion

◆ mXMLInfo

VstPatchChunkInfo VSTWrapper::mXMLInfo

Definition at line 173 of file VSTWrapper.h.

Referenced by HandleXMLEndTag(), and HandleXMLTag().

◆ mXMLVersion

long VSTWrapper::mXMLVersion

Definition at line 172 of file VSTWrapper.h.

Referenced by HandleXMLTag().


The documentation for this struct was generated from the following files: