Free EffectManager and EffectRack from the big s.c.c. ...
... though in a small cycle with each other, by moving RealtimeEffectManager to new files, which remain in the big component. Net loss of 1, the big component now has 27 files
This commit is contained in:
parent
04a3ed9d04
commit
ab5a98003a
|
@ -427,6 +427,8 @@ src/effects/Paulstretch.cpp
|
|||
src/effects/Paulstretch.h
|
||||
src/effects/Phaser.cpp
|
||||
src/effects/Phaser.h
|
||||
src/effects/RealtimeEffectManager.cpp
|
||||
src/effects/RealtimeEffectManager.h
|
||||
src/effects/Repair.cpp
|
||||
src/effects/Repair.h
|
||||
src/effects/Repeat.cpp
|
||||
|
|
|
@ -1235,6 +1235,7 @@
|
|||
5E19D655217D51190024D0B1 /* PluginMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E19D64C217D51190024D0B1 /* PluginMenus.cpp */; };
|
||||
5E19F59922A9665500E3F88E /* AutoRecoveryDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E19F59722A9665500E3F88E /* AutoRecoveryDialog.cpp */; };
|
||||
5E2A19941EED688500217B58 /* SelectionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2A19921EED688500217B58 /* SelectionState.cpp */; };
|
||||
5E2B3E6222BF9621005042E1 /* RealtimeEffectManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2B3E6022BF9621005042E1 /* RealtimeEffectManager.cpp */; };
|
||||
5E2BF3852193A2A500995694 /* TrackView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2BF3832193A2A500995694 /* TrackView.cpp */; };
|
||||
5E2BF3882193A2BD00995694 /* TimeTrackView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2BF3862193A2BD00995694 /* TimeTrackView.cpp */; };
|
||||
5E2BF38B2193A2E400995694 /* WaveTrackView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2BF3892193A2E400995694 /* WaveTrackView.cpp */; };
|
||||
|
@ -3237,6 +3238,8 @@
|
|||
5E19F59822A9665500E3F88E /* AutoRecoveryDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoRecoveryDialog.h; sourceTree = "<group>"; };
|
||||
5E2A19921EED688500217B58 /* SelectionState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionState.cpp; sourceTree = "<group>"; };
|
||||
5E2A19931EED688500217B58 /* SelectionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionState.h; sourceTree = "<group>"; };
|
||||
5E2B3E6022BF9621005042E1 /* RealtimeEffectManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RealtimeEffectManager.cpp; sourceTree = "<group>"; };
|
||||
5E2B3E6122BF9621005042E1 /* RealtimeEffectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RealtimeEffectManager.h; sourceTree = "<group>"; };
|
||||
5E2BF3832193A2A500995694 /* TrackView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackView.cpp; sourceTree = "<group>"; };
|
||||
5E2BF3842193A2A500995694 /* TrackView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackView.h; sourceTree = "<group>"; };
|
||||
5E2BF3862193A2BD00995694 /* TimeTrackView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeTrackView.cpp; sourceTree = "<group>"; };
|
||||
|
@ -4716,10 +4719,12 @@
|
|||
1790B03209883BFD008A330A /* Normalize.cpp */,
|
||||
1790B03309883BFD008A330A /* Normalize.h */,
|
||||
1790B03409883BFD008A330A /* nyquist */,
|
||||
1790B03A09883BFD008A330A /* Phaser.cpp */,
|
||||
1790B03B09883BFD008A330A /* Phaser.h */,
|
||||
EDF3B7AF1588C0D50032D35F /* Paulstretch.cpp */,
|
||||
EDF3B7AE1588C0D50032D35F /* Paulstretch.h */,
|
||||
1790B03A09883BFD008A330A /* Phaser.cpp */,
|
||||
1790B03B09883BFD008A330A /* Phaser.h */,
|
||||
5E2B3E6022BF9621005042E1 /* RealtimeEffectManager.cpp */,
|
||||
5E2B3E6122BF9621005042E1 /* RealtimeEffectManager.h */,
|
||||
28EBA7FA0A78FADE00C8BB1F /* Repair.cpp */,
|
||||
28EBA7FB0A78FADE00C8BB1F /* Repair.h */,
|
||||
1790B03E09883BFD008A330A /* Repeat.cpp */,
|
||||
|
@ -8477,6 +8482,7 @@
|
|||
1790B19009883BFD008A330A /* Sequence.cpp in Sources */,
|
||||
5E36A0AF217FA2430068E082 /* ViewMenus.cpp in Sources */,
|
||||
1790B19109883BFD008A330A /* Shuttle.cpp in Sources */,
|
||||
5E2B3E6222BF9621005042E1 /* RealtimeEffectManager.cpp in Sources */,
|
||||
1790B19209883BFD008A330A /* Spectrum.cpp in Sources */,
|
||||
1790B19309883BFD008A330A /* Tags.cpp in Sources */,
|
||||
1790B19409883BFD008A330A /* TimeTrack.cpp in Sources */,
|
||||
|
|
|
@ -459,7 +459,7 @@ time warp info and AudioIOListener and whether the playback is looped.
|
|||
#include "WaveTrack.h"
|
||||
#include "AutoRecovery.h"
|
||||
|
||||
#include "effects/EffectManager.h"
|
||||
#include "effects/RealtimeEffectManager.h"
|
||||
#include "prefs/QualityPrefs.h"
|
||||
#include "prefs/RecordingPrefs.h"
|
||||
#include "toolbars/ControlToolBar.h"
|
||||
|
|
|
@ -454,6 +454,8 @@ audacity_SOURCES = \
|
|||
effects/Paulstretch.h \
|
||||
effects/Phaser.cpp \
|
||||
effects/Phaser.h \
|
||||
effects/RealtimeEffectManager.cpp \
|
||||
effects/RealtimeEffectManager.h \
|
||||
effects/Repair.cpp \
|
||||
effects/Repair.h \
|
||||
effects/Repeat.cpp \
|
||||
|
|
|
@ -412,23 +412,25 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
|
|||
effects/NoiseRemoval.h effects/Normalize.cpp \
|
||||
effects/Normalize.h effects/Paulstretch.cpp \
|
||||
effects/Paulstretch.h effects/Phaser.cpp effects/Phaser.h \
|
||||
effects/Repair.cpp effects/Repair.h effects/Repeat.cpp \
|
||||
effects/Repeat.h effects/Reverb.cpp effects/Reverb.h \
|
||||
effects/Reverb_libSoX.h effects/Reverse.cpp effects/Reverse.h \
|
||||
effects/SBSMSEffect.cpp effects/SBSMSEffect.h \
|
||||
effects/ScienFilter.cpp effects/ScienFilter.h \
|
||||
effects/Silence.cpp effects/Silence.h effects/SimpleMono.cpp \
|
||||
effects/SimpleMono.h effects/SoundTouchEffect.cpp \
|
||||
effects/SoundTouchEffect.h effects/StereoToMono.cpp \
|
||||
effects/StereoToMono.h effects/TimeScale.cpp \
|
||||
effects/TimeScale.h effects/TimeWarper.cpp \
|
||||
effects/TimeWarper.h effects/ToneGen.cpp effects/ToneGen.h \
|
||||
effects/TruncSilence.cpp effects/TruncSilence.h \
|
||||
effects/TwoPassSimpleMono.cpp effects/TwoPassSimpleMono.h \
|
||||
effects/Wahwah.cpp effects/Wahwah.h export/Export.cpp \
|
||||
export/Export.h export/ExportCL.cpp export/ExportCL.h \
|
||||
export/ExportFLAC.cpp export/ExportFLAC.h export/ExportMP2.cpp \
|
||||
export/ExportMP2.h export/ExportMP3.cpp export/ExportMP3.h \
|
||||
effects/RealtimeEffectManager.cpp \
|
||||
effects/RealtimeEffectManager.h effects/Repair.cpp \
|
||||
effects/Repair.h effects/Repeat.cpp effects/Repeat.h \
|
||||
effects/Reverb.cpp effects/Reverb.h effects/Reverb_libSoX.h \
|
||||
effects/Reverse.cpp effects/Reverse.h effects/SBSMSEffect.cpp \
|
||||
effects/SBSMSEffect.h effects/ScienFilter.cpp \
|
||||
effects/ScienFilter.h effects/Silence.cpp effects/Silence.h \
|
||||
effects/SimpleMono.cpp effects/SimpleMono.h \
|
||||
effects/SoundTouchEffect.cpp effects/SoundTouchEffect.h \
|
||||
effects/StereoToMono.cpp effects/StereoToMono.h \
|
||||
effects/TimeScale.cpp effects/TimeScale.h \
|
||||
effects/TimeWarper.cpp effects/TimeWarper.h \
|
||||
effects/ToneGen.cpp effects/ToneGen.h effects/TruncSilence.cpp \
|
||||
effects/TruncSilence.h effects/TwoPassSimpleMono.cpp \
|
||||
effects/TwoPassSimpleMono.h effects/Wahwah.cpp \
|
||||
effects/Wahwah.h export/Export.cpp export/Export.h \
|
||||
export/ExportCL.cpp export/ExportCL.h export/ExportFLAC.cpp \
|
||||
export/ExportFLAC.h export/ExportMP2.cpp export/ExportMP2.h \
|
||||
export/ExportMP3.cpp export/ExportMP3.h \
|
||||
export/ExportMultiple.cpp export/ExportMultiple.h \
|
||||
export/ExportOGG.cpp export/ExportOGG.h export/ExportPCM.cpp \
|
||||
export/ExportPCM.h import/Import.cpp import/Import.h \
|
||||
|
@ -776,6 +778,7 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \
|
|||
effects/audacity-Normalize.$(OBJEXT) \
|
||||
effects/audacity-Paulstretch.$(OBJEXT) \
|
||||
effects/audacity-Phaser.$(OBJEXT) \
|
||||
effects/audacity-RealtimeEffectManager.$(OBJEXT) \
|
||||
effects/audacity-Repair.$(OBJEXT) \
|
||||
effects/audacity-Repeat.$(OBJEXT) \
|
||||
effects/audacity-Reverb.$(OBJEXT) \
|
||||
|
@ -1510,23 +1513,25 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \
|
|||
effects/NoiseRemoval.h effects/Normalize.cpp \
|
||||
effects/Normalize.h effects/Paulstretch.cpp \
|
||||
effects/Paulstretch.h effects/Phaser.cpp effects/Phaser.h \
|
||||
effects/Repair.cpp effects/Repair.h effects/Repeat.cpp \
|
||||
effects/Repeat.h effects/Reverb.cpp effects/Reverb.h \
|
||||
effects/Reverb_libSoX.h effects/Reverse.cpp effects/Reverse.h \
|
||||
effects/SBSMSEffect.cpp effects/SBSMSEffect.h \
|
||||
effects/ScienFilter.cpp effects/ScienFilter.h \
|
||||
effects/Silence.cpp effects/Silence.h effects/SimpleMono.cpp \
|
||||
effects/SimpleMono.h effects/SoundTouchEffect.cpp \
|
||||
effects/SoundTouchEffect.h effects/StereoToMono.cpp \
|
||||
effects/StereoToMono.h effects/TimeScale.cpp \
|
||||
effects/TimeScale.h effects/TimeWarper.cpp \
|
||||
effects/TimeWarper.h effects/ToneGen.cpp effects/ToneGen.h \
|
||||
effects/TruncSilence.cpp effects/TruncSilence.h \
|
||||
effects/TwoPassSimpleMono.cpp effects/TwoPassSimpleMono.h \
|
||||
effects/Wahwah.cpp effects/Wahwah.h export/Export.cpp \
|
||||
export/Export.h export/ExportCL.cpp export/ExportCL.h \
|
||||
export/ExportFLAC.cpp export/ExportFLAC.h export/ExportMP2.cpp \
|
||||
export/ExportMP2.h export/ExportMP3.cpp export/ExportMP3.h \
|
||||
effects/RealtimeEffectManager.cpp \
|
||||
effects/RealtimeEffectManager.h effects/Repair.cpp \
|
||||
effects/Repair.h effects/Repeat.cpp effects/Repeat.h \
|
||||
effects/Reverb.cpp effects/Reverb.h effects/Reverb_libSoX.h \
|
||||
effects/Reverse.cpp effects/Reverse.h effects/SBSMSEffect.cpp \
|
||||
effects/SBSMSEffect.h effects/ScienFilter.cpp \
|
||||
effects/ScienFilter.h effects/Silence.cpp effects/Silence.h \
|
||||
effects/SimpleMono.cpp effects/SimpleMono.h \
|
||||
effects/SoundTouchEffect.cpp effects/SoundTouchEffect.h \
|
||||
effects/StereoToMono.cpp effects/StereoToMono.h \
|
||||
effects/TimeScale.cpp effects/TimeScale.h \
|
||||
effects/TimeWarper.cpp effects/TimeWarper.h \
|
||||
effects/ToneGen.cpp effects/ToneGen.h effects/TruncSilence.cpp \
|
||||
effects/TruncSilence.h effects/TwoPassSimpleMono.cpp \
|
||||
effects/TwoPassSimpleMono.h effects/Wahwah.cpp \
|
||||
effects/Wahwah.h export/Export.cpp export/Export.h \
|
||||
export/ExportCL.cpp export/ExportCL.h export/ExportFLAC.cpp \
|
||||
export/ExportFLAC.h export/ExportMP2.cpp export/ExportMP2.h \
|
||||
export/ExportMP3.cpp export/ExportMP3.h \
|
||||
export/ExportMultiple.cpp export/ExportMultiple.h \
|
||||
export/ExportOGG.cpp export/ExportOGG.h export/ExportPCM.cpp \
|
||||
export/ExportPCM.h import/Import.cpp import/Import.h \
|
||||
|
@ -2009,6 +2014,8 @@ effects/audacity-Paulstretch.$(OBJEXT): effects/$(am__dirstamp) \
|
|||
effects/$(DEPDIR)/$(am__dirstamp)
|
||||
effects/audacity-Phaser.$(OBJEXT): effects/$(am__dirstamp) \
|
||||
effects/$(DEPDIR)/$(am__dirstamp)
|
||||
effects/audacity-RealtimeEffectManager.$(OBJEXT): \
|
||||
effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
|
||||
effects/audacity-Repair.$(OBJEXT): effects/$(am__dirstamp) \
|
||||
effects/$(DEPDIR)/$(am__dirstamp)
|
||||
effects/audacity-Repeat.$(OBJEXT): effects/$(am__dirstamp) \
|
||||
|
@ -2760,6 +2767,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Normalize.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Paulstretch.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Phaser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-RealtimeEffectManager.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Repair.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Repeat.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Reverb.Po@am__quote@
|
||||
|
@ -5639,6 +5647,20 @@ effects/audacity-Phaser.obj: effects/Phaser.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/audacity-Phaser.obj `if test -f 'effects/Phaser.cpp'; then $(CYGPATH_W) 'effects/Phaser.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/Phaser.cpp'; fi`
|
||||
|
||||
effects/audacity-RealtimeEffectManager.o: effects/RealtimeEffectManager.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-RealtimeEffectManager.o -MD -MP -MF effects/$(DEPDIR)/audacity-RealtimeEffectManager.Tpo -c -o effects/audacity-RealtimeEffectManager.o `test -f 'effects/RealtimeEffectManager.cpp' || echo '$(srcdir)/'`effects/RealtimeEffectManager.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-RealtimeEffectManager.Tpo effects/$(DEPDIR)/audacity-RealtimeEffectManager.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/RealtimeEffectManager.cpp' object='effects/audacity-RealtimeEffectManager.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/audacity-RealtimeEffectManager.o `test -f 'effects/RealtimeEffectManager.cpp' || echo '$(srcdir)/'`effects/RealtimeEffectManager.cpp
|
||||
|
||||
effects/audacity-RealtimeEffectManager.obj: effects/RealtimeEffectManager.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-RealtimeEffectManager.obj -MD -MP -MF effects/$(DEPDIR)/audacity-RealtimeEffectManager.Tpo -c -o effects/audacity-RealtimeEffectManager.obj `if test -f 'effects/RealtimeEffectManager.cpp'; then $(CYGPATH_W) 'effects/RealtimeEffectManager.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/RealtimeEffectManager.cpp'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-RealtimeEffectManager.Tpo effects/$(DEPDIR)/audacity-RealtimeEffectManager.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/RealtimeEffectManager.cpp' object='effects/audacity-RealtimeEffectManager.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/audacity-RealtimeEffectManager.obj `if test -f 'effects/RealtimeEffectManager.cpp'; then $(CYGPATH_W) 'effects/RealtimeEffectManager.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/RealtimeEffectManager.cpp'; fi`
|
||||
|
||||
effects/audacity-Repair.o: effects/Repair.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-Repair.o -MD -MP -MF effects/$(DEPDIR)/audacity-Repair.Tpo -c -o effects/audacity-Repair.o `test -f 'effects/Repair.cpp' || echo '$(srcdir)/'`effects/Repair.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-Repair.Tpo effects/$(DEPDIR)/audacity-Repair.Po
|
||||
|
|
|
@ -47,7 +47,7 @@ greater use in future.
|
|||
|
||||
#include "audacity/ConfigInterface.h"
|
||||
|
||||
#include "EffectManager.h"
|
||||
#include "RealtimeEffectManager.h"
|
||||
#include "../AudioIO.h"
|
||||
#include "../CommonCommandFlags.h"
|
||||
#include "../LabelTrack.h"
|
||||
|
|
|
@ -52,25 +52,6 @@ EffectManager & EffectManager::Get()
|
|||
return em;
|
||||
}
|
||||
|
||||
RealtimeEffectManager & RealtimeEffectManager::Get()
|
||||
{
|
||||
static RealtimeEffectManager rem;
|
||||
return rem;
|
||||
}
|
||||
|
||||
RealtimeEffectManager::RealtimeEffectManager()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
mRealtimeActive = false;
|
||||
mRealtimeSuspended = true;
|
||||
mRealtimeLatency = 0;
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
RealtimeEffectManager::~RealtimeEffectManager()
|
||||
{
|
||||
}
|
||||
|
||||
EffectManager::EffectManager()
|
||||
{
|
||||
mSkipStateFlag = false;
|
||||
|
@ -526,337 +507,8 @@ void EffectManager::ShowRack()
|
|||
{
|
||||
GetRack()->Show(!GetRack()->IsShown());
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeSetEffects(const EffectArray & effects)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
// Tell any effects no longer in the chain to clean up
|
||||
for (auto e: mRealtimeEffects)
|
||||
{
|
||||
// Scan the NEW chain for the effect
|
||||
for (auto e1: effects)
|
||||
{
|
||||
// Found it so we're done
|
||||
if (e == e1)
|
||||
{
|
||||
e = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Must not have been in the NEW chain, so tell it to cleanup
|
||||
if (e && mRealtimeActive)
|
||||
{
|
||||
e->RealtimeFinalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Tell any NEW effects to get ready
|
||||
for (auto e : effects)
|
||||
{
|
||||
// Scan the old chain for the effect
|
||||
for (auto e1 : mRealtimeEffects)
|
||||
{
|
||||
// Found it so tell effect to get ready
|
||||
if (e == e1)
|
||||
{
|
||||
e = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Must not have been in the old chain, so tell it to initialize
|
||||
if (e && mRealtimeActive)
|
||||
{
|
||||
e->RealtimeInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of the old chain
|
||||
// And install the NEW one
|
||||
mRealtimeEffects = effects;
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RealtimeEffectManager::RealtimeIsActive()
|
||||
{
|
||||
return mRealtimeEffects.size() != 0;
|
||||
}
|
||||
|
||||
bool RealtimeEffectManager::RealtimeIsSuspended()
|
||||
{
|
||||
return mRealtimeSuspended;
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeAddEffect(Effect *effect)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
// Initialize effect if realtime is already active
|
||||
if (mRealtimeActive)
|
||||
{
|
||||
// Initialize realtime processing
|
||||
effect->RealtimeInitialize();
|
||||
|
||||
// Add the required processors
|
||||
for (size_t i = 0, cnt = mRealtimeChans.size(); i < cnt; i++)
|
||||
{
|
||||
effect->RealtimeAddProcessor(i, mRealtimeChans[i], mRealtimeRates[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to list of active effects
|
||||
mRealtimeEffects.push_back(effect);
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeRemoveEffect(Effect *effect)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
if (mRealtimeActive)
|
||||
{
|
||||
// Cleanup realtime processing
|
||||
effect->RealtimeFinalize();
|
||||
}
|
||||
|
||||
// Remove from list of active effects
|
||||
auto end = mRealtimeEffects.end();
|
||||
auto found = std::find(mRealtimeEffects.begin(), end, effect);
|
||||
if (found != end)
|
||||
mRealtimeEffects.erase(found);
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeInitialize(double rate)
|
||||
{
|
||||
// The audio thread should not be running yet, but protect anyway
|
||||
RealtimeSuspend();
|
||||
|
||||
// (Re)Set processor parameters
|
||||
mRealtimeChans.clear();
|
||||
mRealtimeRates.clear();
|
||||
|
||||
// RealtimeAdd/RemoveEffect() 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 (auto e : mRealtimeEffects) {
|
||||
e->SetSampleRate(rate);
|
||||
e->RealtimeInitialize();
|
||||
}
|
||||
|
||||
// Get things moving
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeAddProcessor(int group, unsigned chans, float rate)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeAddProcessor(group, chans, rate);
|
||||
|
||||
mRealtimeChans.push_back(chans);
|
||||
mRealtimeRates.push_back(rate);
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeFinalize()
|
||||
{
|
||||
// Make sure nothing is going on
|
||||
RealtimeSuspend();
|
||||
|
||||
// It is now safe to clean up
|
||||
mRealtimeLatency = 0;
|
||||
|
||||
// Tell each effect to clean up as well
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeFinalize();
|
||||
|
||||
// Reset processor parameters
|
||||
mRealtimeChans.clear();
|
||||
mRealtimeRates.clear();
|
||||
|
||||
// No longer active
|
||||
mRealtimeActive = false;
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeSuspend()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Already suspended...bail
|
||||
if (mRealtimeSuspended)
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return;
|
||||
}
|
||||
|
||||
// Show that we aren't going to be doing anything
|
||||
mRealtimeSuspended = true;
|
||||
|
||||
// And make sure the effects don't either
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeSuspend();
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeResume()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Already running...bail
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell the effects to get ready for more action
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeResume();
|
||||
|
||||
// And we should too
|
||||
mRealtimeSuspended = false;
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
void RealtimeEffectManager::RealtimeProcessStart()
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended.
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
e->RealtimeProcessStart();
|
||||
}
|
||||
}
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
size_t RealtimeEffectManager::RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended, so allow the samples to pass as-is.
|
||||
if (mRealtimeSuspended || mRealtimeEffects.empty())
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
// Remember when we started so we can calculate the amount of latency we
|
||||
// are introducing
|
||||
wxMilliClock_t start = wxGetUTCTimeMillis();
|
||||
|
||||
// Allocate the in/out buffer arrays
|
||||
float **ibuf = (float **) alloca(chans * sizeof(float *));
|
||||
float **obuf = (float **) alloca(chans * sizeof(float *));
|
||||
|
||||
// And populate the input with the buffers we've been given while allocating
|
||||
// NEW output buffers
|
||||
for (unsigned int i = 0; i < chans; i++)
|
||||
{
|
||||
ibuf[i] = buffers[i];
|
||||
obuf[i] = (float *) alloca(numSamples * sizeof(float));
|
||||
}
|
||||
|
||||
// Now call each effect in the chain while swapping buffer pointers to feed the
|
||||
// output of one effect as the input to the next effect
|
||||
size_t called = 0;
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
{
|
||||
e->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
|
||||
called++;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < chans; j++)
|
||||
{
|
||||
float *temp;
|
||||
temp = ibuf[j];
|
||||
ibuf[j] = obuf[j];
|
||||
obuf[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Once we're done, we might wind up with the last effect storing its results
|
||||
// in the temporary buffers. If that's the case, we need to copy it over to
|
||||
// the caller's buffers. This happens when the number of effects proccessed
|
||||
// is odd.
|
||||
if (called & 1)
|
||||
{
|
||||
for (unsigned int i = 0; i < chans; i++)
|
||||
{
|
||||
memcpy(buffers[i], ibuf[i], numSamples * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the latency
|
||||
mRealtimeLatency = (int) (wxGetUTCTimeMillis() - start).GetValue();
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
|
||||
//
|
||||
// This is wrong...needs to handle tails
|
||||
//
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
void RealtimeEffectManager::RealtimeProcessEnd()
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended.
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
e->RealtimeProcessEnd();
|
||||
}
|
||||
}
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
int RealtimeEffectManager::GetRealtimeLatency()
|
||||
{
|
||||
return mRealtimeLatency;
|
||||
}
|
||||
|
||||
Effect *EffectManager::GetEffect(const PluginID & ID)
|
||||
{
|
||||
// Must have a "valid" ID
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <wx/thread.h>
|
||||
#include "audacity/Types.h"
|
||||
|
||||
class AudacityCommand;
|
||||
|
@ -32,7 +31,6 @@ class SelectedRegion;
|
|||
class wxString;
|
||||
typedef wxString PluginID;
|
||||
|
||||
using EffectArray = std::vector <Effect*> ;
|
||||
using EffectMap = std::unordered_map<wxString, Effect *>;
|
||||
using AudacityCommandMap = std::unordered_map<wxString, AudacityCommand *>;
|
||||
using EffectOwnerMap = std::unordered_map< wxString, std::shared_ptr<Effect> >;
|
||||
|
@ -163,40 +161,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API RealtimeEffectManager final
|
||||
{
|
||||
public:
|
||||
|
||||
/** Get the singleton instance of the RealtimeEffectManager. **/
|
||||
static RealtimeEffectManager & Get();
|
||||
|
||||
// Realtime effect processing
|
||||
bool RealtimeIsActive();
|
||||
bool RealtimeIsSuspended();
|
||||
void RealtimeAddEffect(Effect *effect);
|
||||
void RealtimeRemoveEffect(Effect *effect);
|
||||
void RealtimeSetEffects(const EffectArray & mActive);
|
||||
void RealtimeInitialize(double rate);
|
||||
void RealtimeAddProcessor(int group, unsigned chans, float rate);
|
||||
void RealtimeFinalize();
|
||||
void RealtimeSuspend();
|
||||
void RealtimeResume();
|
||||
void RealtimeProcessStart();
|
||||
size_t RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples);
|
||||
void RealtimeProcessEnd();
|
||||
int GetRealtimeLatency();
|
||||
|
||||
private:
|
||||
RealtimeEffectManager();
|
||||
~RealtimeEffectManager();
|
||||
|
||||
wxCriticalSection mRealtimeLock;
|
||||
EffectArray mRealtimeEffects;
|
||||
int mRealtimeLatency;
|
||||
bool mRealtimeSuspended;
|
||||
bool mRealtimeActive;
|
||||
std::vector<unsigned> mRealtimeChans;
|
||||
std::vector<double> mRealtimeRates;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Effect.h"
|
||||
#include "EffectManager.h"
|
||||
#include "RealtimeEffectManager.h"
|
||||
|
||||
#if defined(EXPERIMENTAL_EFFECTS_RACK)
|
||||
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
RealtimeEffectManager.cpp
|
||||
|
||||
Paul Licameli split from EffectManager.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "RealtimeEffectManager.h"
|
||||
|
||||
#include "../Experimental.h"
|
||||
|
||||
#include "Effect.h"
|
||||
|
||||
#include <wx/time.h>
|
||||
|
||||
RealtimeEffectManager & RealtimeEffectManager::Get()
|
||||
{
|
||||
static RealtimeEffectManager rem;
|
||||
return rem;
|
||||
}
|
||||
|
||||
RealtimeEffectManager::RealtimeEffectManager()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
mRealtimeActive = false;
|
||||
mRealtimeSuspended = true;
|
||||
mRealtimeLatency = 0;
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
RealtimeEffectManager::~RealtimeEffectManager()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(EXPERIMENTAL_EFFECTS_RACK)
|
||||
void RealtimeEffectManager::RealtimeSetEffects(const EffectArray & effects)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
// Tell any effects no longer in the chain to clean up
|
||||
for (auto e: mRealtimeEffects)
|
||||
{
|
||||
// Scan the NEW chain for the effect
|
||||
for (auto e1: effects)
|
||||
{
|
||||
// Found it so we're done
|
||||
if (e == e1)
|
||||
{
|
||||
e = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Must not have been in the NEW chain, so tell it to cleanup
|
||||
if (e && mRealtimeActive)
|
||||
{
|
||||
e->RealtimeFinalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Tell any NEW effects to get ready
|
||||
for (auto e : effects)
|
||||
{
|
||||
// Scan the old chain for the effect
|
||||
for (auto e1 : mRealtimeEffects)
|
||||
{
|
||||
// Found it so tell effect to get ready
|
||||
if (e == e1)
|
||||
{
|
||||
e = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Must not have been in the old chain, so tell it to initialize
|
||||
if (e && mRealtimeActive)
|
||||
{
|
||||
e->RealtimeInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of the old chain
|
||||
// And install the NEW one
|
||||
mRealtimeEffects = effects;
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RealtimeEffectManager::RealtimeIsActive()
|
||||
{
|
||||
return mRealtimeEffects.size() != 0;
|
||||
}
|
||||
|
||||
bool RealtimeEffectManager::RealtimeIsSuspended()
|
||||
{
|
||||
return mRealtimeSuspended;
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeAddEffect(Effect *effect)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
// Initialize effect if realtime is already active
|
||||
if (mRealtimeActive)
|
||||
{
|
||||
// Initialize realtime processing
|
||||
effect->RealtimeInitialize();
|
||||
|
||||
// Add the required processors
|
||||
for (size_t i = 0, cnt = mRealtimeChans.size(); i < cnt; i++)
|
||||
{
|
||||
effect->RealtimeAddProcessor(i, mRealtimeChans[i], mRealtimeRates[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to list of active effects
|
||||
mRealtimeEffects.push_back(effect);
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeRemoveEffect(Effect *effect)
|
||||
{
|
||||
// Block RealtimeProcess()
|
||||
RealtimeSuspend();
|
||||
|
||||
if (mRealtimeActive)
|
||||
{
|
||||
// Cleanup realtime processing
|
||||
effect->RealtimeFinalize();
|
||||
}
|
||||
|
||||
// Remove from list of active effects
|
||||
auto end = mRealtimeEffects.end();
|
||||
auto found = std::find(mRealtimeEffects.begin(), end, effect);
|
||||
if (found != end)
|
||||
mRealtimeEffects.erase(found);
|
||||
|
||||
// Allow RealtimeProcess() to, well, process
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeInitialize(double rate)
|
||||
{
|
||||
// The audio thread should not be running yet, but protect anyway
|
||||
RealtimeSuspend();
|
||||
|
||||
// (Re)Set processor parameters
|
||||
mRealtimeChans.clear();
|
||||
mRealtimeRates.clear();
|
||||
|
||||
// RealtimeAdd/RemoveEffect() 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 (auto e : mRealtimeEffects) {
|
||||
e->SetSampleRate(rate);
|
||||
e->RealtimeInitialize();
|
||||
}
|
||||
|
||||
// Get things moving
|
||||
RealtimeResume();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeAddProcessor(int group, unsigned chans, float rate)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeAddProcessor(group, chans, rate);
|
||||
|
||||
mRealtimeChans.push_back(chans);
|
||||
mRealtimeRates.push_back(rate);
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeFinalize()
|
||||
{
|
||||
// Make sure nothing is going on
|
||||
RealtimeSuspend();
|
||||
|
||||
// It is now safe to clean up
|
||||
mRealtimeLatency = 0;
|
||||
|
||||
// Tell each effect to clean up as well
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeFinalize();
|
||||
|
||||
// Reset processor parameters
|
||||
mRealtimeChans.clear();
|
||||
mRealtimeRates.clear();
|
||||
|
||||
// No longer active
|
||||
mRealtimeActive = false;
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeSuspend()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Already suspended...bail
|
||||
if (mRealtimeSuspended)
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return;
|
||||
}
|
||||
|
||||
// Show that we aren't going to be doing anything
|
||||
mRealtimeSuspended = true;
|
||||
|
||||
// And make sure the effects don't either
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeSuspend();
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
void RealtimeEffectManager::RealtimeResume()
|
||||
{
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Already running...bail
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell the effects to get ready for more action
|
||||
for (auto e : mRealtimeEffects)
|
||||
e->RealtimeResume();
|
||||
|
||||
// And we should too
|
||||
mRealtimeSuspended = false;
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
void RealtimeEffectManager::RealtimeProcessStart()
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended.
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
e->RealtimeProcessStart();
|
||||
}
|
||||
}
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
size_t RealtimeEffectManager::RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended, so allow the samples to pass as-is.
|
||||
if (mRealtimeSuspended || mRealtimeEffects.empty())
|
||||
{
|
||||
mRealtimeLock.Leave();
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
// Remember when we started so we can calculate the amount of latency we
|
||||
// are introducing
|
||||
wxMilliClock_t start = wxGetUTCTimeMillis();
|
||||
|
||||
// Allocate the in/out buffer arrays
|
||||
float **ibuf = (float **) alloca(chans * sizeof(float *));
|
||||
float **obuf = (float **) alloca(chans * sizeof(float *));
|
||||
|
||||
// And populate the input with the buffers we've been given while allocating
|
||||
// NEW output buffers
|
||||
for (unsigned int i = 0; i < chans; i++)
|
||||
{
|
||||
ibuf[i] = buffers[i];
|
||||
obuf[i] = (float *) alloca(numSamples * sizeof(float));
|
||||
}
|
||||
|
||||
// Now call each effect in the chain while swapping buffer pointers to feed the
|
||||
// output of one effect as the input to the next effect
|
||||
size_t called = 0;
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
{
|
||||
e->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
|
||||
called++;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < chans; j++)
|
||||
{
|
||||
float *temp;
|
||||
temp = ibuf[j];
|
||||
ibuf[j] = obuf[j];
|
||||
obuf[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Once we're done, we might wind up with the last effect storing its results
|
||||
// in the temporary buffers. If that's the case, we need to copy it over to
|
||||
// the caller's buffers. This happens when the number of effects proccessed
|
||||
// is odd.
|
||||
if (called & 1)
|
||||
{
|
||||
for (unsigned int i = 0; i < chans; i++)
|
||||
{
|
||||
memcpy(buffers[i], ibuf[i], numSamples * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the latency
|
||||
mRealtimeLatency = (int) (wxGetUTCTimeMillis() - start).GetValue();
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
|
||||
//
|
||||
// This is wrong...needs to handle tails
|
||||
//
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
//
|
||||
// This will be called in a different thread than the main GUI thread.
|
||||
//
|
||||
void RealtimeEffectManager::RealtimeProcessEnd()
|
||||
{
|
||||
// Protect ourselves from the main thread
|
||||
mRealtimeLock.Enter();
|
||||
|
||||
// Can be suspended because of the audio stream being paused or because effects
|
||||
// have been suspended.
|
||||
if (!mRealtimeSuspended)
|
||||
{
|
||||
for (auto e : mRealtimeEffects)
|
||||
{
|
||||
if (e->IsRealtimeActive())
|
||||
e->RealtimeProcessEnd();
|
||||
}
|
||||
}
|
||||
|
||||
mRealtimeLock.Leave();
|
||||
}
|
||||
|
||||
int RealtimeEffectManager::GetRealtimeLatency()
|
||||
{
|
||||
return mRealtimeLatency;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
RealtimeEffectManager.h
|
||||
|
||||
Paul Licameli split from EffectManager.h
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_REALTIME_EFFECT_MANAGER__
|
||||
#define __AUDACITY_REALTIME_EFFECT_MANAGER__
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <wx/thread.h>
|
||||
|
||||
class Effect;
|
||||
using EffectArray = std::vector <Effect*> ;
|
||||
|
||||
class AUDACITY_DLL_API RealtimeEffectManager final
|
||||
{
|
||||
public:
|
||||
|
||||
/** Get the singleton instance of the RealtimeEffectManager. **/
|
||||
static RealtimeEffectManager & Get();
|
||||
|
||||
// Realtime effect processing
|
||||
bool RealtimeIsActive();
|
||||
bool RealtimeIsSuspended();
|
||||
void RealtimeAddEffect(Effect *effect);
|
||||
void RealtimeRemoveEffect(Effect *effect);
|
||||
void RealtimeSetEffects(const EffectArray & mActive);
|
||||
void RealtimeInitialize(double rate);
|
||||
void RealtimeAddProcessor(int group, unsigned chans, float rate);
|
||||
void RealtimeFinalize();
|
||||
void RealtimeSuspend();
|
||||
void RealtimeResume();
|
||||
void RealtimeProcessStart();
|
||||
size_t RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples);
|
||||
void RealtimeProcessEnd();
|
||||
int GetRealtimeLatency();
|
||||
|
||||
private:
|
||||
RealtimeEffectManager();
|
||||
~RealtimeEffectManager();
|
||||
|
||||
wxCriticalSection mRealtimeLock;
|
||||
EffectArray mRealtimeEffects;
|
||||
int mRealtimeLatency;
|
||||
bool mRealtimeSuspended;
|
||||
bool mRealtimeActive;
|
||||
std::vector<unsigned> mRealtimeChans;
|
||||
std::vector<double> mRealtimeRates;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -23,6 +23,7 @@
|
|||
#include "../commands/ScreenshotCommand.h"
|
||||
#include "../effects/Contrast.h"
|
||||
#include "../effects/EffectManager.h"
|
||||
#include "../effects/RealtimeEffectManager.h"
|
||||
|
||||
// private helper classes and functions
|
||||
namespace {
|
||||
|
|
|
@ -28,7 +28,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||
#include "../../../../TrackPanelMouseEvent.h"
|
||||
#include "../../../../WaveTrack.h"
|
||||
#include "../../../../widgets/PopupMenuTable.h"
|
||||
#include "../../../../effects/EffectManager.h"
|
||||
#include "../../../../effects/RealtimeEffectManager.h"
|
||||
#include "../../../../ondemand/ODManager.h"
|
||||
#include "../../../../prefs/PrefsDialog.h"
|
||||
#include "../../../../prefs/SpectrumPrefs.h"
|
||||
|
|
|
@ -358,6 +358,7 @@
|
|||
<ClCompile Include="..\..\..\src\effects\NoiseRemoval.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\Normalize.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\Paulstretch.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\RealtimeEffectManager.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\Repair.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\Repeat.cpp" />
|
||||
<ClCompile Include="..\..\..\src\effects\Reverb.cpp" />
|
||||
|
@ -747,6 +748,7 @@
|
|||
<ClInclude Include="..\..\..\src\effects\NoiseRemoval.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\Normalize.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\Paulstretch.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\RealtimeEffectManager.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\Repair.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\Repeat.h" />
|
||||
<ClInclude Include="..\..\..\src\effects\Reverb.h" />
|
||||
|
|
|
@ -461,6 +461,9 @@
|
|||
<ClCompile Include="..\..\..\src\effects\Paulstretch.cpp">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\effects\RealtimeEffectManager.cpp">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\effects\Repair.cpp">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1588,6 +1591,9 @@
|
|||
<ClInclude Include="..\..\..\src\effects\Paulstretch.h">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\effects\RealtimeEffectManager.h">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\effects\Repair.h">
|
||||
<Filter>src\effects</Filter>
|
||||
</ClInclude>
|
||||
|
|
Loading…
Reference in New Issue