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

#include <VSTEffect.h>

Inheritance diagram for VSTEffectWrapper:
[legend]
Collaboration diagram for VSTEffectWrapper:
[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

 VSTEffectWrapper (const PluginPath &path)
 
 ~VSTEffectWrapper ()
 
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 (VSTEffectSettings &vst3Settings, bool doFetch=true) const
 
bool StoreSettings (const VSTEffectSettings &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 UpdateDisplay ()
 
virtual void SetBufferDelay (int samples)
 
std::unique_ptr< EffectInstance::MessageMakeMessageFS (const VSTEffectSettings &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 VSTEffectUIWrapper
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 VSTEffectSettingsGetSettings (EffectSettings &settings)
 
static const VSTEffectSettingsGetSettings (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 112 of file VSTEffect.h.

Member Typedef Documentation

◆ BundleHandle

Definition at line 245 of file VSTEffect.h.

◆ ModuleHandle

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

Definition at line 218 of file VSTEffect.h.

◆ ParameterVisitor

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

Definition at line 163 of file VSTEffect.h.

Constructor & Destructor Documentation

◆ VSTEffectWrapper()

VSTEffectWrapper::VSTEffectWrapper ( const PluginPath path)
inlineexplicit

Definition at line 128 of file VSTEffect.h.

129 : mPath(path)
130 , mMainThreadId{ std::this_thread::get_id() }
131 {}
std::thread::id mMainThreadId
Definition: VSTEffect.h:136
PluginPath mPath
Definition: VSTEffect.h:214

◆ ~VSTEffectWrapper()

VSTEffectWrapper::~VSTEffectWrapper ( )

Definition at line 2058 of file VSTEffect.cpp.

2059{
2060 Unload();
2062}
void ResetModuleAndHandle()
Definition: VSTEffect.cpp:2043

References ResetModuleAndHandle(), and Unload().

Here is the call graph for this function:

Member Function Documentation

◆ AudioMaster()

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

Definition at line 604 of file VSTEffect.cpp.

610{
611 VSTEffectWrapper* vst = (effect ? static_cast<VSTEffectWrapper*>(effect->ptr2) : nullptr);
612
613 // Handles operations during initialization...before VSTEffect has had a
614 // chance to set its instance pointer.
615 switch (opcode)
616 {
618 return (intptr_t) 2400;
619
621 return vst->mCurrentEffectID;
622
624 strcpy((char *) ptr, "Audacity Team"); // Do not translate, max 64 + 1 for null terminator
625 return 1;
626
628 strcpy((char *) ptr, "Audacity"); // Do not translate, max 64 + 1 for null terminator
629 return 1;
630
632 return (intptr_t) (AUDACITY_VERSION << 24 |
633 AUDACITY_RELEASE << 16 |
634 AUDACITY_REVISION << 8 |
635 AUDACITY_MODLEVEL);
636
637 // Some (older) effects depend on an effIdle call when requested. An
638 // example is the Antress Modern plugins which uses the call to update
639 // the editors display when the program (preset) changes.
641 if (vst)
642 {
643 vst->NeedIdle();
644 return 1;
645 }
646 return 0;
647
648 // We would normally get this if the effect editor is dipslayed and something "major"
649 // has changed (like a program change) instead of multiple automation calls.
650 // Since we don't do anything with the parameters while the editor is displayed,
651 // there's no need for us to do anything.
653 if (vst)
654 {
655 vst->UpdateDisplay();
656 return 1;
657 }
658 return 0;
659
660 // Return the current time info.
662 if (vst)
663 {
664 return (intptr_t) vst->GetTimeInfo();
665 }
666 return 0;
667
668 // Inputs, outputs, or initial delay has changed...all we care about is initial delay.
670 if (vst)
671 {
672 vst->SetBufferDelay(effect->initialDelay);
673 return 1;
674 }
675 return 0;
676
678 if (vst)
679 {
680 return (intptr_t) vst->GetSampleRate();
681 }
682 return 0;
683
684 case audioMasterIdle:
685 wxYieldIfNeeded();
686 return 1;
687
689 if (vst)
690 {
691 return vst->GetProcessLevel();
692 }
693 return 0;
694
696 return kVstLangEnglish;
697
698 // We always replace, never accumulate
700 return 1;
701
702 // Resize the window to accommodate the effect size
704 if (vst)
705 {
706 vst->SizeWindow(index, value);
707 }
708 return 1;
709
710 case audioMasterCanDo:
711 {
712 char *s = (char *) ptr;
713 if (strcmp(s, "acceptIOChanges") == 0 ||
714 strcmp(s, "sendVstTimeInfo") == 0 ||
715 strcmp(s, "startStopProcess") == 0 ||
716 strcmp(s, "shellCategory") == 0 ||
717 strcmp(s, "sizeWindow") == 0)
718 {
719 return 1;
720 }
721
722#if defined(VST_DEBUG)
723#if defined(__WXMSW__)
724 wxLogDebug(wxT("VST canDo: %s"), wxString::FromAscii((char *)ptr));
725#else
726 wxPrintf(wxT("VST canDo: %s\n"), wxString::FromAscii((char *)ptr));
727#endif
728#endif
729
730 return 0;
731 }
732
735 return 0;
736
738 if (vst)
739 {
740 vst->Automate(index, opt);
741 }
742 return 0;
743
744 // We're always connected (sort of)
746
747 // We don't do MIDI yet
750
751 // Don't need to see any messages about these
752 return 0;
753 }
754
755#if defined(VST_DEBUG)
756#if defined(__WXMSW__)
757 wxLogDebug(wxT("vst: %p opcode: %d index: %d value: %p ptr: %p opt: %f user: %p"),
758 effect, (int) opcode, (int) index, (void *) value, ptr, opt, vst);
759#else
760 wxPrintf(wxT("vst: %p opcode: %d index: %d value: %p ptr: %p opt: %f user: %p\n"),
761 effect, (int) opcode, (int) index, (void *) value, ptr, opt, vst);
762#endif
763#endif
764
765 return 0;
766}
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 Automate(int index, float value)
Definition: VSTEffect.cpp:3980
virtual void SizeWindow(int w, int h)
Definition: VSTEffect.cpp:2312
virtual void NeedIdle()
Definition: VSTEffect.cpp:2234
intptr_t mCurrentEffectID
Definition: VSTEffect.h:211
VstTimeInfo * GetTimeInfo()
Definition: VSTEffect.cpp:2260
float GetSampleRate()
Definition: VSTEffect.cpp:2266
virtual void UpdateDisplay()
Definition: VSTEffect.cpp:3975
virtual void SetBufferDelay(int samples)
Definition: VSTEffect.cpp:2409

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

Referenced by Load().

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

◆ callDispatcher()

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

Implements VSTEffectLink.

Definition at line 2456 of file VSTEffect.cpp.

2458{
2459 // Needed since we might be in the dispatcher when the timer pops
2460 std::lock_guard guard(mDispatcherLock);
2461
2462 return mAEffect->dispatcher(mAEffect, opcode, index, value, ptr, opt);
2463}
intptr_t(* dispatcher)(AEffect *, int, int, intptr_t, void *, float)
Definition: aeffectx.h:264
std::recursive_mutex mDispatcherLock
Definition: VSTEffect.h:144
AEffect * mAEffect
Definition: VSTEffect.h:135

References AEffect::dispatcher, mAEffect, and mDispatcherLock.

Referenced by callSetProgram(), constCallDispatcher(), VSTEffectInstance::DoProcessInitialize(), VSTEffect::GetEffectIDs(), HandleXMLEndTag(), HandleXMLTag(), Load(), LoadFXB(), LoadFXProgram(), LoadXML(), VSTEffectEditor::OnTimer(), VSTEffectInstance::PowerOff(), VSTEffectInstance::PowerOn(), SetString(), and Unload().

Here is the caller graph for this function:

◆ callGetParameter()

float VSTEffectWrapper::callGetParameter ( int  index) const

Definition at line 2481 of file VSTEffect.cpp.

2482{
2483 return mAEffect->getParameter(mAEffect, index);
2484}
float(* getParameter)(AEffect *, int)
Definition: aeffectx.h:270

References AEffect::getParameter, and mAEffect.

Referenced by FetchSettings(), and SaveFXProgram().

Here is the caller graph for this function:

◆ callSetChunk() [1/2]

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

Definition at line 2507 of file VSTEffect.cpp.

2508{
2509 VstPatchChunkInfo info;
2510
2511 memset(&info, 0, sizeof(info));
2512 info.version = 1;
2516
2517 callSetChunk(isPgm, len, buf, &info);
2518}
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: VSTEffect.cpp:2507
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 VSTEffectInstance::ApplyChunk(), callSetChunk(), HandleXMLEndTag(), LoadFXB(), LoadFXProgram(), VSTEffect::LoadUserPreset(), and StoreSettings().

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

◆ callSetChunk() [2/2]

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

Definition at line 2520 of file VSTEffect.cpp.

2521{
2522 if (isPgm)
2523 {
2524 // Ask the effect if this is an acceptable program
2525 if (constCallDispatcher(effBeginLoadProgram, 0, 0, info, 0.0) == -1)
2526 {
2527 return;
2528 }
2529 }
2530 else
2531 {
2532 // Ask the effect if this is an acceptable bank
2533 if (constCallDispatcher(effBeginLoadBank, 0, 0, info, 0.0) == -1)
2534 {
2535 return;
2536 }
2537 }
2538
2539 constCallDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
2540 constCallDispatcher(effSetChunk, isPgm ? 1 : 0, len, buf, 0.0);
2541 constCallDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
2542}
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: VSTEffect.cpp:2465

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

Here is the call graph for this function:

◆ callSetParameter()

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

Definition at line 2488 of file VSTEffect.cpp.

2489{
2490 if (mVstVersion == 0 || constCallDispatcher(effCanBeAutomated, 0, index, NULL, 0.0))
2491 {
2492 mAEffect->setParameter(mAEffect, index, value);
2493 }
2494}
const int effCanBeAutomated
Definition: aeffectx.h:115
void(* setParameter)(AEffect *, int, float)
Definition: aeffectx.h:268

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

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

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

◆ callSetProgram()

void VSTEffectWrapper::callSetProgram ( int  index)

Definition at line 2497 of file VSTEffect.cpp.

2498{
2499 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
2500
2501 callDispatcher(effSetProgram, 0, index, NULL, 0.0);
2502
2503 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
2504}
const int effSetProgram
Definition: aeffectx.h:93
intptr_t callDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt) override
Definition: VSTEffect.cpp:2456

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

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

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

◆ constCallDispatcher()

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

Definition at line 2465 of file VSTEffect.cpp.

2467{
2468 // Assume we are passed a read-only dispatcher function code
2469 return const_cast<VSTEffectWrapper*>(this)
2470 ->callDispatcher(opcode, index, value, ptr, opt);
2471}

References callDispatcher().

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

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

◆ FetchSettings()

bool VSTEffectWrapper::FetchSettings ( VSTEffectSettings vst3Settings,
bool  doFetch = true 
) const

Definition at line 3783 of file VSTEffect.cpp.

3784{
3785 // Get the fallback ID-value parameters
3787 (
3788 [&](const ParameterInfo& pi)
3789 {
3790 if (doFetch)
3791 {
3792 float val = callGetParameter(pi.mID);
3793 vstSettings.mParamsMap[pi.mName] = val;
3794 }
3795 else
3796 {
3797 vstSettings.mParamsMap[pi.mName] = std::nullopt;
3798 }
3799 return true;
3800 }
3801 );
3802
3803 // These are here to be checked against for compatibility later
3804 vstSettings.mVersion = mAEffect->version;
3805 vstSettings.mUniqueID = mAEffect->uniqueID;
3806 vstSettings.mNumParams = mAEffect->numParams;
3807
3808 // Get the chunk (if supported)
3809 vstSettings.mChunk.resize(0);
3810
3812 {
3813 void* chunk = nullptr;
3814 int clen = (int)constCallDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
3815 if (clen > 0 && chunk) {
3816 vstSettings.mChunk.resize(clen);
3817 memcpy(vstSettings.mChunk.data(), chunk, clen);
3818 }
3819
3820 if (!doFetch)
3821 {
3822 // Don't keep the contents, but keep a sufficiently allocated string,
3823 // with some extra space in case chunk length might vary
3824 auto size = vstSettings.mChunk.size();
3825 vstSettings.mChunk.resize(0);
3826 vstSettings.mChunk.reserve(2 * size);
3827 }
3828 }
3829
3830 return true;
3831}
const int effGetChunk
Definition: aeffectx.h:111
const int effFlagsProgramChunks
Definition: aeffectx.h:88
int flags
Definition: aeffectx.h:280
float callGetParameter(int index) const
Definition: VSTEffect.cpp:2481
void ForEachParameter(ParameterVisitor visitor) const
Definition: VSTEffect.cpp:3756

References callGetParameter(), constCallDispatcher(), effFlagsProgramChunks, effGetChunk, AEffect::flags, ForEachParameter(), mAEffect, VSTEffectSettings::mChunk, VSTEffectWrapper::ParameterInfo::mID, VSTEffectWrapper::ParameterInfo::mName, VSTEffectSettings::mNumParams, VSTEffectSettings::mParamsMap, VSTEffectSettings::mUniqueID, VSTEffectSettings::mVersion, AEffect::numParams, size, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEffectEditor::FetchSettingsFromInstance(), VSTEffect::ImportPresetsNC(), VSTEffect::LoadFactoryPreset(), VSTEffect::LoadUserPreset(), VSTEffectInstance::MakeMessage(), and VSTEffect::MakeSettings().

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

◆ ForEachParameter()

void VSTEffectWrapper::ForEachParameter ( ParameterVisitor  visitor) const

Definition at line 3756 of file VSTEffect.cpp.

3757{
3758 for (int i = 0; i < mAEffect->numParams; i++)
3759 {
3760 wxString name = GetString(effGetParamName, i);
3761 if (name.empty())
3762 {
3763 name.Printf(wxT("parm_%d"), i);
3764 }
3765 else
3766 /* Easy fix for now for issue 3854, but this should be reconsidered
3767 There is the possibility that two parameter names might collide
3768 after normalizing. A question is whether the normalizing was ever
3769 really needed for saving in a wxConfigFile. Maybe not. But then
3770 redefinition of the keys stored in the file may introduce versioning
3771 difficulties if there is an attempt to fix this in future Audacity.
3772 */
3774
3775 ParameterInfo pi{ i, name };
3776
3777 if (!visitor(pi))
3778 break;
3779 }
3780}
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: VSTEffect.cpp:2425

References effGetParamName, TranslatableString::empty(), GetString(), mAEffect, name, CommandParameters::NormalizeName(), AEffect::numParams, and wxT().

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

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

◆ GetChunkInfo()

VstPatchChunkInfo VSTEffectWrapper::GetChunkInfo ( ) const

Definition at line 2087 of file VSTEffect.cpp.

2088{
2090 return info;
2091}

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

Referenced by VSTEffect::LoadUserPreset().

Here is the caller graph for this function:

◆ GetProcessLevel()

int VSTEffectWrapper::GetProcessLevel ( )

Definition at line 2271 of file VSTEffect.cpp.

2272{
2273 return mProcessLevel;
2274}

References mProcessLevel.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ GetSampleRate()

float VSTEffectWrapper::GetSampleRate ( )

Definition at line 2266 of file VSTEffect.cpp.

2267{
2268 return mTimeInfo.sampleRate;
2269}
double sampleRate
Definition: aeffectx.h:311
VstTimeInfo mTimeInfo
Definition: VSTEffect.h:276

References mTimeInfo, and VstTimeInfo::sampleRate.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ GetSettings() [1/2]

static const VSTEffectSettings & VSTEffectWrapper::GetSettings ( const EffectSettings settings)
inlinestatic

Definition at line 121 of file VSTEffect.h.

122 {
123 auto pSettings = settings.cast<VSTEffectSettings>();
124 assert(pSettings);
125 return *pSettings;
126 }
static Settings & settings()
Definition: TrackInfo.cpp:87

References settings().

Here is the call graph for this function:

◆ GetSettings() [2/2]

static VSTEffectSettings & VSTEffectWrapper::GetSettings ( EffectSettings settings)
inlinestatic

Definition at line 114 of file VSTEffect.h.

115 {
116 auto pSettings = settings.cast<VSTEffectSettings>();
117 assert(pSettings);
118 return *pSettings;
119 }

References settings().

Referenced by VSTEffect::ExportPresets(), VSTEffect::ImportPresetsNC(), VSTEffect::LoadFactoryPreset(), VSTEffect::LoadSettings(), VSTEffect::LoadUserPreset(), VSTEffectEditor::NotifyParameterChanged(), VSTEffectInstance::ProcessInitialize(), VSTEffect::SaveSettings(), VSTEffect::SaveUserPreset(), and VSTEffectEditor::VSTEffectEditor().

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

◆ GetString() [1/2]

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

Definition at line 2439 of file VSTEffect.cpp.

2440{
2441 wxString str;
2442
2443 GetString(str, opcode, index);
2444
2445 return str;
2446}
#define str(a)

References GetString(), and str.

Here is the call graph for this function:

◆ GetString() [2/2]

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

Definition at line 2425 of file VSTEffect.cpp.

2426{
2427 char buf[256];
2428
2429 memset(buf, 0, sizeof(buf));
2430
2431 // Assume we are passed a read-only dispatcher function code
2432 constCallDispatcher(opcode, index, 0, buf, 0.0);
2433
2434 outstr = wxString::FromUTF8(buf);
2435
2436 return 0;
2437}

References constCallDispatcher().

Referenced by VSTEffectEditor::BuildPlain(), ForEachParameter(), VSTEffect::GetFactoryPresets(), GetString(), Load(), and VSTEffectEditor::RefreshParameters().

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

◆ GetSymbol()

ComponentInterfaceSymbol VSTEffectWrapper::GetSymbol ( ) const

Definition at line 3890 of file VSTEffect.cpp.

3891{
3892 return mName;
3893}
wxString mName
Definition: VSTEffect.h:177

References mName.

Referenced by VSTEffect::GetSymbol(), and HandleXMLTag().

Here is the caller graph for this function:

◆ GetTimeInfo()

VstTimeInfo * VSTEffectWrapper::GetTimeInfo ( )

Definition at line 2260 of file VSTEffect.cpp.

2261{
2262 mTimeInfo.nanoSeconds = wxGetUTCTimeMillis().ToDouble();
2263 return &mTimeInfo;
2264}
double nanoSeconds
Definition: aeffectx.h:313

References mTimeInfo, and VstTimeInfo::nanoSeconds.

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ HandleXMLChild()

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

Implements XMLTagHandler.

Definition at line 3725 of file VSTEffect.cpp.

3726{
3727 if (tag == "vstprogrampersistence")
3728 {
3729 return this;
3730 }
3731
3732 if (tag == "effect")
3733 {
3734 return this;
3735 }
3736
3737 if (tag == "program")
3738 {
3739 return this;
3740 }
3741
3742 if (tag == "param")
3743 {
3744 return this;
3745 }
3746
3747 if (tag == "chunk")
3748 {
3749 return this;
3750 }
3751
3752 return NULL;
3753}

◆ HandleXMLContent()

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

Definition at line 3717 of file VSTEffect.cpp.

3718{
3719 if (mInChunk)
3720 {
3721 mChunk += wxString(std::string(content)).Trim(true).Trim(false);
3722 }
3723}
wxString mChunk
Definition: VSTEffect.h:182

References mChunk, and mInChunk.

◆ HandleXMLEndTag()

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

Definition at line 3687 of file VSTEffect.cpp.

3688{
3689 if (tag == "chunk")
3690 {
3691 if (mChunk.length())
3692 {
3693 ArrayOf<char> buf{ mChunk.length() / 4 * 3 };
3694
3695 int len = Base64::Decode(mChunk, buf.get());
3696 if (len)
3697 {
3698 callSetChunk(true, len, buf.get(), &mXMLInfo);
3699 }
3700
3701 mChunk.clear();
3702 }
3703 mInChunk = false;
3704 }
3705
3706 if (tag == "program")
3707 {
3708 if (mInSet)
3709 {
3710 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
3711
3712 mInSet = false;
3713 }
3714 }
3715}
STRINGS_API int Decode(const wxString &in, void *out)
Definition: Base64.cpp:67
VstPatchChunkInfo mXMLInfo
Definition: VSTEffect.h:184

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

Here is the call graph for this function:

◆ HandleXMLTag()

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

Implements XMLTagHandler.

Definition at line 3479 of file VSTEffect.cpp.

3480{
3481 if (tag == "vstprogrampersistence")
3482 {
3483 for (auto pair : attrs)
3484 {
3485 auto attr = pair.first;
3486 auto value = pair.second;
3487
3488 if (attr == "version")
3489 {
3490 if (!value.TryGet(mXMLVersion))
3491 {
3492 return false;
3493 }
3494
3495 if (mXMLVersion < 1 || mXMLVersion > 2)
3496 {
3497 return false;
3498 }
3499 }
3500 else
3501 {
3502 return false;
3503 }
3504 }
3505
3506 return true;
3507 }
3508
3509 if (tag == "effect")
3510 {
3511 memset(&mXMLInfo, 0, sizeof(mXMLInfo));
3512 mXMLInfo.version = 1;
3516
3517 for (auto pair : attrs)
3518 {
3519 auto attr = pair.first;
3520 auto value = pair.second;
3521
3522 if (attr == "name")
3523 {
3524 wxString strValue = value.ToWString();
3525
3526 if (strValue != GetSymbol().Internal())
3527 {
3528 auto msg = XO("This parameter file was saved from %s. Continue?")
3529 .Format( strValue );
3530 int result = AudacityMessageBox(
3531 msg,
3532 XO("Confirm"),
3533 wxYES_NO,
3534 nullptr );
3535 if (result == wxNO)
3536 {
3537 return false;
3538 }
3539 }
3540 }
3541 else if (attr == "version")
3542 {
3543 long version;
3544 if (!value.TryGet(version))
3545 {
3546 return false;
3547 }
3548
3549 mXMLInfo.pluginVersion = (int) version;
3550 }
3551 else if (mXMLVersion > 1 && attr == "uniqueID")
3552 {
3553 long uniqueID;
3554 if (!value.TryGet(uniqueID))
3555 {
3556 return false;
3557 }
3558
3559 mXMLInfo.pluginUniqueID = (int) uniqueID;
3560 }
3561 else if (mXMLVersion > 1 && attr == "numParams")
3562 {
3563 long numParams;
3564 if (!value.TryGet(numParams))
3565 {
3566 return false;
3567 }
3568
3569 mXMLInfo.numElements = (int) numParams;
3570 }
3571 else
3572 {
3573 return false;
3574 }
3575 }
3576
3577 return true;
3578 }
3579
3580 if (tag == "program")
3581 {
3582 for (auto pair : attrs)
3583 {
3584 auto attr = pair.first;
3585 auto value = pair.second;
3586
3587 if (attr == "name")
3588 {
3589 const wxString strValue = value.ToWString();
3590
3591 if (strValue.length() > 24)
3592 {
3593 return false;
3594 }
3595
3596 int ndx = 0; //mProgram->GetCurrentSelection();
3597 if (ndx == wxNOT_FOUND)
3598 {
3599 ndx = 0;
3600 }
3601
3602 SetString(effSetProgramName, strValue, ndx);
3603 }
3604 else
3605 {
3606 return false;
3607 }
3608 }
3609
3610 mInChunk = false;
3611
3612 if (callDispatcher(effBeginLoadProgram, 0, 0, &mXMLInfo, 0.0) == -1)
3613 {
3614 return false;
3615 }
3616
3617 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
3618
3619 mInSet = true;
3620
3621 return true;
3622 }
3623
3624 if (tag == "param")
3625 {
3626 long ndx = -1;
3627 double val = -1.0;
3628
3629 for (auto pair : attrs)
3630 {
3631 auto attr = pair.first;
3632 auto value = pair.second;
3633
3634 if (attr == "index")
3635 {
3636 if (!value.TryGet(ndx))
3637 {
3638 return false;
3639 }
3640
3641 if (ndx < 0 || ndx >= mAEffect->numParams)
3642 {
3643 // Could be a different version of the effect...probably should
3644 // tell the user
3645 return false;
3646 }
3647 }
3648 // "name" attribute is ignored for params
3649 /* else if (attr == "name")
3650 {
3651
3652 // Nothing to do with it for now
3653 }*/
3654 else if (attr == "value")
3655 {
3656 if (!value.TryGet(val))
3657 {
3658 return false;
3659 }
3660
3661 if (val < 0.0 || val > 1.0)
3662 {
3663 return false;
3664 }
3665 }
3666 }
3667
3668 if (ndx == -1 || val == -1.0)
3669 {
3670 return false;
3671 }
3672
3673 callSetParameter(ndx, val);
3674
3675 return true;
3676 }
3677
3678 if (tag == "chunk")
3679 {
3680 mInChunk = true;
3681 return true;
3682 }
3683
3684 return false;
3685}
@ Internal
Indicates internal failure from Audacity.
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
XO("Cut/Copy/Paste")
const int effSetProgramName
Definition: aeffectx.h:96
ComponentInterfaceSymbol GetSymbol() const
Definition: VSTEffect.cpp:3890
void callSetParameter(int index, float value) const
Definition: VSTEffect.cpp:2488
void SetString(int opcode, const wxString &str, int index=0)
Definition: VSTEffect.cpp:2448

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

Here is the call graph for this function:

◆ IsCompatible()

bool VSTEffectWrapper::IsCompatible ( const VstPatchChunkInfo info) const

Definition at line 2093 of file VSTEffect.cpp.

2094{
2095 return (info.pluginUniqueID == mAEffect->uniqueID) &&
2096 (info.pluginVersion == mAEffect->version) &&
2097 (info.numElements == mAEffect->numParams);
2098}

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

Referenced by VSTEffect::LoadUserPreset().

Here is the caller graph for this function:

◆ Load()

bool VSTEffectWrapper::Load ( )

Definition at line 1765 of file VSTEffect.cpp.

1766{
1767 vstPluginMain pluginMain;
1768 bool success = false;
1769
1770 long effectID = 0;
1771 wxString realPath = mPath.BeforeFirst(wxT(';'));
1772 mPath.AfterFirst(wxT(';')).ToLong(&effectID);
1773 mCurrentEffectID = (intptr_t) effectID;
1774
1775 mModule = NULL;
1776 mAEffect = NULL;
1777
1778#if defined(__WXMAC__)
1779 // Start clean
1780 mBundleRef.reset();
1781
1782 mResource = ResourceHandle{};
1783
1784 // Convert the path to a CFSTring
1785 wxCFStringRef path(realPath);
1786
1787 // Create the bundle using the URL
1788 BundleHandle bundleRef{ CFBundleCreate(kCFAllocatorDefault,
1789 // Convert the path to a URL
1790 CF_ptr<CFURLRef>{
1791 CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
1792 path, kCFURLPOSIXPathStyle, true)
1793 }.get()
1794 )};
1795
1796 // Bail if the bundle wasn't created
1797 if (!bundleRef)
1798 return false;
1799
1800
1801 // Convert back to path
1802 UInt8 exePath[PLATFORM_MAX_PATH];
1803 Boolean good = CFURLGetFileSystemRepresentation(
1804 // Retrieve a reference to the executable
1805 CF_ptr<CFURLRef>{ CFBundleCopyExecutableURL(bundleRef.get()) }.get(),
1806 true, exePath, sizeof(exePath)
1807 );
1808
1809 // Bail if we couldn't resolve the executable path
1810 if (good == FALSE)
1811 return false;
1812
1813 // Attempt to open it
1814 mModule.reset((char*)dlopen((char *) exePath, RTLD_NOW | RTLD_LOCAL));
1815 if (!mModule)
1816 return false;
1817
1818 // Try to locate the NEW plugin entry point
1819 pluginMain = (vstPluginMain) dlsym(mModule.get(), "VSTPluginMain");
1820
1821 // If not found, try finding the old entry point
1822 if (pluginMain == NULL)
1823 {
1824 pluginMain = (vstPluginMain) dlsym(mModule.get(), "main_macho");
1825 }
1826
1827 // Must not be a VST plugin
1828 if (pluginMain == NULL)
1829 {
1830 mModule.reset();
1831 return false;
1832 }
1833
1834 // Need to keep the bundle reference around so we can map the
1835 // resources.
1836 mBundleRef = std::move(bundleRef);
1837
1838 // Open the resource map ... some plugins (like GRM Tools) need this.
1839 mResource = ResourceHandle{
1840 mBundleRef.get(), CFBundleOpenBundleResourceMap(mBundleRef.get())
1841 };
1842
1843#elif defined(__WXMSW__)
1844
1845 {
1846 wxLogNull nolog;
1847
1848 // Try to load the library
1849 auto lib = std::make_unique<wxDynamicLibrary>(realPath);
1850 if (!lib)
1851 return false;
1852
1853 // Bail if it wasn't successful
1854 if (!lib->IsLoaded())
1855 return false;
1856
1857 // Try to find the entry point, while suppressing error messages
1858 pluginMain = (vstPluginMain) lib->GetSymbol(wxT("VSTPluginMain"));
1859 if (pluginMain == NULL)
1860 {
1861 pluginMain = (vstPluginMain) lib->GetSymbol(wxT("main"));
1862 if (pluginMain == NULL)
1863 return false;
1864 }
1865
1866 // Save the library reference
1867 mModule = std::move(lib);
1868 }
1869
1870#else
1871
1872 // Attempt to load it
1873 //
1874 // Spent a few days trying to figure out why some VSTs where running okay and
1875 // others were hit or miss. The cause was that we export all of Audacity's
1876 // symbols and some of the loaded libraries were picking up Audacity's and
1877 // not their own.
1878 //
1879 // So far, I've only seen this issue on Linux, but we might just be getting
1880 // lucky on the Mac and Windows. The sooner we stop exporting everything
1881 // the better.
1882 //
1883 // To get around the problem, I just added the RTLD_DEEPBIND flag to the load
1884 // and that "basically" puts Audacity last when the loader needs to resolve
1885 // symbols.
1886 //
1887 // Once we define a proper external API, the flags can be removed.
1888#ifndef RTLD_DEEPBIND
1889#define RTLD_DEEPBIND 0
1890#endif
1891 ModuleHandle lib {
1892 (char*) dlopen((const char *)wxString(realPath).ToUTF8(),
1893 RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND)
1894 };
1895 if (!lib)
1896 {
1897 return false;
1898 }
1899
1900 // Try to find the entry point, while suppressing error messages
1901 pluginMain = (vstPluginMain) dlsym(lib.get(), "VSTPluginMain");
1902 if (pluginMain == NULL)
1903 {
1904 pluginMain = (vstPluginMain) dlsym(lib.get(), "main");
1905 if (pluginMain == NULL)
1906 return false;
1907 }
1908
1909 // Save the library reference
1910 mModule = std::move(lib);
1911
1912#endif
1913
1914 // Initialize the plugin
1915 try
1916 {
1918 }
1919 catch (...)
1920 {
1921 wxLogMessage(wxT("VST plugin initialization failed\n"));
1922 mAEffect = NULL;
1923 }
1924
1925 // Was it successful?
1926 if (mAEffect)
1927 {
1929
1930 // Must use the GUI editor if parameters aren't provided
1931 if (mAEffect->numParams == 0)
1932 {
1933 mGui = true;
1934 }
1935
1936 // Save a reference to ourselves
1937 //
1938 // Note: Some hosts use "user" and some use "ptr2/resvd2". It might
1939 // be worthwhile to check if user is NULL before using it and
1940 // then falling back to "ptr2/resvd2".
1941 mAEffect->ptr2 = static_cast<VSTEffectWrapper*>(this);
1942
1943 // Give the plugin an initial sample rate and blocksize
1944 callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0);
1945 callDispatcher(effSetBlockSize, 0, 512, NULL, 0);
1946
1947 // Ask the plugin to identify itself...might be needed for older plugins
1948 callDispatcher(effIdentify, 0, 0, NULL, 0);
1949
1950 // Open the plugin
1951 callDispatcher(effOpen, 0, 0, NULL, 0.0);
1952
1953 // Get the VST version the plugin understands
1955
1956 // Set it again in case plugin ignored it before the effOpen
1957 callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0);
1958 callDispatcher(effSetBlockSize, 0, 512, NULL, 0);
1959
1960 // Ensure that it looks like a plugin and can deal with ProcessReplacing
1961 // calls. Also exclude synths for now.
1962 if (mAEffect->magic == kEffectMagic &&
1965 {
1966 if (mVstVersion >= 2)
1967 {
1969 if (mName.length() == 0)
1970 {
1972 }
1973 }
1974 if (mName.length() == 0)
1975 {
1976 mName = wxFileName{realPath}.GetName();
1977 }
1978
1979 if (mVstVersion >= 2)
1980 {
1982 mVersion = wxINT32_SWAP_ON_LE(callDispatcher(effGetVendorVersion, 0, 0, NULL, 0));
1983 }
1984 if (mVersion == 0)
1985 {
1986 mVersion = wxINT32_SWAP_ON_LE(mAEffect->version);
1987 }
1988
1990 {
1991 mInteractive = true;
1992 }
1993
1996
1997 // Check to see if parameters can be automated. This isn't a guarantee
1998 // since it could be that the effect simply doesn't support the opcode.
1999 mAutomatable = false;
2000 for (int i = 0; i < mAEffect->numParams; i++)
2001 {
2002 if (callDispatcher(effCanBeAutomated, 0, i, NULL, 0.0))
2003 {
2004 mAutomatable = true;
2005 break;
2006 }
2007 }
2008
2009 // Make sure we start out with a valid program selection
2010 // I've found one plugin (SoundHack +morphfilter) that will
2011 // crash Audacity when saving the initial default parameters
2012 // with this.
2013 callSetProgram(0);
2014
2015 // Pretty confident that we're good to go
2016 success = true;
2017 }
2018 }
2019
2020 if (!success)
2021 {
2022 Unload();
2024 }
2025
2026 return success;
2027}
#define PLATFORM_MAX_PATH
Definition: FileNames.h:42
AEffect *(* vstPluginMain)(audioMasterCallback audioMaster)
Definition: VSTEffect.cpp:602
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
unsigned mAudioOuts
Definition: VSTEffect.h:233
BundleHandle mBundleRef
Definition: VSTEffect.h:247
void callSetProgram(int index)
Definition: VSTEffect.cpp:2497
wxString mVendor
Definition: VSTEffect.h:228
static intptr_t AudioMaster(AEffect *effect, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
Definition: VSTEffect.cpp:604
std::unique_ptr< wxDynamicLibrary > ModuleHandle
Definition: VSTEffect.h:218
ResourceHandle mResource
Definition: VSTEffect.h:270
unsigned mAudioIns
Definition: VSTEffect.h:232
ModuleHandle mModule
Definition: VSTEffect.h:226
CF_ptr< CFBundleRef > BundleHandle
Definition: VSTEffect.h:245

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(), VSTEffect::InitializePlugin(), and VSTEffectInstance::VSTEffectInstance().

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

◆ LoadFXB()

bool VSTEffectWrapper::LoadFXB ( const wxFileName &  fn)

Definition at line 2824 of file VSTEffect.cpp.

2825{
2826 bool ret = false;
2827
2828 // Try to open the file...will be closed automatically when method returns
2829 wxFFile f(fn.GetFullPath(), wxT("rb"));
2830 if (!f.IsOpened())
2831 {
2832 return false;
2833 }
2834
2835 // Allocate memory for the contents
2836 ArrayOf<unsigned char> data{ size_t(f.Length()) };
2837 if (!data)
2838 {
2840 XO("Unable to allocate memory when loading presets file."),
2841 XO("Error Loading VST Presets"),
2842 wxOK | wxCENTRE,
2843 nullptr);
2844 return false;
2845 }
2846 unsigned char *bptr = data.get();
2847
2848 do
2849 {
2850 // Read in the whole file
2851 ssize_t len = f.Read((void *) bptr, f.Length());
2852 if (f.Error())
2853 {
2855 XO("Unable to read presets file."),
2856 XO("Error Loading VST Presets"),
2857 wxOK | wxCENTRE,
2858 nullptr);
2859 break;
2860 }
2861
2862 // Most references to the data are via an "int" array
2863 int32_t *iptr = (int32_t *) bptr;
2864
2865 // Verify that we have at least enough for the header
2866 if (len < 156)
2867 {
2868 break;
2869 }
2870
2871 // Verify that we probably have an FX file
2872 if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K'))
2873 {
2874 break;
2875 }
2876
2877 // Ignore the size...sometimes it's there, other times it's zero
2878
2879 // Get the version and verify
2880 int version = wxINT32_SWAP_ON_LE(iptr[3]);
2881 if (version != 1 && version != 2)
2882 {
2883 break;
2884 }
2885
2886 VstPatchChunkInfo info =
2887 {
2888 1,
2889 wxINT32_SWAP_ON_LE(iptr[4]),
2890 wxINT32_SWAP_ON_LE(iptr[5]),
2891 wxINT32_SWAP_ON_LE(iptr[6]),
2892 ""
2893 };
2894
2895 // Ensure this program looks to belong to the current plugin
2896 if ((info.pluginUniqueID != mAEffect->uniqueID) &&
2897 (info.pluginVersion != mAEffect->version) &&
2898 (info.numElements != mAEffect->numPrograms))
2899 {
2900 break;
2901 }
2902
2903 // Get the number of programs
2904 int numProgs = info.numElements;
2905
2906 // Get the current program index
2907 int curProg = 0;
2908 if (version >= 2)
2909 {
2910 curProg = wxINT32_SWAP_ON_LE(iptr[7]);
2911 if (curProg < 0 || curProg >= numProgs)
2912 {
2913 break;
2914 }
2915 }
2916
2917 // Is it a bank of programs?
2918 if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'B', 'k'))
2919 {
2920 // Drop the header
2921 bptr += 156;
2922 len -= 156;
2923
2924 unsigned char *tempPtr = bptr;
2925 ssize_t tempLen = len;
2926
2927 // Validate all of the programs
2928 for (int i = 0; i < numProgs; i++)
2929 {
2930 if (!LoadFXProgram(&tempPtr, tempLen, i, true))
2931 {
2932 break;
2933 }
2934 }
2935
2936 // Ask the effect if this is an acceptable bank
2937 if (callDispatcher(effBeginLoadBank, 0, 0, &info, 0.0) == -1)
2938 {
2939 return false;
2940 }
2941
2942 // Start loading the individual programs
2943 for (int i = 0; i < numProgs; i++)
2944 {
2945 ret = LoadFXProgram(&bptr, len, i, false);
2946 }
2947 }
2948 // Or maybe a bank chunk?
2949 else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'B', 'C', 'h'))
2950 {
2951 // Can't load programs chunks if the plugin doesn't support it
2953 {
2954 break;
2955 }
2956
2957 // Verify that we have enough to grab the chunk size
2958 if (len < 160)
2959 {
2960 break;
2961 }
2962
2963 // Get the chunk size
2964 int size = wxINT32_SWAP_ON_LE(iptr[39]);
2965
2966 // We finally know the full length of the program
2967 int proglen = 160 + size;
2968
2969 // Verify that we have enough for the entire program
2970 if (len < proglen)
2971 {
2972 break;
2973 }
2974
2975 // Set the entire bank in one shot
2976 callSetChunk(false, size, &iptr[40], &info);
2977
2978 // Success
2979 ret = true;
2980 }
2981 // Unrecognizable type
2982 else
2983 {
2984 break;
2985 }
2986
2987 // Set the active program
2988 if (ret && version >= 2)
2989 {
2990 callSetProgram(curProg);
2991 }
2992 } while (false);
2993
2994 return ret;
2995}
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: VSTEffect.cpp:3049

References AudacityMessageBox(), callDispatcher(), callSetChunk(), callSetProgram(), CCONST, effBeginLoadBank, effFlagsProgramChunks, AEffect::flags, fn, LoadFXProgram(), mAEffect, VstPatchChunkInfo::numElements, AEffect::numPrograms, VstPatchChunkInfo::pluginUniqueID, VstPatchChunkInfo::pluginVersion, 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 VSTEffectWrapper::LoadFXP ( const wxFileName &  fn)

Definition at line 2997 of file VSTEffect.cpp.

2998{
2999 bool ret = false;
3000
3001 // Try to open the file...will be closed automatically when method returns
3002 wxFFile f(fn.GetFullPath(), wxT("rb"));
3003 if (!f.IsOpened())
3004 {
3005 return false;
3006 }
3007
3008 // Allocate memory for the contents
3009 ArrayOf<unsigned char> data{ size_t(f.Length()) };
3010 if (!data)
3011 {
3013 XO("Unable to allocate memory when loading presets file."),
3014 XO("Error Loading VST Presets"),
3015 wxOK | wxCENTRE,
3016 nullptr);
3017 return false;
3018 }
3019 unsigned char *bptr = data.get();
3020
3021 do
3022 {
3023 // Read in the whole file
3024 ssize_t len = f.Read((void *) bptr, f.Length());
3025 if (f.Error())
3026 {
3028 XO("Unable to read presets file."),
3029 XO("Error Loading VST Presets"),
3030 wxOK | wxCENTRE,
3031 nullptr);
3032 break;
3033 }
3034
3035 // Get (or default) currently selected program
3036 int i = 0; //mProgram->GetCurrentSelection();
3037 if (i < 0)
3038 {
3039 i = 0; // default to first program
3040 }
3041
3042 // Go verify and set the program
3043 ret = LoadFXProgram(&bptr, len, i, false);
3044 } while (false);
3045
3046 return ret;
3047}

References AudacityMessageBox(), fn, LoadFXProgram(), 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 VSTEffectWrapper::LoadFXProgram ( unsigned char **  bptr,
ssize_t &  len,
int  index,
bool  dryrun 
)

Definition at line 3049 of file VSTEffect.cpp.

3050{
3051 // Most references to the data are via an "int" array
3052 int32_t *iptr = (int32_t *) *bptr;
3053
3054 // Verify that we have at least enough for a program without parameters
3055 if (len < 28)
3056 {
3057 return false;
3058 }
3059
3060 // Verify that we probably have an FX file
3061 if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K'))
3062 {
3063 return false;
3064 }
3065
3066 // Ignore the size...sometimes it's there, other times it's zero
3067
3068 // Get the version and verify
3069#if defined(IS_THIS_AN_FXP_ARTIFICAL_LIMITATION)
3070 int version = wxINT32_SWAP_ON_LE(iptr[3]);
3071 if (version != 1)
3072 {
3073 return false;
3074 }
3075#endif
3076
3077 VstPatchChunkInfo info =
3078 {
3079 1,
3080 wxINT32_SWAP_ON_LE(iptr[4]),
3081 wxINT32_SWAP_ON_LE(iptr[5]),
3082 wxINT32_SWAP_ON_LE(iptr[6]),
3083 ""
3084 };
3085
3086 // Ensure this program looks to belong to the current plugin
3087 if ((info.pluginUniqueID != mAEffect->uniqueID) &&
3088 (info.pluginVersion != mAEffect->version) &&
3089 (info.numElements != mAEffect->numParams))
3090 {
3091 return false;
3092 }
3093
3094 // Get the number of parameters
3095 int numParams = info.numElements;
3096
3097 // At this point, we have to have enough to include the program name as well
3098 if (len < 56)
3099 {
3100 return false;
3101 }
3102
3103 // Get the program name
3104 wxString progName(wxString::From8BitData((char *)&iptr[7]));
3105
3106 // Might be a regular program
3107 if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'C', 'k'))
3108 {
3109 // We finally know the full length of the program
3110 int proglen = 56 + (numParams * sizeof(float));
3111
3112 // Verify that we have enough for all of the parameter values
3113 if (len < proglen)
3114 {
3115 return false;
3116 }
3117
3118 // Validate all of the parameter values
3119 for (int i = 0; i < numParams; i++)
3120 {
3121 uint32_t ival = wxUINT32_SWAP_ON_LE(iptr[14 + i]);
3122 float val = reinterpretAsFloat(ival);
3123 if (val < 0.0 || val > 1.0)
3124 {
3125 return false;
3126 }
3127 }
3128
3129 // They look okay...time to start changing things
3130 if (!dryrun)
3131 {
3132 // Ask the effect if this is an acceptable program
3133 if (callDispatcher(effBeginLoadProgram, 0, 0, &info, 0.0) == -1)
3134 {
3135 return false;
3136 }
3137
3138 // Load all of the parameters
3139 callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
3140 for (int i = 0; i < numParams; i++)
3141 {
3142 wxUint32 val = wxUINT32_SWAP_ON_LE(iptr[14 + i]);
3144 }
3145 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
3146 }
3147
3148 // Update in case we're loading an "FxBk" format bank file
3149 *bptr += proglen;
3150 len -= proglen;
3151 }
3152 // Maybe we have a program chunk
3153 else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'P', 'C', 'h'))
3154 {
3155 // Can't load programs chunks if the plugin doesn't support it
3157 {
3158 return false;
3159 }
3160
3161 // Verify that we have enough to grab the chunk size
3162 if (len < 60)
3163 {
3164 return false;
3165 }
3166
3167 // Get the chunk size
3168 int size = wxINT32_SWAP_ON_LE(iptr[14]);
3169
3170 // We finally know the full length of the program
3171 int proglen = 60 + size;
3172
3173 // Verify that we have enough for the entire program
3174 if (len < proglen)
3175 {
3176 return false;
3177 }
3178
3179 // Set the entire program in one shot
3180 if (!dryrun)
3181 {
3182 callSetChunk(true, size, &iptr[15], &info);
3183 }
3184
3185 // Update in case we're loading an "FxBk" format bank file
3186 *bptr += proglen;
3187 len -= proglen;
3188 }
3189 else
3190 {
3191 // Unknown type
3192 return false;
3193 }
3194
3195 if (!dryrun)
3196 {
3197 SetString(effSetProgramName, wxString(progName), index);
3198 }
3199
3200 return true;
3201}
static float reinterpretAsFloat(uint32_t x)
Definition: VSTEffect.cpp:110

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 VSTEffectWrapper::LoadXML ( const wxFileName &  fn)

Definition at line 3203 of file VSTEffect.cpp.

3204{
3205 mInChunk = false;
3206 mInSet = false;
3207
3208 // default to read as XML file
3209 // Load the program
3210 XMLFileReader reader;
3211 bool ok = reader.Parse(this, fn.GetFullPath());
3212
3213 // Something went wrong with the file, clean up
3214 if (mInSet)
3215 {
3216 callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
3217
3218 mInSet = false;
3219 }
3220
3221 if (!ok)
3222 {
3223 // Inform user of load failure
3225 reader.GetErrorStr(),
3226 XO("Error Loading VST Presets"),
3227 wxOK | wxCENTRE,
3228 nullptr);
3229 return false;
3230 }
3231
3232 return true;
3233}
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 AudacityMessageBox(), callDispatcher(), effEndSetProgram, fn, XMLFileReader::GetErrorStr(), mInChunk, mInSet, XMLFileReader::Parse(), 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 > VSTEffectWrapper::MakeMessageFS ( const VSTEffectSettings settings) const

Definition at line 3910 of file VSTEffect.cpp.

3911{
3912 VSTEffectMessage::ParamVector paramVector;
3913 paramVector.resize(mAEffect->numParams, std::nullopt);
3914
3916 (
3917 [&](const VSTEffectWrapper::ParameterInfo& pi)
3918 {
3919 auto &slot = paramVector[pi.mID]; // operator [] may make a nullopt
3920 const auto iter = settings.mParamsMap.find(pi.mName),
3921 end = settings.mParamsMap.end();
3922 if (iter != end)
3923 slot = iter->second;
3924 return true;
3925 }
3926 );
3927
3928 return std::make_unique<VSTEffectMessage>(
3929 settings.mChunk /* vector copy */, std::move(paramVector));
3930}
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References PackedArray::end(), ForEachParameter(), mAEffect, VSTEffectWrapper::ParameterInfo::mID, VSTEffectWrapper::ParameterInfo::mName, AEffect::numParams, and settings().

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

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

◆ ResetModuleAndHandle()

void VSTEffectWrapper::ResetModuleAndHandle ( )

Definition at line 2043 of file VSTEffect.cpp.

2044{
2045 if (mModule)
2046 {
2047#if defined(__WXMAC__)
2048 mResource.reset();
2049 mBundleRef.reset();
2050#endif
2051
2052 mModule.reset();
2053 mAEffect = NULL;
2054 }
2055}

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

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

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

◆ SaveFXB()

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

Definition at line 3235 of file VSTEffect.cpp.

3236{
3237 // Create/Open the file
3238 const wxString fullPath{fn.GetFullPath()};
3239 wxFFile f(fullPath, wxT("wb"));
3240 if (!f.IsOpened())
3241 {
3243 XO("Could not open file: \"%s\"").Format( fullPath ),
3244 XO("Error Saving VST Presets"),
3245 wxOK | wxCENTRE,
3246 nullptr);
3247 return;
3248 }
3249
3250 wxMemoryBuffer buf;
3251 wxInt32 subType;
3252 void *chunkPtr = nullptr;
3253 int chunkSize = 0;
3254 int dataSize = 148;
3255 wxInt32 tab[8];
3256 int curProg = 0 ; //mProgram->GetCurrentSelection();
3257
3259 {
3260 subType = CCONST('F', 'B', 'C', 'h');
3261
3262 // read-only dispatcher function
3263 chunkSize = constCallDispatcher(effGetChunk, 0, 0, &chunkPtr, 0.0);
3264 dataSize += 4 + chunkSize;
3265 }
3266 else
3267 {
3268 subType = CCONST('F', 'x', 'B', 'k');
3269
3270 for (int i = 0; i < mAEffect->numPrograms; i++)
3271 {
3272 SaveFXProgram(buf, i);
3273 }
3274
3275 dataSize += buf.GetDataLen();
3276 }
3277
3278 tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K'));
3279 tab[1] = wxINT32_SWAP_ON_LE(dataSize);
3280 tab[2] = wxINT32_SWAP_ON_LE(subType);
3281 tab[3] = wxINT32_SWAP_ON_LE(curProg >= 0 ? 2 : 1);
3282 tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID);
3283 tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version);
3284 tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numPrograms);
3285 tab[7] = wxINT32_SWAP_ON_LE(curProg >= 0 ? curProg : 0);
3286
3287 f.Write(tab, sizeof(tab));
3288 if (!f.Error())
3289 {
3290 char padding[124];
3291 memset(padding, 0, sizeof(padding));
3292 f.Write(padding, sizeof(padding));
3293
3294 if (!f.Error())
3295 {
3297 {
3298 wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize);
3299 f.Write(&size, sizeof(size));
3300 f.Write(chunkPtr, chunkSize);
3301 }
3302 else
3303 {
3304 f.Write(buf.GetData(), buf.GetDataLen());
3305 }
3306 }
3307 }
3308
3309 if (f.Error())
3310 {
3312 XO("Error writing to file: \"%s\"").Format( fullPath ),
3313 XO("Error Saving VST Presets"),
3314 wxOK | wxCENTRE,
3315 nullptr);
3316 }
3317
3318 f.Close();
3319
3320 return;
3321}
Abstract base class used in importing a file.
void SaveFXProgram(wxMemoryBuffer &buf, int index) const
Definition: VSTEffect.cpp:3359

References AudacityMessageBox(), CCONST, constCallDispatcher(), effFlagsProgramChunks, effGetChunk, AEffect::flags, fn, mAEffect, AEffect::numPrograms, SaveFXProgram(), 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 VSTEffectWrapper::SaveFXP ( const wxFileName &  fn) const

Definition at line 3323 of file VSTEffect.cpp.

3324{
3325 // Create/Open the file
3326 const wxString fullPath{ fn.GetFullPath() };
3327 wxFFile f(fullPath, wxT("wb"));
3328 if (!f.IsOpened())
3329 {
3331 XO("Could not open file: \"%s\"").Format( fullPath ),
3332 XO("Error Saving VST Presets"),
3333 wxOK | wxCENTRE,
3334 nullptr);
3335 return;
3336 }
3337
3338 wxMemoryBuffer buf;
3339
3340 // read-only dispatcher function
3341 int ndx = constCallDispatcher(effGetProgram, 0, 0, NULL, 0.0);
3342 SaveFXProgram(buf, ndx);
3343
3344 f.Write(buf.GetData(), buf.GetDataLen());
3345 if (f.Error())
3346 {
3348 XO("Error writing to file: \"%s\"").Format( fullPath ),
3349 XO("Error Saving VST Presets"),
3350 wxOK | wxCENTRE,
3351 nullptr);
3352 }
3353
3354 f.Close();
3355
3356 return;
3357}
const int effGetProgram
Definition: aeffectx.h:94

References AudacityMessageBox(), constCallDispatcher(), effGetProgram, fn, SaveFXProgram(), 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 VSTEffectWrapper::SaveFXProgram ( wxMemoryBuffer &  buf,
int  index 
) const

Definition at line 3359 of file VSTEffect.cpp.

3360{
3361 wxInt32 subType;
3362 void *chunkPtr;
3363 int chunkSize;
3364 int dataSize = 48;
3365 char progName[28];
3366 wxInt32 tab[7];
3367
3368 // read-only dispatcher function
3369 constCallDispatcher(effGetProgramNameIndexed, index, 0, &progName, 0.0);
3370 progName[27] = '\0';
3371 chunkSize = strlen(progName);
3372 memset(&progName[chunkSize], 0, sizeof(progName) - chunkSize);
3373
3375 {
3376 subType = CCONST('F', 'P', 'C', 'h');
3377
3378 // read-only dispatcher function
3379 chunkSize = constCallDispatcher(effGetChunk, 1, 0, &chunkPtr, 0.0);
3380 dataSize += 4 + chunkSize;
3381 }
3382 else
3383 {
3384 subType = CCONST('F', 'x', 'C', 'k');
3385
3386 dataSize += (mAEffect->numParams << 2);
3387 }
3388
3389 tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K'));
3390 tab[1] = wxINT32_SWAP_ON_LE(dataSize);
3391 tab[2] = wxINT32_SWAP_ON_LE(subType);
3392 tab[3] = wxINT32_SWAP_ON_LE(1);
3393 tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID);
3394 tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version);
3395 tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numParams);
3396
3397 buf.AppendData(tab, sizeof(tab));
3398 buf.AppendData(progName, sizeof(progName));
3399
3401 {
3402 wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize);
3403 buf.AppendData(&size, sizeof(size));
3404 buf.AppendData(chunkPtr, chunkSize);
3405 }
3406 else
3407 {
3408 for (int i = 0; i < mAEffect->numParams; i++)
3409 {
3410 float val = callGetParameter(i);
3411 wxUint32 ival = wxUINT32_SWAP_ON_LE(reinterpretAsUint32(val));
3412 buf.AppendData(&ival, sizeof(ival));
3413 }
3414 }
3415
3416 return;
3417}
static uint32_t reinterpretAsUint32(float f)
Definition: VSTEffect.cpp:118
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 VSTEffectWrapper::SaveXML ( const wxFileName &  fn) const

Definition at line 3420 of file VSTEffect.cpp.

3422{
3423 XMLFileWriter xmlFile{ fn.GetFullPath(), XO("Error Saving Effect Presets") };
3424
3425 xmlFile.StartTag(wxT("vstprogrampersistence"));
3426 xmlFile.WriteAttr(wxT("version"), wxT("2"));
3427
3428 xmlFile.StartTag(wxT("effect"));
3429 // Use internal name only in persistent information
3430 xmlFile.WriteAttr(wxT("name"), GetSymbol().Internal());
3431 xmlFile.WriteAttr(wxT("uniqueID"), mAEffect->uniqueID);
3432 xmlFile.WriteAttr(wxT("version"), mAEffect->version);
3433 xmlFile.WriteAttr(wxT("numParams"), mAEffect->numParams);
3434
3435 xmlFile.StartTag(wxT("program"));
3436 xmlFile.WriteAttr(wxT("name"), wxEmptyString); //mProgram->GetValue());
3437
3438 int clen = 0;
3440 {
3441 void *chunk = NULL;
3442
3443 // read-only dispatcher function
3444 clen = (int) constCallDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
3445 if (clen != 0)
3446 {
3447 xmlFile.StartTag(wxT("chunk"));
3448 xmlFile.WriteSubTree(Base64::Encode(chunk, clen) + wxT('\n'));
3449 xmlFile.EndTag(wxT("chunk"));
3450 }
3451 }
3452
3453 if (clen == 0)
3454 {
3455 for (int i = 0; i < mAEffect->numParams; i++)
3456 {
3457 xmlFile.StartTag(wxT("param"));
3458
3459 xmlFile.WriteAttr(wxT("index"), i);
3460 xmlFile.WriteAttr(wxT("name"),
3462 xmlFile.WriteAttr(wxT("value"),
3463 wxString::Format(wxT("%f"),
3464 callGetParameter(i)));
3465
3466 xmlFile.EndTag(wxT("param"));
3467 }
3468 }
3469
3470 xmlFile.EndTag(wxT("program"));
3471
3472 xmlFile.EndTag(wxT("effect"));
3473
3474 xmlFile.EndTag(wxT("vstprogrampersistence"));
3475
3476 xmlFile.Commit();
3477}
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 effFlagsProgramChunks, effGetChunk, effGetParamName, Base64::Encode(), fn, Internal, 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 VSTEffectWrapper::SetBufferDelay ( int  samples)
virtual

Reimplemented in VSTEffectInstance.

Definition at line 2409 of file VSTEffect.cpp.

2410{
2411}

Referenced by AudioMaster().

Here is the caller graph for this function:

◆ SetString()

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

Definition at line 2448 of file VSTEffect.cpp.

2449{
2450 char buf[256];
2451 strcpy(buf, str.Left(255).ToUTF8());
2452
2453 callDispatcher(opcode, index, 0, buf, 0.0);
2454}

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 VSTEffectWrapper::StoreSettings ( const VSTEffectSettings vst3settings) const

Definition at line 3833 of file VSTEffect.cpp.

3834{
3835 // First, make sure settings are compatibile with the plugin
3836 if ((vstSettings.mUniqueID != mAEffect->uniqueID) ||
3837// (vstSettings.mVersion != mAEffect->version) ||
3838 (vstSettings.mNumParams != mAEffect->numParams) )
3839 {
3840 return false;
3841 }
3842
3843
3844 // Try using the chunk first (if available)
3845 auto &chunk = vstSettings.mChunk;
3846 if (!chunk.empty())
3847 {
3849 callSetChunk(true, chunk.size(), const_cast<char *>(chunk.data()), &info);
3850 }
3851
3852
3853 // Settings (like the message) may store both a chunk, and also accumulated
3854 // slider movements to reapply after the chunk change. Or it might be
3855 // no chunk and id-value pairs only
3856
3857 constCallDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
3858
3860 (
3861 [&](const ParameterInfo& pi)
3862 {
3863 const auto itr = vstSettings.mParamsMap.find(pi.mName);
3864 if (itr != vstSettings.mParamsMap.end())
3865 {
3866 const float& value = *(itr->second);
3867
3868 if (value >= -1.0 && value <= 1.0)
3869 {
3870 callSetParameter(pi.mID, value);
3871 }
3872 }
3873 return true;
3874 }
3875 );
3876
3877 constCallDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
3878
3879 return true;
3880}

References callSetChunk(), constCallDispatcher(), effBeginSetProgram, ForEachParameter(), mAEffect, VSTEffectSettings::mChunk, VSTEffectWrapper::ParameterInfo::mName, VSTEffectSettings::mNumParams, VSTEffectSettings::mParamsMap, VSTEffectSettings::mUniqueID, AEffect::numParams, AEffect::uniqueID, and AEffect::version.

Referenced by VSTEffect::ExportPresets(), VSTEffectInstance::ProcessInitialize(), VSTEffect::SaveUserPreset(), and VSTEffectEditor::StoreSettingsToInstance().

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

◆ Unload()

void VSTEffectWrapper::Unload ( )

Definition at line 2030 of file VSTEffect.cpp.

2031{
2032 if (mAEffect)
2033 {
2034 // Finally, close the plugin
2035 callDispatcher(effClose, 0, 0, NULL, 0.0);
2036 mAEffect = NULL;
2037 }
2038
2039 //ResetModuleAndHandle();
2040}
const int effClose
Definition: aeffectx.h:92

References callDispatcher(), effClose, and mAEffect.

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

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

◆ UpdateDisplay()

void VSTEffectWrapper::UpdateDisplay ( )
virtual

Reimplemented in VSTEffect.

Definition at line 3975 of file VSTEffect.cpp.

3976{
3977}

Referenced by AudioMaster().

Here is the caller graph for this function:

Member Data Documentation

◆ mAEffect

AEffect* VSTEffectWrapper::mAEffect = nullptr

◆ mAudioIns

unsigned VSTEffectWrapper::mAudioIns { 0 }

◆ mAudioOuts

unsigned VSTEffectWrapper::mAudioOuts { 0 }

◆ mAutomatable

bool VSTEffectWrapper::mAutomatable

Definition at line 236 of file VSTEffect.h.

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

◆ mBufferDelay

int VSTEffectWrapper::mBufferDelay { 0 }

Definition at line 278 of file VSTEffect.h.

Referenced by VSTEffectInstance::SetBufferDelay().

◆ mBundleRef

BundleHandle VSTEffectWrapper::mBundleRef

Definition at line 247 of file VSTEffect.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mChunk

wxString VSTEffectWrapper::mChunk

Definition at line 182 of file VSTEffect.h.

Referenced by HandleXMLContent(), and HandleXMLEndTag().

◆ mCurrentEffectID

intptr_t VSTEffectWrapper::mCurrentEffectID {}

Definition at line 211 of file VSTEffect.h.

Referenced by AudioMaster(), and Load().

◆ mDescription

wxString VSTEffectWrapper::mDescription

Definition at line 229 of file VSTEffect.h.

◆ mDispatcherLock

std::recursive_mutex VSTEffectWrapper::mDispatcherLock

Definition at line 144 of file VSTEffect.h.

Referenced by callDispatcher().

◆ mGui

bool VSTEffectWrapper::mGui { false }

Definition at line 310 of file VSTEffect.h.

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

◆ mInChunk

bool VSTEffectWrapper::mInChunk

Definition at line 181 of file VSTEffect.h.

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

◆ mInSet

bool VSTEffectWrapper::mInSet

Definition at line 180 of file VSTEffect.h.

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

◆ mInteractive

bool VSTEffectWrapper::mInteractive { false }

Definition at line 231 of file VSTEffect.h.

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

◆ mMainThreadId

std::thread::id VSTEffectWrapper::mMainThreadId

◆ mMidiIns

int VSTEffectWrapper::mMidiIns { 0 }

Definition at line 234 of file VSTEffect.h.

◆ mMidiOuts

int VSTEffectWrapper::mMidiOuts { 0 }

Definition at line 235 of file VSTEffect.h.

◆ mModule

ModuleHandle VSTEffectWrapper::mModule {}

Definition at line 226 of file VSTEffect.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mName

wxString VSTEffectWrapper::mName

Definition at line 177 of file VSTEffect.h.

Referenced by GetSymbol(), and Load().

◆ mPath

PluginPath VSTEffectWrapper::mPath

◆ mProcessLevel

int VSTEffectWrapper::mProcessLevel { 1 }

Definition at line 281 of file VSTEffect.h.

Referenced by GetProcessLevel().

◆ mResource

ResourceHandle VSTEffectWrapper::mResource

Definition at line 270 of file VSTEffect.h.

Referenced by Load(), and ResetModuleAndHandle().

◆ mTimeInfo

VstTimeInfo VSTEffectWrapper::mTimeInfo

◆ mVendor

wxString VSTEffectWrapper::mVendor

Definition at line 228 of file VSTEffect.h.

Referenced by VSTEffect::GetVendor(), Load(), and VSTEffectInstance::VSTEffectInstance().

◆ mVersion

int VSTEffectWrapper::mVersion

Definition at line 230 of file VSTEffect.h.

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

◆ mVstVersion

int VSTEffectWrapper::mVstVersion

◆ mXMLInfo

VstPatchChunkInfo VSTEffectWrapper::mXMLInfo

Definition at line 184 of file VSTEffect.h.

Referenced by HandleXMLEndTag(), and HandleXMLTag().

◆ mXMLVersion

long VSTEffectWrapper::mXMLVersion

Definition at line 183 of file VSTEffect.h.

Referenced by HandleXMLTag().


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