1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 23:30:07 +02:00

Remove some naked new amd delete in: Plug-in effects

This commit is contained in:
Paul Licameli 2016-08-04 07:33:50 -04:00
parent 6fec00149b
commit eb6ba1ed7a
10 changed files with 138 additions and 155 deletions

View File

@ -1043,6 +1043,30 @@ intptr_t VSTEffect::AudioMaster(AEffect * effect,
return 0;
}
#if !defined(__WXMSW__)
void VSTEffect::ModuleDeleter::operator() (void* p) const
{
if (p)
dlclose(p);
}
#endif
#if defined(__WXMAC__)
void VSTEffect::BundleDeleter::operator() (void* p) const
{
if (p)
CFRelease(static_cast<CFBundleRef>(p));
}
void VSTEffect::ResourceDeleter::operator() (void *p) const
{
if (mpHandle) {
int resource = (int)p;
CFBundleCloseBundleResourceMap(mpHandle->get(), resource);
}
}
#endif
VSTEffect::VSTEffect(const wxString & path, VSTEffect *master)
: mPath(path),
mMaster(master)
@ -1052,7 +1076,7 @@ VSTEffect::VSTEffect(const wxString & path, VSTEffect *master)
mAEffect = NULL;
mDialog = NULL;
mTimer = new VSTEffectTimer(this);
mTimer = std::make_unique<VSTEffectTimer>(this);
mTimerGuard = 0;
mInteractive = false;
@ -1986,10 +2010,9 @@ bool VSTEffect::Load()
#if defined(__WXMAC__)
// Start clean
mBundleRef = NULL;
mBundleRef.reset();
// Don't really know what this should be initialize to
mResource = -1;
mResource = ResourceHandle{};
// Convert the path to a CFSTring
wxCFStringRef path(realPath);
@ -1997,33 +2020,30 @@ bool VSTEffect::Load()
// Convert the path to a URL
CFURLRef urlRef =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
path,
kCFURLPOSIXPathStyle,
true);
path,
kCFURLPOSIXPathStyle,
true);
if (urlRef == NULL)
{
return false;
}
// Create the bundle using the URL
CFBundleRef bundleRef = CFBundleCreate(kCFAllocatorDefault, urlRef);
BundleHandle bundleRef{ CFBundleCreate(kCFAllocatorDefault, urlRef) };
// Done with the URL
CFRelease(urlRef);
// Bail if the bundle wasn't created
if (bundleRef == NULL)
if (!bundleRef)
{
return false;
}
// Retrieve a reference to the executable
CFURLRef exeRef = CFBundleCopyExecutableURL(bundleRef);
if (exeRef == NULL)
{
CFRelease(bundleRef);
CFURLRef exeRef = CFBundleCopyExecutableURL(bundleRef.get());
if (!exeRef)
return false;
}
// Convert back to path
UInt8 exePath[PLATFORM_MAX_PATH];
@ -2034,43 +2054,39 @@ bool VSTEffect::Load()
// Bail if we couldn't resolve the executable path
if (good == FALSE)
{
CFRelease(bundleRef);
return false;
}
// Attempt to open it
mModule = dlopen((char *) exePath, RTLD_NOW | RTLD_LOCAL);
if (mModule == NULL)
{
CFRelease(bundleRef);
mModule.reset((char*)dlopen((char *) exePath, RTLD_NOW | RTLD_LOCAL));
if (!mModule)
return false;
}
// Try to locate the NEW plugin entry point
pluginMain = (vstPluginMain) dlsym(mModule, "VSTPluginMain");
pluginMain = (vstPluginMain) dlsym(mModule.get(), "VSTPluginMain");
// If not found, try finding the old entry point
if (pluginMain == NULL)
{
pluginMain = (vstPluginMain) dlsym(mModule, "main_macho");
pluginMain = (vstPluginMain) dlsym(mModule.get(), "main_macho");
}
// Must not be a VST plugin
if (pluginMain == NULL)
{
dlclose(mModule);
mModule = NULL;
CFRelease(bundleRef);
mModule.reset();
return false;
}
// Need to keep the bundle reference around so we can map the
// resources.
mBundleRef = bundleRef;
mBundleRef = std::move(bundleRef);
// Open the resource map ... some plugins (like GRM Tools) need this.
mResource = (int) CFBundleOpenBundleResourceMap(bundleRef);
mResource = ResourceHandle {
reinterpret_cast<char*>(
CFBundleOpenBundleResourceMap(mBundleRef.get())),
ResourceDeleter{&mBundleRef}
};
#elif defined(__WXMSW__)
@ -2078,18 +2094,13 @@ bool VSTEffect::Load()
wxLogNull nolog;
// Try to load the library
wxDynamicLibrary *lib = new wxDynamicLibrary(realPath);
auto lib = std::make_unique<wxDynamicLibrary>(realPath);
if (!lib)
{
return false;
}
// Bail if it wasn't successful
if (!lib->IsLoaded())
{
delete lib;
return false;
}
// Try to find the entry point, while suppressing error messages
pluginMain = (vstPluginMain) lib->GetSymbol(wxT("VSTPluginMain"));
@ -2097,14 +2108,11 @@ bool VSTEffect::Load()
{
pluginMain = (vstPluginMain) lib->GetSymbol(wxT("main"));
if (pluginMain == NULL)
{
delete lib;
return false;
}
}
// Save the library reference
mModule = lib;
mModule = std::move(lib);
}
#else
@ -2128,26 +2136,26 @@ bool VSTEffect::Load()
#ifndef RTLD_DEEPBIND
#define RTLD_DEEPBIND 0
#endif
void *lib = dlopen((const char *)wxString(realPath).ToUTF8(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
ModuleHandle lib {
(char*) dlopen((const char *)wxString(realPath).ToUTF8(),
RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND)
};
if (!lib)
{
return false;
}
// Try to find the entry point, while suppressing error messages
pluginMain = (vstPluginMain) dlsym(lib, "VSTPluginMain");
pluginMain = (vstPluginMain) dlsym(lib.get(), "VSTPluginMain");
if (pluginMain == NULL)
{
pluginMain = (vstPluginMain) dlsym(lib, "main");
pluginMain = (vstPluginMain) dlsym(lib.get(), "main");
if (pluginMain == NULL)
{
dlclose(lib);
return false;
}
}
// Save the library reference
mModule = lib;
mModule = std::move(lib);
#endif
@ -2267,13 +2275,6 @@ void VSTEffect::Unload()
CloseUI();
}
if (mTimer)
{
mTimer->Stop();
delete mTimer;
mTimer = NULL;
}
if (mAEffect)
{
// Turn the power off
@ -2287,32 +2288,11 @@ void VSTEffect::Unload()
if (mModule)
{
#if defined(__WXMAC__)
if (mResource != -1)
{
CFBundleCloseBundleResourceMap((CFBundleRef) mBundleRef, mResource);
mResource = -1;
}
if (mBundleRef != NULL)
{
CFRelease((CFBundleRef) mBundleRef);
mBundleRef = NULL;
}
dlclose(mModule);
#elif defined(__WXMSW__)
delete (wxDynamicLibrary *) mModule;
#else
dlclose(mModule);
mResource = ResourceHandle{};
mBundleRef.reset();
#endif
mModule = NULL;
mModule.reset();
mAEffect = NULL;
}
}

View File

@ -49,6 +49,11 @@ typedef AEffect *(*vstPluginMain)(audioMasterCallback audioMaster);
class VSTEffectTimer;
class VSTEffectDialog;
class VSTEffect;
class wxDynamicLibrary;
#if defined(__WXMAC__)
struct __CFBundle;
#endif
///////////////////////////////////////////////////////////////////////////////
//
@ -244,6 +249,16 @@ private:
void callSetChunk(bool isPgm, int len, void *buf, VstPatchChunkInfo *info);
private:
// Define a manager class for a handle to a module
#if defined(__WXMSW__)
using ModuleHandle = std::unique_ptr<wxDynamicLibrary>;
#else
struct ModuleDeleter {
void operator() (void*) const;
};
using ModuleHandle = std::unique_ptr < char, ModuleDeleter > ;
#endif
EffectHostInterface *mHost;
PluginID mID;
wxString mPath;
@ -265,11 +280,32 @@ private:
bool mReady;
ModuleHandle mModule;
#if defined(__WXMAC__)
void *mBundleRef; // Cheating a little ... type is really CFBundle
int mResource; // Cheating a little ... type is really CFBundle
// These members must be ordered after mModule
struct BundleDeleter {
void operator() (void*) const;
};
using BundleHandle = std::unique_ptr<
__CFBundle, BundleDeleter
>;
BundleHandle mBundleRef;
struct ResourceDeleter {
const BundleHandle *mpHandle;
ResourceDeleter(const BundleHandle *pHandle = nullptr)
: mpHandle(pHandle) {}
void operator() (void*) const;
};
using ResourceHandle = std::unique_ptr<
char, ResourceDeleter
>;
ResourceHandle mResource;
#endif
void *mModule;
AEffect *mAEffect;
VstTimeInfo mTimeInfo;
@ -286,7 +322,7 @@ private:
wxCRIT_SECT_DECLARE_MEMBER(mDispatcherLock);
VSTEffectTimer *mTimer;
std::unique_ptr<VSTEffectTimer> mTimer;
int mTimerGuard;
// Realtime processing

View File

@ -1346,36 +1346,28 @@ bool AudioUnitEffect::RealtimeInitialize()
bool AudioUnitEffect::RealtimeAddProcessor(int numChannels, float sampleRate)
{
AudioUnitEffect *slave = new AudioUnitEffect(mPath, mName, mComponent, this);
auto slave = make_movable<AudioUnitEffect>(mPath, mName, mComponent, this);
if (!slave->SetHost(NULL))
{
delete slave;
return false;
}
slave->SetBlockSize(mBlockSize);
slave->SetChannelCount(numChannels);
slave->SetSampleRate(sampleRate);
if (!CopyParameters(mUnit, slave->mUnit))
{
delete slave;
return false;
}
mSlaves.Add(slave);
auto pSlave = slave.get();
mSlaves.push_back(std::move(slave));
return slave->ProcessInitialize(0);
return pSlave->ProcessInitialize(0);
}
bool AudioUnitEffect::RealtimeFinalize()
{
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
mSlaves[i]->ProcessFinalize();
delete mSlaves[i];
}
mSlaves.Clear();
mSlaves.clear();
for (int i = 0; i < mAudioIns; i++)
{
@ -2184,10 +2176,8 @@ void AudioUnitEffect::EventListener(const AudioUnitEvent *inEvent,
else
{
// We're the master, so propogate
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
mSlaves[i]->EventListener(inEvent, inParameterValue);
}
}
}

View File

@ -14,6 +14,8 @@
#if USE_AUDIO_UNITS
#include "../../MemoryX.h"
#include <vector>
#include <wx/dialog.h>
#include <AudioToolbox/AudioUnitUtilities.h>
@ -31,7 +33,7 @@
class AudioUnitEffect;
WX_DEFINE_ARRAY_PTR(AudioUnitEffect *, AudioUnitEffectArray);
using AudioUnitEffectArray = std::vector<movable_ptr<AudioUnitEffect>>;
class AudioUnitEffectExportDialog;
class AudioUnitEffectImportDialog;

View File

@ -124,7 +124,7 @@ void LV2EffectMeter::OnErase(wxEraseEvent & WXUNUSED(evt))
void LV2EffectMeter::OnPaint(wxPaintEvent & WXUNUSED(evt))
{
wxDC *dc = wxAutoBufferedPaintDCFactory(this);
std::unique_ptr<wxDC> dc{ wxAutoBufferedPaintDCFactory(this) };
// Cache some metrics
wxRect r = GetClientRect();
@ -153,8 +153,6 @@ void LV2EffectMeter::OnPaint(wxPaintEvent & WXUNUSED(evt))
dc->DrawRectangle(x, y, (w * (val / fabs(mCtrl.mMax - mCtrl.mMin))), h);
mLastValue = mCtrl.mVal;
delete dc;
}
void LV2EffectMeter::OnSize(wxSizeEvent & WXUNUSED(evt))
@ -1461,8 +1459,10 @@ bool LV2Effect::BuildFancy()
}
// Use a panel to host the plugins GUI
mContainer = safenew wxPanelWrapper(mParent, wxID_ANY);
if (!mContainer)
// container is owned by mParent, but we may destroy it if there are
// any errors before completing the build of UI.
auto container = std::make_unique<wxPanelWrapper>(mParent, wxID_ANY);
if (!container)
{
lilv_uis_free(uis);
return false;
@ -1476,30 +1476,29 @@ bool LV2Effect::BuildFancy()
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
if (hs)
{
si = hs->Add(mContainer, 1, wxCENTER | wxEXPAND);
si = hs->Add(container.get(), 1, wxCENTER | wxEXPAND);
vs->Add(hs.release(), 0, wxCENTER);
}
}
if (!si)
{
delete mContainer;
lilv_uis_free(uis);
return false;
}
#if defined(__WXGTK__)
// Make sure the parent has a window
if (!gtk_widget_get_window(GTK_WIDGET(mContainer->m_wxwindow)))
if (!gtk_widget_get_window(GTK_WIDGET(container->m_wxwindow)))
{
gtk_widget_realize(GTK_WIDGET(mContainer->m_wxwindow));
gtk_widget_realize(GTK_WIDGET(container->m_wxwindow));
}
mParentFeature->data = GTK_WIDGET(mContainer->GetHandle());
mParentFeature->data = GTK_WIDGET(container->GetHandle());
#elif defined(__WXMSW__)
mParentFeature->data = mContainer->GetHandle();
mParentFeature->data = container->GetHandle();
#elif defined(__WXMAC__)
mParentFeature->data = mContainer->GetHandle();
mParentFeature->data = container->GetHandle();
#endif
mInstanceAccessFeature->data = lilv_instance_get_handle(mMaster);
@ -1509,7 +1508,6 @@ bool LV2Effect::BuildFancy()
mSuilHost = suil_host_new(LV2Effect::suil_write_func, NULL, NULL, NULL);
if (!mSuilHost)
{
delete mContainer;
lilv_uis_free(uis);
return false;
}
@ -1532,7 +1530,6 @@ bool LV2Effect::BuildFancy()
suil_host_free(mSuilHost);
mSuilHost = NULL;
delete mContainer;
return false;
}
@ -1545,7 +1542,7 @@ bool LV2Effect::BuildFancy()
gtk_widget_set_size_request(widget, 1, 1);
gtk_widget_set_size_request(widget, sz.width, sz.height);
wxPizza *pizza = WX_PIZZA(mContainer->m_wxwindow);
wxPizza *pizza = WX_PIZZA(container->m_wxwindow);
pizza->put(widget,
0, //gtk_pizza_get_xoffset(pizza),
0, //gtk_pizza_get_yoffset(pizza),
@ -1565,6 +1562,8 @@ bool LV2Effect::BuildFancy()
#endif
mParent->SetSizerAndFit(vs.release());
// mParent will guarantee release of the container now.
container.release();
}
mIdleFeature = (const LV2UI_Idle_Interface *)

View File

@ -285,7 +285,6 @@ private:
EffectUIHostInterface *mUIHost;
bool mUseGUI;
wxWindow *mContainer;
char **mURIMap;
int mNumURIMap;

View File

@ -132,7 +132,7 @@ wxArrayString VampEffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(p
for (PluginLoader::PluginKeyList::iterator i = keys.begin(); i != keys.end(); ++i)
{
Plugin *vp = PluginLoader::getInstance()->loadPlugin(*i, 48000); // rate doesn't matter here
std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(*i, 48000) }; // rate doesn't matter here
if (!vp)
{
continue;
@ -194,8 +194,6 @@ wxArrayString VampEffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(p
++output;
}
delete vp;
}
return names;
@ -206,10 +204,10 @@ bool VampEffectsModule::RegisterPlugin(PluginManagerInterface & pm, const wxStri
int output;
bool hasParameters;
Plugin *vp = FindPlugin(path, output, hasParameters);
auto vp = FindPlugin(path, output, hasParameters);
if (vp)
{
VampEffect effect(vp, path, output, hasParameters);
VampEffect effect(std::move(vp), path, output, hasParameters);
pm.RegisterPlugin(this, &effect);
return true;
@ -223,14 +221,8 @@ bool VampEffectsModule::IsPluginValid(const wxString & path)
int output;
bool hasParameters;
Plugin *vp = FindPlugin(path, output, hasParameters);
if (vp)
{
delete vp;
return true;
}
return false;
auto vp = FindPlugin(path, output, hasParameters);
return bool(vp);
}
IdentInterface *VampEffectsModule::CreateInstance(const wxString & path)
@ -239,11 +231,11 @@ IdentInterface *VampEffectsModule::CreateInstance(const wxString & path)
int output;
bool hasParameters;
Plugin *vp = FindPlugin(path, output, hasParameters);
auto vp = FindPlugin(path, output, hasParameters);
if (vp)
{
// Safety of this depends on complementary calls to DeleteInstance on the module manager side.
return safenew VampEffect(vp, path, output, hasParameters);
return safenew VampEffect(std::move(vp), path, output, hasParameters);
}
return NULL;
@ -258,13 +250,13 @@ void VampEffectsModule::DeleteInstance(IdentInterface *instance)
// VampEffectsModule implementation
Plugin *VampEffectsModule::FindPlugin(const wxString & path,
std::unique_ptr<Vamp::Plugin> VampEffectsModule::FindPlugin(const wxString & path,
int & output,
bool & hasParameters)
{
PluginLoader::PluginKey key = path.BeforeLast(wxT('/')).ToUTF8().data();
Plugin *vp = PluginLoader::getInstance()->loadPlugin(key, 48000); // rate doesn't matter here
std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(key, 48000) }; // rate doesn't matter here
if (!vp)
{
return nullptr;
@ -331,9 +323,7 @@ Plugin *VampEffectsModule::FindPlugin(const wxString & path,
++output;
}
delete vp;
return NULL;
return {};
}
#endif

View File

@ -54,7 +54,7 @@ public:
private:
// VampEffectModule implementation
Vamp::Plugin *FindPlugin(const wxString & wpath,
std::unique_ptr<Vamp::Plugin> FindPlugin(const wxString & wpath,
int & output,
bool & hasParameters);

View File

@ -69,11 +69,11 @@ BEGIN_EVENT_TABLE(VampEffect, wxEvtHandler)
EVT_CHOICE(wxID_ANY, VampEffect::OnChoice)
END_EVENT_TABLE()
VampEffect::VampEffect(Vamp::Plugin *plugin,
VampEffect::VampEffect(std::unique_ptr<Vamp::Plugin> &&plugin,
const wxString & path,
int output,
bool hasParameters)
: mPlugin(plugin),
: mPlugin(std::move(plugin)),
mPath(path),
mOutput(output),
mHasParameters(hasParameters),
@ -92,11 +92,6 @@ VampEffect::VampEffect(Vamp::Plugin *plugin,
VampEffect::~VampEffect()
{
if (mPlugin)
{
delete mPlugin;
}
if (mValues)
{
delete [] mValues;
@ -381,14 +376,7 @@ bool VampEffect::Init()
// The plugin must be reloaded to allow changing parameters
Vamp::HostExt::PluginLoader *loader = Vamp::HostExt::PluginLoader::getInstance();
if (mPlugin)
{
delete mPlugin;
mPlugin = NULL;
}
mPlugin = loader->loadPlugin(mKey, mRate, Vamp::HostExt::PluginLoader::ADAPT_ALL);
mPlugin.reset(loader->loadPlugin(mKey, mRate, Vamp::HostExt::PluginLoader::ADAPT_ALL));
if (!mPlugin)
{
wxMessageBox(_("Sorry, failed to load Vamp Plug-in."));
@ -584,8 +572,7 @@ bool VampEffect::Process()
void VampEffect::End()
{
delete mPlugin;
mPlugin = 0;
mPlugin.reset();
}
void VampEffect::PopulateOrExchange(ShuttleGui & S)

View File

@ -35,7 +35,7 @@ class LabelTrack;
class VampEffect final : public Effect
{
public:
VampEffect(Vamp::Plugin *plugin,
VampEffect(std::unique_ptr<Vamp::Plugin> &&plugin,
const wxString & path,
int output,
bool hasParameters);
@ -85,7 +85,7 @@ private:
void OnTextCtrl(wxCommandEvent & evt);
private:
Vamp::Plugin *mPlugin;
std::unique_ptr<Vamp::Plugin> mPlugin;
wxString mPath;
int mOutput;
bool mHasParameters;