1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-15 16:17:41 +02:00

Add re-entrancy checks to Nyquist

These changes below are paving the way for aud-do:

Nyquist Effect now detects self reentrancy and skips reentry if so.
Nyquist Effect now detects if another effect has run during effect processing, and does not send Nyquist
output if so.

Neither of these preparatory changes have an effect in absence of AUD-DO (or other function
that allows Nyquist effect to call out to Audacity functions).
This commit is contained in:
James Crook 2018-02-24 10:31:50 +00:00
parent d554ea53d2
commit b975956812
5 changed files with 39 additions and 6 deletions

View File

@ -207,6 +207,10 @@ void SelectTracksCommand::PopulateOrExchange(ShuttleGui & S)
bool SelectTracksCommand::Apply(const CommandContext &context) bool SelectTracksCommand::Apply(const CommandContext &context)
{ {
// Count selection as a do-nothing effect.
// Used to invalidate cached selection and tracks.
Effect::IncEffectCounter();
int index = 0; int index = 0;
TrackList *tracks = context.GetProject()->GetTracks(); TrackList *tracks = context.GetProject()->GetTracks();

View File

@ -70,6 +70,9 @@ greater use in future.
#include <unordered_map> #include <unordered_map>
// Effect application counter
int Effect::nEffectsDone=0;
static const int kDummyID = 20000; static const int kDummyID = 20000;
static const int kSaveAsID = 20001; static const int kSaveAsID = 20001;
static const int kImportID = 20002; static const int kImportID = 20002;
@ -1074,8 +1077,9 @@ bool Effect::SetAutomationParameters(const wxString & parms)
preset preset
) )
); );
// We are using defualt settings and we still wish to continue.
return false; return true;
//return false;
} }
if (!mUIDialog) if (!mUIDialog)
@ -1246,7 +1250,7 @@ bool Effect::DoEffect(wxWindow *parent,
returnVal = Process(); returnVal = Process();
} }
if (returnVal) if (returnVal && (mT1 >= mT0 ))
{ {
selectedRegion->setTimes(mT0, mT1); selectedRegion->setTimes(mT0, mT1);
} }
@ -2246,6 +2250,7 @@ void Effect::ReplaceProcessedTracks(const bool bGoodResult)
// The output list is no longer needed // The output list is no longer needed
mOutputTracks.reset(); mOutputTracks.reset();
mOutputTracksType = Track::None; mOutputTracksType = Track::None;
nEffectsDone++;
} }
void Effect::CountWaveTracks() void Effect::CountWaveTracks()

View File

@ -270,6 +270,8 @@ class AUDACITY_DLL_API Effect /* not final */ : public wxEvtHandler,
long style = DefaultMessageBoxStyle, long style = DefaultMessageBoxStyle,
const wxString& titleStr = wxString{}); const wxString& titleStr = wxString{});
static void IncEffectCounter(){ nEffectsDone++;};
// //
// protected virtual methods // protected virtual methods
// //
@ -341,7 +343,6 @@ protected:
bool TrackGroupProgress(int whichGroup, double frac, const wxString & = wxEmptyString); bool TrackGroupProgress(int whichGroup, double frac, const wxString & = wxEmptyString);
int GetNumWaveTracks() { return mNumTracks; } int GetNumWaveTracks() { return mNumTracks; }
int GetNumWaveGroups() { return mNumGroups; } int GetNumWaveGroups() { return mNumGroups; }
// Calculates the start time and selection length in samples // Calculates the start time and selection length in samples
@ -370,6 +371,9 @@ protected:
void CopyInputTracks(); // trackType = Track::Wave void CopyInputTracks(); // trackType = Track::Wave
void CopyInputTracks(int trackType); void CopyInputTracks(int trackType);
// A global counter of all the successful Effect invocations.
static int nEffectsDone;
// For the use of analyzers, which don't need to make output wave tracks, // For the use of analyzers, which don't need to make output wave tracks,
// but may need to add label tracks. // but may need to add label tracks.
class AddedAnalysisTrack { class AddedAnalysisTrack {

View File

@ -75,6 +75,8 @@ effects from this one class.
#include "../../Experimental.h" #include "../../Experimental.h"
int NyquistEffect::mReentryCount = 0;
enum enum
{ {
ID_Editor = 10000, ID_Editor = 10000,
@ -584,10 +586,21 @@ static void RegisterFunctions();
bool NyquistEffect::Process() bool NyquistEffect::Process()
{ {
// Check for reentrant Nyquist commands.
// I'm choosing to mark skipped Nyquist commands as successful even though
// they are skipped. The reason is that when Nyquist calls out to a chain,
// and that chain contains Nyquist, it will be clearer if the chain completes
// skipping Nyquist, rather than doing nothing at all.
if( mReentryCount > 0 )
return true;
// Restore the reentry counter (to zero) when we exit.
auto cleanup = valueRestorer( mReentryCount);
mReentryCount++;
RegisterFunctions(); RegisterFunctions();
bool success = true; bool success = true;
int nEffectsSoFar = nEffectsDone;
mProjectChanged = false; mProjectChanged = false;
EffectManager & em = EffectManager::Get(); EffectManager & em = EffectManager::Get();
em.SetSkipStateFlag(false); em.SetSkipStateFlag(false);
@ -894,7 +907,13 @@ finish:
dlog.ShowModal(); dlog.ShowModal();
} }
ReplaceProcessedTracks(success); // Has rug been pulled from under us by some effect done within Nyquist??
if( nEffectsSoFar == nEffectsDone )
ReplaceProcessedTracks(success);
else{
ReplaceProcessedTracks(false); // Do not use the results.
mT1 = mT0 - 1.0;// And don't use the times either, in resetting the selection (make them bogus).
}
if (!mProjectChanged) if (!mProjectChanged)
em.SetSkipStateFlag(true); em.SetSkipStateFlag(true);

View File

@ -129,6 +129,7 @@ public:
void Stop(); void Stop();
private: private:
static int mReentryCount;
// NyquistEffect implementation // NyquistEffect implementation
bool ProcessOne(); bool ProcessOne();