1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 23:59:37 +02:00

Converts the ladspa effects to the new format and adds realtime support

This also (hopefully) corrects some additional problems in general 
realtime support.  Particular focus should be given to the handling
of various combinations of stereo, left channel mono, right channel
mono, and true mono as this has been a particularly troublesome
area.
This commit is contained in:
lllucius@gmail.com 2014-11-05 07:06:38 +00:00
parent 080b67ce9e
commit 126152a756
15 changed files with 1066 additions and 761 deletions

View File

@ -336,7 +336,6 @@
1790B13C09883BFD008A330A /* Fade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01D09883BFD008A330A /* Fade.cpp */; };
1790B13E09883BFD008A330A /* Invert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02109883BFD008A330A /* Invert.cpp */; };
1790B13F09883BFD008A330A /* LadspaEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02609883BFD008A330A /* LadspaEffect.cpp */; };
1790B14009883BFD008A330A /* LoadLadspa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02809883BFD008A330A /* LoadLadspa.cpp */; };
1790B14109883BFD008A330A /* Leveller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02A09883BFD008A330A /* Leveller.cpp */; };
1790B14209883BFD008A330A /* LoadEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02C09883BFD008A330A /* LoadEffects.cpp */; };
1790B14309883BFD008A330A /* Noise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02E09883BFD008A330A /* Noise.cpp */; };
@ -1314,7 +1313,6 @@
ED663BA816543647007F53A5 /* Fade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01D09883BFD008A330A /* Fade.cpp */; };
ED663BA916543647007F53A5 /* Invert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02109883BFD008A330A /* Invert.cpp */; };
ED663BAA16543647007F53A5 /* LadspaEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02609883BFD008A330A /* LadspaEffect.cpp */; };
ED663BAB16543647007F53A5 /* LoadLadspa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02809883BFD008A330A /* LoadLadspa.cpp */; };
ED663BAC16543647007F53A5 /* Leveller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02A09883BFD008A330A /* Leveller.cpp */; };
ED663BAD16543647007F53A5 /* LoadEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02C09883BFD008A330A /* LoadEffects.cpp */; };
ED663BAE16543647007F53A5 /* Noise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02E09883BFD008A330A /* Noise.cpp */; };
@ -1641,7 +1639,6 @@
ED85B48016A47353006DA21D /* Fade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01D09883BFD008A330A /* Fade.cpp */; };
ED85B48116A47353006DA21D /* Invert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02109883BFD008A330A /* Invert.cpp */; };
ED85B48216A47353006DA21D /* LadspaEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02609883BFD008A330A /* LadspaEffect.cpp */; };
ED85B48316A47353006DA21D /* LoadLadspa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02809883BFD008A330A /* LoadLadspa.cpp */; };
ED85B48416A47353006DA21D /* Leveller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02A09883BFD008A330A /* Leveller.cpp */; };
ED85B48516A47353006DA21D /* LoadEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02C09883BFD008A330A /* LoadEffects.cpp */; };
ED85B48616A47353006DA21D /* Noise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B02E09883BFD008A330A /* Noise.cpp */; };
@ -2865,8 +2862,6 @@
1790B02509883BFD008A330A /* ladspa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = ladspa.h; sourceTree = "<group>"; tabWidth = 3; };
1790B02609883BFD008A330A /* LadspaEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LadspaEffect.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B02709883BFD008A330A /* LadspaEffect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = LadspaEffect.h; sourceTree = "<group>"; tabWidth = 3; };
1790B02809883BFD008A330A /* LoadLadspa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LoadLadspa.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B02909883BFD008A330A /* LoadLadspa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = LoadLadspa.h; sourceTree = "<group>"; tabWidth = 3; };
1790B02A09883BFD008A330A /* Leveller.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = Leveller.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B02B09883BFD008A330A /* Leveller.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = Leveller.h; sourceTree = "<group>"; tabWidth = 3; };
1790B02C09883BFD008A330A /* LoadEffects.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LoadEffects.cpp; sourceTree = "<group>"; tabWidth = 3; };
@ -5270,8 +5265,6 @@
1790B02509883BFD008A330A /* ladspa.h */,
1790B02609883BFD008A330A /* LadspaEffect.cpp */,
1790B02709883BFD008A330A /* LadspaEffect.h */,
1790B02809883BFD008A330A /* LoadLadspa.cpp */,
1790B02909883BFD008A330A /* LoadLadspa.h */,
);
path = ladspa;
sourceTree = "<group>";
@ -8833,7 +8826,6 @@
1790B13C09883BFD008A330A /* Fade.cpp in Sources */,
1790B13E09883BFD008A330A /* Invert.cpp in Sources */,
1790B13F09883BFD008A330A /* LadspaEffect.cpp in Sources */,
1790B14009883BFD008A330A /* LoadLadspa.cpp in Sources */,
1790B14109883BFD008A330A /* Leveller.cpp in Sources */,
1790B14209883BFD008A330A /* LoadEffects.cpp in Sources */,
1790B14309883BFD008A330A /* Noise.cpp in Sources */,
@ -9345,7 +9337,6 @@
ED663BA816543647007F53A5 /* Fade.cpp in Sources */,
ED663BA916543647007F53A5 /* Invert.cpp in Sources */,
ED663BAA16543647007F53A5 /* LadspaEffect.cpp in Sources */,
ED663BAB16543647007F53A5 /* LoadLadspa.cpp in Sources */,
ED663BAC16543647007F53A5 /* Leveller.cpp in Sources */,
ED663BAD16543647007F53A5 /* LoadEffects.cpp in Sources */,
ED663BAE16543647007F53A5 /* Noise.cpp in Sources */,
@ -9655,7 +9646,6 @@
ED85B48016A47353006DA21D /* Fade.cpp in Sources */,
ED85B48116A47353006DA21D /* Invert.cpp in Sources */,
ED85B48216A47353006DA21D /* LadspaEffect.cpp in Sources */,
ED85B48316A47353006DA21D /* LoadLadspa.cpp in Sources */,
ED85B48416A47353006DA21D /* Leveller.cpp in Sources */,
ED85B48516A47353006DA21D /* LoadEffects.cpp in Sources */,
ED85B48616A47353006DA21D /* Noise.cpp in Sources */,

View File

@ -585,8 +585,6 @@ audacity_SOURCES += \
effects/ladspa/ladspa.h \
effects/ladspa/LadspaEffect.cpp \
effects/ladspa/LadspaEffect.h \
effects/ladspa/LoadLadspa.cpp \
effects/ladspa/LoadLadspa.h \
$(NULL)
endif

View File

@ -113,8 +113,6 @@ bin_PROGRAMS = audacity$(EXEEXT)
@USE_LADSPA_TRUE@ effects/ladspa/ladspa.h \
@USE_LADSPA_TRUE@ effects/ladspa/LadspaEffect.cpp \
@USE_LADSPA_TRUE@ effects/ladspa/LadspaEffect.h \
@USE_LADSPA_TRUE@ effects/ladspa/LoadLadspa.cpp \
@USE_LADSPA_TRUE@ effects/ladspa/LoadLadspa.h \
@USE_LADSPA_TRUE@ $(NULL)
@USE_LAME_TRUE@am__append_13 = $(LAME_CFLAGS)
@ -469,7 +467,6 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
import/ImportFFmpeg.h import/ImportGStreamer.cpp \
import/ImportGStreamer.h effects/ladspa/ladspa.h \
effects/ladspa/LadspaEffect.cpp effects/ladspa/LadspaEffect.h \
effects/ladspa/LoadLadspa.cpp effects/ladspa/LoadLadspa.h \
ondemand/ODDecodeFlacTask.cpp ondemand/ODDecodeFlacTask.h \
effects/nyquist/LoadNyquist.cpp effects/nyquist/LoadNyquist.h \
effects/nyquist/Nyquist.cpp effects/nyquist/Nyquist.h \
@ -504,8 +501,7 @@ am__objects_1 = audacity-BlockFile.$(OBJEXT) \
@USE_FFMPEG_TRUE@ import/audacity-ImportFFmpeg.$(OBJEXT)
@USE_GSTREAMER_TRUE@am__objects_4 = \
@USE_GSTREAMER_TRUE@ import/audacity-ImportGStreamer.$(OBJEXT)
@USE_LADSPA_TRUE@am__objects_5 = effects/ladspa/audacity-LadspaEffect.$(OBJEXT) \
@USE_LADSPA_TRUE@ effects/ladspa/audacity-LoadLadspa.$(OBJEXT)
@USE_LADSPA_TRUE@am__objects_5 = effects/ladspa/audacity-LadspaEffect.$(OBJEXT)
@USE_LIBFLAC_TRUE@am__objects_6 = ondemand/audacity-ODDecodeFlacTask.$(OBJEXT)
@USE_LIBNYQUIST_TRUE@am__objects_7 = effects/nyquist/audacity-LoadNyquist.$(OBJEXT) \
@USE_LIBNYQUIST_TRUE@ effects/nyquist/audacity-Nyquist.$(OBJEXT)
@ -1889,9 +1885,6 @@ effects/ladspa/$(DEPDIR)/$(am__dirstamp):
effects/ladspa/audacity-LadspaEffect.$(OBJEXT): \
effects/ladspa/$(am__dirstamp) \
effects/ladspa/$(DEPDIR)/$(am__dirstamp)
effects/ladspa/audacity-LoadLadspa.$(OBJEXT): \
effects/ladspa/$(am__dirstamp) \
effects/ladspa/$(DEPDIR)/$(am__dirstamp)
ondemand/audacity-ODDecodeFlacTask.$(OBJEXT): \
ondemand/$(am__dirstamp) ondemand/$(DEPDIR)/$(am__dirstamp)
effects/nyquist/$(am__dirstamp):
@ -2146,7 +2139,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@effects/audiounits/$(DEPDIR)/audacity-AudioUnitEffect.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/audiounits/$(DEPDIR)/audacity-LoadAudioUnits.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/ladspa/$(DEPDIR)/audacity-LadspaEffect.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/lv2/$(DEPDIR)/audacity-LV2Effect.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/lv2/$(DEPDIR)/audacity-LV2PortGroup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@effects/lv2/$(DEPDIR)/audacity-LoadLV2.Po@am__quote@
@ -5783,20 +5775,6 @@ effects/ladspa/audacity-LadspaEffect.obj: effects/ladspa/LadspaEffect.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/ladspa/audacity-LadspaEffect.obj `if test -f 'effects/ladspa/LadspaEffect.cpp'; then $(CYGPATH_W) 'effects/ladspa/LadspaEffect.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/ladspa/LadspaEffect.cpp'; fi`
effects/ladspa/audacity-LoadLadspa.o: effects/ladspa/LoadLadspa.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/ladspa/audacity-LoadLadspa.o -MD -MP -MF effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Tpo -c -o effects/ladspa/audacity-LoadLadspa.o `test -f 'effects/ladspa/LoadLadspa.cpp' || echo '$(srcdir)/'`effects/ladspa/LoadLadspa.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Tpo effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/ladspa/LoadLadspa.cpp' object='effects/ladspa/audacity-LoadLadspa.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/ladspa/audacity-LoadLadspa.o `test -f 'effects/ladspa/LoadLadspa.cpp' || echo '$(srcdir)/'`effects/ladspa/LoadLadspa.cpp
effects/ladspa/audacity-LoadLadspa.obj: effects/ladspa/LoadLadspa.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/ladspa/audacity-LoadLadspa.obj -MD -MP -MF effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Tpo -c -o effects/ladspa/audacity-LoadLadspa.obj `if test -f 'effects/ladspa/LoadLadspa.cpp'; then $(CYGPATH_W) 'effects/ladspa/LoadLadspa.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/ladspa/LoadLadspa.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Tpo effects/ladspa/$(DEPDIR)/audacity-LoadLadspa.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/ladspa/LoadLadspa.cpp' object='effects/ladspa/audacity-LoadLadspa.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/ladspa/audacity-LoadLadspa.obj `if test -f 'effects/ladspa/LoadLadspa.cpp'; then $(CYGPATH_W) 'effects/ladspa/LoadLadspa.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/ladspa/LoadLadspa.cpp'; fi`
ondemand/audacity-ODDecodeFlacTask.o: ondemand/ODDecodeFlacTask.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT ondemand/audacity-ODDecodeFlacTask.o -MD -MP -MF ondemand/$(DEPDIR)/audacity-ODDecodeFlacTask.Tpo -c -o ondemand/audacity-ODDecodeFlacTask.o `test -f 'ondemand/ODDecodeFlacTask.cpp' || echo '$(srcdir)/'`ondemand/ODDecodeFlacTask.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ondemand/$(DEPDIR)/audacity-ODDecodeFlacTask.Tpo ondemand/$(DEPDIR)/audacity-ODDecodeFlacTask.Po

View File

@ -1009,10 +1009,6 @@ bool Effect::ProcessTrack(int count,
void Effect::End()
{
if (mClient)
{
mClient->Shutdown();
}
}
bool Effect::TotalProgress(double frac)
@ -1432,10 +1428,10 @@ sampleCount Effect::RealtimeProcess(int group,
// If the current group hasn't yet been seen, then we must
// add a new processor to handle this channel (sub)group
if (group > mHighGroup)
if (mCurrentGroup > mHighGroup)
{
mClient->RealtimeAddProcessor(gchans, rate);
mHighGroup = group;
mHighGroup = mCurrentGroup;
}
// Finally call the plugin to process the block

View File

@ -178,6 +178,7 @@ EffectManager::EffectManager()
mRealtimeLock.Enter();
mRealtimeEffects = NULL;
mRealtimeCount = 0;
mRealtimeActive = false;
mRealtimeSuspended = true;
mRealtimeLatency = 0;
mRealtimeLock.Leave();
@ -420,7 +421,7 @@ void EffectManager::RealtimeSetEffects(const EffectArray & effects)
}
// Must not have been in the new chain, so tell it to cleanup
if (e)
if (e && mRealtimeActive)
{
e->RealtimeFinalize();
}
@ -442,7 +443,7 @@ void EffectManager::RealtimeSetEffects(const EffectArray & effects)
}
// Must not have been in the old chain, so tell it to initialize
if (e)
if (e && mRealtimeActive)
{
e->RealtimeInitialize();
}
@ -474,6 +475,10 @@ void EffectManager::RealtimeInitialize()
// The audio thread should not be running yet, but protect anyway
RealtimeSuspend();
// RealtimeSetEffects() needs to know when we're active so it can
// initialize newly added effects
mRealtimeActive = true;
// Tell each effect to get ready for action
for (int i = 0; i < mRealtimeCount; i++)
{
@ -497,6 +502,8 @@ void EffectManager::RealtimeFinalize()
{
mRealtimeEffects[i]->RealtimeFinalize();
}
mRealtimeActive = false;
}
void EffectManager::RealtimeSuspend()

View File

@ -162,6 +162,7 @@ private:
int mRealtimeCount;
int mRealtimeLatency;
bool mRealtimeSuspended;
bool mRealtimeActive;
#endif
#ifdef EFFECT_CATEGORIES

View File

@ -62,10 +62,6 @@
#include "audiounits/LoadAudioUnits.h"
#endif
#ifdef USE_LADSPA
#include "ladspa/LoadLadspa.h"
#endif
#ifdef USE_LV2
#include "lv2/LoadLV2.h"
#endif
@ -279,12 +275,6 @@ void LoadEffects()
}
#endif
#ifdef USE_LADSPA
if (gPrefs->Read(wxT("/Ladspa/Enable"), true)) {
LoadLadspaPlugins();
}
#endif
#ifdef USE_LV2
if (gPrefs->Read(wxT("/LV2/Enable"), true)) {
LoadLV2Plugins();
@ -309,10 +299,6 @@ void UnloadEffects()
{
EffectManager::Get().UnregisterEffects();
#ifdef USE_LADSPA
UnloadLadspaPlugins();
#endif
#ifdef USE_LV2
UnloadLV2Plugins();
#endif

View File

@ -3216,7 +3216,7 @@ wxString VSTEffect::GetDescription()
// description, but most do not or they just return the name again. So,
// try to provide some sort of useful information.
mDescription = _("Audio In: ") +
wxString::Format(wxT("%d"), mAudioIns),
wxString::Format(wxT("%d"), mAudioIns) +
_(", Audio Out: ") +
wxString::Format(wxT("%d"), mAudioOuts);
@ -3290,7 +3290,13 @@ bool VSTEffect::Startup()
return false;
}
// mHost will be null when running in the subprocess
// If we have a master then there's no need to load settings since the master will feed
// us everything we need.
if (mMaster)
{
return true;
}
if (mHost)
{
mHost->GetSharedConfig(wxT("Settings"), wxT("BufferSize"), mUserBlockSize, 8192);
@ -3314,6 +3320,12 @@ bool VSTEffect::Startup()
bool VSTEffect::Shutdown()
{
// The master will save the settings.
if (mMaster)
{
return true;
}
SaveParameters(wxT("Current"));
return true;
@ -3450,37 +3462,6 @@ bool VSTEffect::RealtimeInitialize()
return ProcessInitialize();
}
bool VSTEffect::RealtimeAddProcessor(int numChannels, float sampleRate)
{
VSTEffect *slave = new VSTEffect(mPath, this);
mSlaves.Add(slave);
slave->SetChannelCount(numChannels);
slave->SetSampleRate(sampleRate);
int clen = 0;
if (mAEffect->flags & effFlagsProgramChunks)
{
void *chunk = NULL;
clen = (int) callDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
if (clen != 0)
{
slave->callDispatcher(effSetChunk, 1, clen, chunk, 0.0);
}
}
if (clen == 0)
{
for (int i = 0; i < mAEffect->numParams; i++)
{
slave->callSetParameter(i, callGetParameter(i));
}
}
return slave->RealtimeInitialize();
}
bool VSTEffect::RealtimeFinalize()
{
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
@ -3598,6 +3579,37 @@ sampleCount VSTEffect::RealtimeProcess(int group, float **inbuf, float **outbuf,
return mSlaves[group]->ProcessBlock(inbuf, outbuf, size);
}
bool VSTEffect::RealtimeAddProcessor(int numChannels, float sampleRate)
{
VSTEffect *slave = new VSTEffect(mPath, this);
mSlaves.Add(slave);
slave->SetChannelCount(numChannels);
slave->SetSampleRate(sampleRate);
int clen = 0;
if (mAEffect->flags & effFlagsProgramChunks)
{
void *chunk = NULL;
clen = (int) callDispatcher(effGetChunk, 1, 0, &chunk, 0.0);
if (clen != 0)
{
slave->callDispatcher(effSetChunk, 1, clen, chunk, 0.0);
}
}
if (clen == 0)
{
for (int i = 0; i < mAEffect->numParams; i++)
{
slave->callSetParameter(i, callGetParameter(i));
}
}
return slave->RealtimeInitialize();
}
//
// Some history...
//

File diff suppressed because it is too large Load Diff

View File

@ -15,59 +15,164 @@ class wxCheckBox;
#include <wx/dialog.h>
#include "../Effect.h"
#include "audacity/EffectInterface.h"
#include "audacity/ModuleInterface.h"
#include "audacity/PluginInterface.h"
#include "ladspa.h"
void LoadLadspaPlugins();
#define LADSPAEFFECTS_VERSION wxT("1.0.0.0");
#define LADSPAEFFECTS_FAMILY L"Ladspa"
class LadspaEffect:public Effect {
WX_DEFINE_ARRAY_PTR(LADSPA_Handle, LadspaSlaveArray);
public:
class LadspaEffectDialog;
LadspaEffect(const LADSPA_Descriptor *data,
const std::set<wxString>& categories = std::set<wxString>());
class LadspaEffect : public EffectClientInterface
{
public:
LadspaEffect(const wxString & path, int index);
virtual ~LadspaEffect();
virtual wxString GetEffectName();
// IdentInterface implementation
virtual PluginID GetID();
virtual wxString GetPath();
virtual wxString GetName();
virtual wxString GetVendor();
virtual wxString GetVersion();
virtual wxString GetDescription();
virtual std::set<wxString> GetEffectCategories();
// EffectIdentInterface implementation
virtual EffectType GetType();
virtual wxString GetFamily();
virtual bool IsInteractive();
virtual bool IsDefault();
virtual bool IsLegacy();
virtual bool IsRealtimeCapable();
virtual wxString GetEffectIdentifier();
// EffectClientInterface implementation
virtual void SetHost(EffectHostInterface *host);
virtual bool Startup();
virtual bool Shutdown();
virtual wxString GetEffectAction();
virtual int GetAudioInCount();
virtual int GetAudioOutCount();
virtual bool Init();
virtual int GetMidiInCount();
virtual int GetMidiOutCount();
virtual bool PromptUser();
virtual void SetSampleRate(sampleCount rate);
virtual sampleCount GetBlockSize(sampleCount maxBlockSize);
virtual bool Process();
virtual sampleCount GetLatency();
virtual sampleCount GetTailSize();
virtual void End();
virtual bool IsReady();
virtual bool ProcessInitialize();
virtual bool ProcessFinalize();
virtual sampleCount ProcessBlock(float **inbuf, float **outbuf, sampleCount size);
private:
bool ProcessStereo(int count, WaveTrack * left, WaveTrack *right,
sampleCount lstart, sampleCount rstart,
sampleCount len);
virtual bool RealtimeInitialize();
virtual bool RealtimeAddProcessor(int numChannels, float sampleRate);
virtual bool RealtimeFinalize();
virtual bool RealtimeSuspend();
virtual bool RealtimeResume();
virtual sampleCount RealtimeProcess(int group,
float **inbuf,
float **outbuf,
sampleCount numSamples);
virtual bool ShowInterface(void *parent);
private:
// LadspaEffect implementation
bool Load();
void Unload();
void LoadParameters(const wxString & group);
void SaveParameters(const wxString & group);
LADSPA_Handle InitInstance(float sampleRate);
void FreeInstance(LADSPA_Handle handle);
private:
wxString mPath;
int mIndex;
EffectHostInterface *mHost;
wxDynamicLibrary mLib;
const LADSPA_Descriptor *mData;
wxString pluginName;
const LADSPA_Descriptor *mData;
sampleCount mBlockSize;
float **fInBuffer;
float **fOutBuffer;
unsigned long inputs;
unsigned long outputs;
unsigned long numInputControls;
unsigned long *inputPorts;
unsigned long *outputPorts;
float *inputControls;
float *outputControls;
int mainRate;
bool mReady;
std::set<wxString> mCategories;
LADSPA_Handle mMaster;
sampleCount mSampleRate;
sampleCount mBlockSize;
sampleCount mUserBlockSize;
bool mInteractive;
int mAudioIns;
unsigned long *mInputPorts;
int mAudioOuts;
unsigned long *mOutputPorts;
int mNumInputControls;
float *mInputControls;
float *mOutputControls;
// Realtime processing
LadspaSlaveArray mSlaves;
wxArrayInt mSlaveChannels;
LadspaEffectDialog *mDlg;
friend class LadspaEffectDialog;
friend class LadspaEffectsModule;
};
class LadspaEffectDialog:public wxDialog {
class LadspaEffectsModule : public ModuleInterface
{
public:
LadspaEffectsModule(ModuleManagerInterface *moduleManager, const wxString *path);
virtual ~LadspaEffectsModule();
// IdentInterface implementatino
virtual wxString GetID();
virtual wxString GetPath();
virtual wxString GetName();
virtual wxString GetVendor();
virtual wxString GetVersion();
virtual wxString GetDescription();
// ModuleInterface implementation
virtual bool Initialize();
virtual void Terminate();
virtual bool AutoRegisterPlugins(PluginManagerInterface & pm);
virtual wxArrayString FindPlugins(PluginManagerInterface & pm);
virtual bool RegisterPlugin(PluginManagerInterface & pm, const wxString & path);
virtual void *CreateInstance(const PluginID & ID, const wxString & path);
// LadspaEffectModule implementation
static void Check(const wchar_t *path);
private:
ModuleManagerInterface *mModMan;
wxString mPath;
};
class LadspaEffectDialog : public wxDialog
{
DECLARE_DYNAMIC_CLASS(LadspaEffectDialog)
public:
@ -75,7 +180,7 @@ class LadspaEffectDialog:public wxDialog {
wxWindow * parent,
const LADSPA_Descriptor *data,
float *inputControls,
int sampleRate,
sampleCount sampleRate,
double length);
~LadspaEffectDialog();
@ -83,16 +188,20 @@ class LadspaEffectDialog:public wxDialog {
void OnCheckBox(wxCommandEvent & event);
void OnSlider(wxCommandEvent & event);
void OnTextCtrl(wxCommandEvent & event);
void OnOK(wxCommandEvent & event);
void OnCancel(wxCommandEvent & event);
void OnPreview(wxCommandEvent & event);
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
void OnApply(wxCommandEvent & evt);
#else
void OnOk(wxCommandEvent & evt);
void OnCancel(wxCommandEvent & evt);
void OnPreview(wxCommandEvent & evt);
#endif
void ControlSetFocus(wxFocusEvent & event);
double GetLength();
DECLARE_EVENT_TABLE()
private:
private:
void HandleText();
void ConnectFocus(wxControl *c);
void DisconnectFocus(wxControl *c);
@ -108,7 +217,7 @@ class LadspaEffectDialog:public wxDialog {
wxCheckBox **toggles;
unsigned long *ports;
unsigned long numParams;
float *inputControls;
float *mInputControls;
LadspaEffect *effect;
wxTextCtrl *mSeconds;
};

View File

@ -1,327 +0,0 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadLadspa.cpp
Dominic Mazzoni
From the ladspa docs:
"To allow multiple hosts to
share plugin types, hosts may wish to check for environment
variable LADSPA_PATH. If present, this should contain a
colon-separated path indicating directories that should be searched
(in order) when loading plugin types."
**********************************************************************/
#define descriptorFnName "ladspa_descriptor"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <wx/dynlib.h>
#include <wx/filename.h>
#include <wx/hashmap.h>
#include <wx/list.h>
#include <wx/log.h>
#include <wx/string.h>
#include "ladspa.h"
#include "../../Audacity.h"
#include "../../AudacityApp.h"
#include "../../Experimental.h"
#include "../../Internat.h"
#include "../EffectManager.h"
#include "LadspaEffect.h"
#include "LoadLadspa.h"
#if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES)
#include <lrdf.h>
#endif
WX_DEFINE_ARRAY(wxDynamicLibrary*, DL_Array);
static DL_Array ladspa_dls;
#if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES)
#define LADSPA(S) wxT("http://ladspa.org/ontology#") wxT(S)
#define LV2(S) wxT("http://lv2plug.in/ns/lv2core#") wxT(S)
static std::map<wxString, wxString> gCategoryMap;
static std::multimap<unsigned long, wxString> gPluginCategories;
/** This function initialises the data structure that maps common LRDF
category URIs to LV2 or internal Audacity category URIs. */
static void InitCategoryMap()
{
gCategoryMap[LADSPA("UtilityPlugin")] = LV2("UtilityPlugin");
gCategoryMap[LADSPA("GeneratorPlugin")] = LV2("GeneratorPlugin");
gCategoryMap[LADSPA("SimulatorPlugin")] = LV2("SimulatorPlugin");
gCategoryMap[LADSPA("OscillatorPlugin")] = LV2("OscillatorPlugin");
gCategoryMap[LADSPA("TimePlugin")] = LV2("DelayPlugin");
gCategoryMap[LADSPA("DelayPlugin")] = LV2("DelayPlugin");
gCategoryMap[LADSPA("PhaserPlugin")] = LV2("PhaserPlugin");
gCategoryMap[LADSPA("FlangerPlugin")] = LV2("FlangerPlugin");
gCategoryMap[LADSPA("ChorusPlugin")] = LV2("ChorusPlugin");
gCategoryMap[LADSPA("ReverbPlugin")] = LV2("ReverbPlugin");
gCategoryMap[LADSPA("FrequencyPlugin")] = LV2("SpectralPlugin");
gCategoryMap[LADSPA("FrequencyMeterPlugin")] = LV2("AnalyserPlugin");
gCategoryMap[LADSPA("FilterPlugin")] = LV2("FilterPlugin");
gCategoryMap[LADSPA("LowpassPlugin")] = LV2("LowpassPlugin");
gCategoryMap[LADSPA("HighpassPlugin")] = LV2("HighpassPlugin");
gCategoryMap[LADSPA("BandpassPlugin")] = LV2("BandpassPlugin");
gCategoryMap[LADSPA("CombPlugin")] = LV2("CombPlugin");
gCategoryMap[LADSPA("AllpassPlugin")] = LV2("AllpassPlugin");
gCategoryMap[LADSPA("EQPlugin")] = LV2("EQPlugin");
gCategoryMap[LADSPA("ParaEQPlugin")] = LV2("ParaEQPlugin");
gCategoryMap[LADSPA("MultiEQPlugin")] = LV2("MultiEQPlugin");
gCategoryMap[LADSPA("AmplitudePlugin")] = LV2("AmplifierPlugin");
gCategoryMap[LADSPA("PitchPlugin")] = LV2("PitchPlugin");
gCategoryMap[LADSPA("AmplifierPlugin")] = LV2("AmplifierPlugin");
gCategoryMap[LADSPA("WaveshaperPlugin")] = LV2("WaveshaperPlugin");
gCategoryMap[LADSPA("ModulatorPlugin")] = LV2("ModulatorPlugin");
gCategoryMap[LADSPA("DistortionPlugin")] = LV2("DistortionPlugin");
gCategoryMap[LADSPA("DynamicsPlugin")] = LV2("DynamicsPlugin");
gCategoryMap[LADSPA("CompressorPlugin")] = LV2("CompressorPlugin");
gCategoryMap[LADSPA("ExpanderPlugin")] = LV2("ExpanderPlugin");
gCategoryMap[LADSPA("LimiterPlugin")] = LV2("LimiterPlugin");
gCategoryMap[LADSPA("GatePlugin")] = LV2("GatePlugin");
// This isn't in ladspa.rdfs, it's added by the swh-plugins -
// we add it here to avoid having multiple "Spectral" categories
gCategoryMap[LADSPA("SpectralPlugin")] = LV2("SpectralPlugin");
}
/** This function maps a LADSPA category URI to the category URIs used
by Audacity (LV2 ones). If there is no known mapping for the
given LADSPA category URI it is returned unchanged. */
static wxString MapCategoryUri(const wxString& ladspaCategory)
{
std::map<wxString, wxString>::const_iterator iter;
iter = gCategoryMap.find(ladspaCategory);
if (iter != gCategoryMap.end())
return iter->second;
return ladspaCategory;
}
#endif
static void LoadLadspaEffect(wxSortedArrayString &uniq, wxString fname,
DL_Array &dls)
{
wxLogNull logNo;
LADSPA_Descriptor_Function mainFn = NULL;
// Since we now have builtin VST support, ignore the VST bridge as it
// causes duplicate menu entries to appear.
wxFileName f(fname);
if (f.GetName().CmpNoCase(wxT("vst-bridge")) == 0) {
return;
}
// As a courtesy to some plug-ins that might be bridges to
// open other plug-ins, we set the current working
// directory to be the plug-in's directory.
wxString saveOldCWD = ::wxGetCwd();
wxString prefix = ::wxPathOnly(fname);
::wxSetWorkingDirectory(prefix);
wxDynamicLibrary* pDLL = new wxDynamicLibrary();
dls.push_back(pDLL);
if (pDLL && pDLL->Load(fname, wxDL_LAZY)) {
mainFn = (LADSPA_Descriptor_Function)(pDLL->GetSymbol(wxT(descriptorFnName)));
}
if (mainFn) {
int index = 0;
const LADSPA_Descriptor *data;
data = mainFn(index);
while(data) {
wxString uniqid = wxString::Format(wxT("%08x-%s"), (int)data->UniqueID, LAT1CTOWX(data->Label).c_str());
if (uniq.Index(uniqid) == wxNOT_FOUND) {
uniq.Add(uniqid);
std::set<wxString> categories;
#if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES)
std::multimap<unsigned long, wxString>::const_iterator iter;
iter = gPluginCategories.lower_bound(data->UniqueID);
for ( ; (iter != gPluginCategories.end() &&
iter->first == data->UniqueID); ++iter)
categories.insert(iter->second);
#endif
LadspaEffect *effect = new LadspaEffect(data, categories);
EffectManager::Get().RegisterEffect(effect);
}
// Get next plugin
index++;
data = mainFn(index);
}
}
::wxSetWorkingDirectory(saveOldCWD);
}
void LoadLadspaPlugins()
{
wxArrayString audacityPathList = wxGetApp().audacityPathList;
wxArrayString pathList;
wxArrayString files;
wxSortedArrayString uniq;
wxString pathVar;
unsigned int i;
#if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES)
EffectManager& em = EffectManager::Get();
wxArrayString rdfPathList;
wxString rdfPathVar;
wxArrayString rdfFiles;
InitCategoryMap();
lrdf_init();
rdfPathVar = wxGetenv(wxT("LADSPA_RDF_PATH"));
if (rdfPathVar != wxT(""))
wxGetApp().AddMultiPathsToPathList(rdfPathVar, rdfPathList);
#ifdef __WXGTK__
wxGetApp().AddUniquePathToPathList(wxT("/usr/share/ladspa/rdf"),
rdfPathList);
wxGetApp().AddUniquePathToPathList(wxT("/usr/local/share/ladspa/rdf"),
rdfPathList);
#endif
#ifdef __WXMAC__
wxGetApp().AddUniquePathToPathList(wxT("/usr/share/ladspa/rdf"),
rdfPathList);
// XXX Maybe other Mac paths here?
#endif
#ifdef __WXMSW__
//wxGetApp().AddUniquePathToPathList(wxT("WINDOWS LRDF PATH"),
// rdfPathList);
// XXX Other Windows paths here.
#endif
// Add the Audacity paths so we get ladspa.rdfs if we are using a local
// liblrdf
for(i=0; i<audacityPathList.GetCount(); i++) {
wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
wxGetApp().AddUniquePathToPathList(prefix + wxT("rdf"),
rdfPathList);
}
wxGetApp().FindFilesInPathList(wxT("*.rdf"), rdfPathList, rdfFiles);
wxGetApp().FindFilesInPathList(wxT("*.rdfs"), rdfPathList, rdfFiles);
for(size_t i = 0; i < rdfFiles.GetCount(); ++i) {
wxString fileUri(wxT("file://"));
fileUri += rdfFiles[i];
lrdf_read_file(fileUri.mb_str(wxConvUTF8));
}
// Add all plugin categories found by LRDF
lrdf_uris* cats =
lrdf_get_all_subclasses("http://ladspa.org/ontology#Plugin");
if (cats) {
// Add the categories and find the plugins belonging to them
for (size_t i = 0; i < cats->count; ++i) {
char* label = lrdf_get_label(cats->items[i]);
if (!label)
continue;
wxString uri = MapCategoryUri(wxString::FromAscii(cats->items[i]));
em.AddCategory(uri, wxString::FromUTF8(label));
std::free(label);
lrdf_uris* plugs = lrdf_get_instances(cats->items[i]);
if (plugs) {
for (size_t j = 0; j < plugs->count; ++j) {
unsigned long uid = lrdf_get_uid(plugs->items[j]);
gPluginCategories.insert(std::make_pair(uid, uri));
}
lrdf_free_uris(plugs);
}
}
// And their relationships
for (size_t i = 0; i < cats->count; ++i) {
EffectCategory* p =
em.LookupCategory(MapCategoryUri(wxString::FromAscii(cats->
items[i])));
if (!p)
continue;
lrdf_uris* subs = lrdf_get_subclasses(cats->items[i]);
if (subs) {
for (size_t j = 0; j < subs->count; ++j) {
EffectCategory* c =
em.LookupCategory(MapCategoryUri(wxString::FromAscii(subs->items[j])));
if (c)
em.AddCategoryParent(c, p);
}
lrdf_free_uris(subs);
}
}
lrdf_free_uris(cats);
}
#endif
pathVar = wxGetenv(wxT("LADSPA_PATH"));
if (pathVar != wxT(""))
wxGetApp().AddMultiPathsToPathList(pathVar, pathList);
#ifdef __WXGTK__
wxGetApp().AddUniquePathToPathList(wxT("~/.ladspa"), pathList);
wxGetApp().AddUniquePathToPathList(wxT("/usr/local/lib/ladspa"), pathList);
wxGetApp().AddUniquePathToPathList(wxT("/usr/lib/ladspa"), pathList);
wxGetApp().AddUniquePathToPathList(wxT(LIBDIR) wxT("/ladspa"), pathList);
#endif
#ifdef __WXMAC__
wxGetApp().AddUniquePathToPathList(wxT("~/Library/Audio/Plug-Ins/LADSPA"), pathList);
wxGetApp().AddUniquePathToPathList(wxT("/Library/Audio/Plug-Ins/LADSPA"), pathList);
#endif
for(i=0; i<audacityPathList.GetCount(); i++) {
wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
wxGetApp().AddUniquePathToPathList(prefix + wxT("ladspa"),
pathList);
wxGetApp().AddUniquePathToPathList(prefix + wxT("plugins"),
pathList);
wxGetApp().AddUniquePathToPathList(prefix + wxT("plug-ins"),
pathList);
}
#ifdef __WXMSW__
wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);
#else
wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
#endif
for(i=0; i<files.GetCount(); i++)
LoadLadspaEffect(uniq, files[i], ladspa_dls);
}
void UnloadLadspaPlugins()
{
int count=ladspa_dls.GetCount();
for (int i=0; i<count; i++)
{
delete ladspa_dls[i];
}
}

View File

@ -1,13 +0,0 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadLadspa.h
Dominic Mazzoni
**********************************************************************/
void LoadLadspaPlugins();
void UnloadLadspaPlugins();

View File

@ -409,7 +409,7 @@ void AButton::Click()
{
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
event.SetEventObject(this);
GetEventHandler()->AddPendingEvent(event);
GetEventHandler()->ProcessEvent(event);
}
void AButton::SetShift(bool shift)

View File

@ -467,7 +467,6 @@
<ClCompile Include="..\..\..\src\blockfile\SilentBlockFile.cpp" />
<ClCompile Include="..\..\..\src\blockfile\SimpleBlockFile.cpp" />
<ClCompile Include="..\..\..\src\effects\ladspa\LadspaEffect.cpp" />
<ClCompile Include="..\..\..\src\effects\ladspa\LoadLadspa.cpp" />
<ClCompile Include="..\..\..\src\toolbars\ControlToolBar.cpp" />
<ClCompile Include="..\..\..\src\toolbars\DeviceToolBar.cpp" />
<ClCompile Include="..\..\..\src\toolbars\EditToolBar.cpp" />
@ -741,7 +740,6 @@
<ClInclude Include="..\..\..\src\blockfile\SimpleBlockFile.h" />
<ClInclude Include="..\..\..\src\effects\ladspa\ladspa.h" />
<ClInclude Include="..\..\..\src\effects\ladspa\LadspaEffect.h" />
<ClInclude Include="..\..\..\src\effects\ladspa\LoadLadspa.h" />
<ClInclude Include="..\..\..\src\toolbars\ControlToolBar.h" />
<ClInclude Include="..\..\..\src\toolbars\DeviceToolBar.h" />
<ClInclude Include="..\..\..\src\toolbars\EditToolBar.h" />

View File

@ -729,9 +729,6 @@
<ClCompile Include="..\..\..\src\effects\ladspa\LadspaEffect.cpp">
<Filter>src/effects/ladspa</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\effects\ladspa\LoadLadspa.cpp">
<Filter>src/effects/ladspa</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\toolbars\ControlToolBar.cpp">
<Filter>src/toolbars</Filter>
</ClCompile>
@ -1526,9 +1523,6 @@
<ClInclude Include="..\..\..\src\effects\ladspa\LadspaEffect.h">
<Filter>src/effects/ladspa</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\effects\ladspa\LoadLadspa.h">
<Filter>src/effects/ladspa</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\toolbars\ControlToolBar.h">
<Filter>src/toolbars</Filter>
</ClInclude>