Audacity 3.2.0
Classes | Public Member Functions | Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Static Private Attributes | Friends | List of all members
NyquistBase Class Reference

An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class. More...

#include <NyquistBase.h>

Inheritance diagram for NyquistBase:
[legend]
Collaboration diagram for NyquistBase:
[legend]

Classes

struct  ExecFromMainHook
 
struct  GetDisplaysHook
 
struct  GetEffectHook
 
struct  NyxContext
 
struct  ShowDebugOutputHook
 
struct  Tokenizer
 
struct  YieldIfNeededHook
 

Public Member Functions

 NyquistBase (const wxString &fName)
 
virtual ~NyquistBase ()
 
PluginPath GetPath () const override
 
ComponentInterfaceSymbol GetSymbol () const override
 
VendorSymbol GetVendor () const override
 
wxString GetVersion () const override
 
TranslatableString GetDescription () const override
 
ManualPageID ManualPage () const override
 Name of a page in the Audacity alpha manual, default is empty. More...
 
FilePath HelpPage () const override
 Fully qualified local help file name, default is empty. More...
 
EffectType GetType () const override
 Type determines how it behaves. More...
 
EffectType GetClassification () const override
 Determines which menu it appears in; default same as GetType(). More...
 
EffectFamilySymbol GetFamily () const override
 Report identifier and user-visible name of the effect protocol. More...
 
bool IsInteractive () const override
 Whether the effect needs a dialog for entry of settings. More...
 
bool IsDefault () const override
 Whether the effect sorts "above the line" in the menus. More...
 
bool EnablesDebug () const override
 Whether the effect dialog should have a Debug button; default, always false. More...
 
bool SaveSettings (const EffectSettings &settings, CommandParameters &parms) const override
 Store settings as keys and values. More...
 
bool LoadSettings (const CommandParameters &parms, EffectSettings &settings) const override
 Restore settings from keys and values. More...
 
bool DoLoadSettings (const CommandParameters &parms, EffectSettings &settings)
 
bool VisitSettings (SettingsVisitor &visitor, EffectSettings &settings) override
 
bool VisitSettings (ConstSettingsVisitor &visitor, const EffectSettings &settings) const override
 
int SetLispVarsFromParameters (const CommandParameters &parms, bool bTestOnly)
 
bool Init () override
 
bool Process (EffectInstance &instance, EffectSettings &settings) override
 
void RedirectOutput ()
 
void SetCommand (const wxString &cmd)
 
void Continue ()
 
void Break ()
 
void Stop ()
 
bool IsOk ()
 
- Public Member Functions inherited from EffectWithSettings< NyquistSettings, StatefulEffect >
EffectSettings MakeSettings () const override
 
bool CopySettingsContents (const EffectSettings &src, EffectSettings &dst) const override
 
- Public Member Functions inherited from StatefulEffect
 ~StatefulEffect () override
 
std::shared_ptr< EffectInstanceMakeInstance () const override
 Make an object maintaining short-term state of an Effect. More...
 
- Public Member Functions inherited from StatefulEffectBase
virtual bool Init ()
 
virtual bool Process (EffectInstance &instance, EffectSettings &settings)=0
 
virtual bool RealtimeInitialize (EffectSettings &settings, double sampleRate)
 
virtual bool RealtimeAddProcessor (EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate)
 
virtual bool RealtimeSuspend ()
 
virtual bool RealtimeResume ()
 
virtual bool RealtimeProcessStart (MessagePackage &package)
 settings are possibly changed, since last call, by an asynchronous dialog More...
 
virtual size_t RealtimeProcess (size_t group, EffectSettings &settings, const float *const *inBuf, float *const *outBuf, size_t numSamples)
 
virtual bool RealtimeProcessEnd (EffectSettings &settings) noexcept
 settings can be updated to let a dialog change appearance at idle More...
 
virtual bool RealtimeFinalize (EffectSettings &settings) noexcept
 
virtual size_t SetBlockSize (size_t maxBlockSize)
 
virtual size_t GetBlockSize () const
 
virtual unsigned GetAudioInCount () const
 How many input buffers to allocate at once. More...
 
virtual unsigned GetAudioOutCount () const
 How many output buffers to allocate at once. More...
 
virtual sampleCount GetLatency () const
 
virtual bool NeedsDither () const
 
virtual bool ProcessInitialize (EffectSettings &settings, double sampleRate, ChannelNames chanMap=nullptr)
 
virtual bool ProcessFinalize () noexcept
 
- Public Member Functions inherited from Effect
 Effect ()
 
virtual ~Effect ()
 
PluginPath GetPath () const override
 
bool VisitSettings (SettingsVisitor &visitor, EffectSettings &settings) override
 
bool VisitSettings (ConstSettingsVisitor &visitor, const EffectSettings &settings) const override
 
ComponentInterfaceSymbol GetSymbol () const override
 
VendorSymbol GetVendor () const override
 
wxString GetVersion () const override
 
TranslatableString GetDescription () const override
 
EffectFamilySymbol GetFamily () const override
 Report identifier and user-visible name of the effect protocol. More...
 
bool IsInteractive () const override
 Whether the effect needs a dialog for entry of settings. More...
 
bool IsDefault () const override
 Whether the effect sorts "above the line" in the menus. More...
 
RealtimeSince RealtimeSupport () const override
 Since which version of Audacity has the effect supported realtime? More...
 
bool SupportsAutomation () const override
 Whether the effect has any automatable controls. More...
 
bool SaveSettings (const EffectSettings &settings, CommandParameters &parms) const override
 Store settings as keys and values. More...
 
bool LoadSettings (const CommandParameters &parms, EffectSettings &settings) const override
 Restore settings from keys and values. More...
 
OptionalMessage LoadUserPreset (const RegistryPath &name, EffectSettings &settings) const override
 
bool SaveUserPreset (const RegistryPath &name, const EffectSettings &settings) const override
 Save settings in the configuration file as a user-named preset. More...
 
RegistryPaths GetFactoryPresets () const override
 Report names of factory presets. More...
 
OptionalMessage LoadFactoryPreset (int id, EffectSettings &settings) const override
 
OptionalMessage LoadFactoryDefaults (EffectSettings &settings) const override
 
virtual const EffectParameterMethodsParameters () const
 
bool CanExportPresets () const override
 Whether the effect supports export of presets to files, and importing too. More...
 
bool HasOptions () const override
 
const EffectSettingsManagerGetDefinition () const override
 
virtual NumericFormatID GetSelectionFormat ()
 
bool SaveSettingsAsString (const EffectSettings &settings, wxString &parms) const override
 
OptionalMessage LoadSettingsFromString (const wxString &parms, EffectSettings &settings) const override
 
bool IsBatchProcessing () const override
 
void SetBatchProcessing () override
 
void UnsetBatchProcessing () override
 
unsigned TestUIFlags (unsigned mask)
 
bool Delegate (Effect &delegate, EffectSettings &settings, InstanceFinder finder={})
 Re-invoke DoEffect on another Effect object that implements the work. More...
 
- Public Member Functions inherited from EffectBase
 EffectBase ()
 
 ~EffectBase () override
 
bool IsLinearEffect () const
 
bool PreviewsFullSelection () const
 
void SetTracks (TrackList *pTracks)
 
double GetDefaultDuration ()
 
virtual std::any BeginPreview (const EffectSettings &settings)
 Called when Preview() starts, to allow temporary effect state changes. More...
 
bool DoEffect (EffectSettings &settings, const InstanceFinder &finder, double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, const EffectSettingsAccessPtr &pAccess) override
 
virtual double CalcPreviewInputLength (const EffectSettings &settings, double previewLength) const =0
 
void CountWaveTracks ()
 
- Public Member Functions inherited from EffectPlugin
EffectPluginoperator= (EffectPlugin &)=delete
 
virtual ~EffectPlugin ()
 
virtual bool HasOptions () const =0
 
virtual bool CanExportPresets () const =0
 Whether the effect supports export of presets to files, and importing too. More...
 
virtual const EffectSettingsManagerGetDefinition () const =0
 
virtual bool SaveSettingsAsString (const EffectSettings &settings, wxString &parms) const =0
 
virtual OptionalMessage LoadSettingsFromString (const wxString &parms, EffectSettings &settings) const =0
 
virtual bool IsBatchProcessing () const =0
 
virtual void SetBatchProcessing ()=0
 
virtual void UnsetBatchProcessing ()=0
 
virtual bool DoEffect (EffectSettings &settings, const InstanceFinder &finder, double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, const EffectSettingsAccessPtr &pAccess=nullptr)=0
 
- Public Member Functions inherited from EffectInstanceFactory
virtual ~EffectInstanceFactory ()
 
virtual std::shared_ptr< EffectInstanceMakeInstance () const =0
 Make an object maintaining short-term state of an Effect. More...
 
- Public Member Functions inherited from EffectSettingsManager
virtual ~EffectSettingsManager ()
 
virtual bool VisitSettings (SettingsVisitor &visitor, EffectSettings &settings)
 
virtual bool VisitSettings (ConstSettingsVisitor &visitor, const EffectSettings &settings) const
 
virtual std::unique_ptr< EffectOutputsMakeOutputs () const
 Produce an object to hold values to send to effect output meters. More...
 
- Public Member Functions inherited from EffectDefinitionInterface
virtual ~EffectDefinitionInterface ()
 
virtual EffectType GetType () const =0
 Type determines how it behaves. More...
 
virtual EffectType GetClassification () const
 Determines which menu it appears in; default same as GetType(). More...
 
virtual EffectFamilySymbol GetFamily () const =0
 Report identifier and user-visible name of the effect protocol. More...
 
virtual bool IsInteractive () const =0
 Whether the effect needs a dialog for entry of settings. More...
 
virtual bool IsDefault () const =0
 Whether the effect sorts "above the line" in the menus. More...
 
virtual RealtimeSince RealtimeSupport () const =0
 Since which version of Audacity has the effect supported realtime? More...
 
bool SupportsRealtime () const
 
virtual bool SupportsAutomation () const =0
 Whether the effect has any automatable controls. More...
 
virtual bool EnablesDebug () const
 Whether the effect dialog should have a Debug button; default, always false. More...
 
virtual ManualPageID ManualPage () const
 Name of a page in the Audacity alpha manual, default is empty. More...
 
virtual FilePath HelpPage () const
 Fully qualified local help file name, default is empty. More...
 
virtual bool IsHiddenFromMenus () const
 Default is false. More...
 
- Public Member Functions inherited from ComponentInterface
virtual ~ComponentInterface ()
 
virtual PluginPath GetPath () const =0
 
virtual ComponentInterfaceSymbol GetSymbol () const =0
 
virtual VendorSymbol GetVendor () const =0
 
virtual wxString GetVersion () const =0
 
virtual TranslatableString GetDescription () const =0
 
TranslatableString GetName () const
 

Public Attributes

std::vector< NyqControlmControls
 
- Public Attributes inherited from EffectBase
std::shared_ptr< TrackListmTracks {}
 
int mNumTracks {}
 
BasicUI::ProgressDialogmProgress {}
 
double mProjectRate {}
 
WaveTrackFactorymFactory {}
 
double mT0 {}
 
double mT1 {}
 
bool mIsPreview { false }
 

Protected Member Functions

bool ParseCommand (const wxString &cmd)
 
bool validatePath (wxString path)
 
wxString ToTimeFormat (double t)
 
- Protected Member Functions inherited from Effect
bool CheckWhetherSkipEffect (const EffectSettings &settings) const override
 Default implementation returns false. More...
 
double CalcPreviewInputLength (const EffectSettings &settings, double previewLength) const override
 Default implementation returns previewLength More...
 
bool TotalProgress (double frac, const TranslatableString &={}) const
 
bool TrackProgress (int whichTrack, double frac, const TranslatableString &={}) const
 
bool TrackGroupProgress (int whichGroup, double frac, const TranslatableString &={}) const
 
int GetNumWaveTracks () const
 
int GetNumWaveGroups () const
 
void GetBounds (const WaveTrack &track, sampleCount *start, sampleCount *len)
 
- Protected Member Functions inherited from EffectBase
virtual bool CheckWhetherSkipEffect (const EffectSettings &settings) const =0
 After Init(), tell whether Process() should be skipped. More...
 
void SetLinearEffectFlag (bool linearEffectFlag)
 
void SetPreviewFullSelectionFlag (bool previewDurationFlag)
 
bool IsPreviewing () const
 
const TrackListinputTracks () const
 
const AudacityProjectFindProject () const
 

Static Protected Member Functions

static double GetCtrlValue (const wxString &s)
 
static void resolveFilePath (wxString &path, FileExtension extension={})
 

Protected Attributes

wxString mXlispPath
 
wxFileName mFileName
 Name of the Nyquist script file this effect is loaded from. More...
 
wxDateTime mFileModified
 When the script was last modified on disk. More...
 
bool mStop
 
bool mBreak
 
bool mCont
 
bool mFoundType
 
bool mCompiler
 
bool mTrace
 
bool mIsSal
 
bool mExternal
 
bool mIsSpectral
 
bool mIsTool
 
const bool mIsPrompt
 
bool mOK
 
TranslatableString mInitError
 
wxString mInputCmd
 
wxString mParameters
 
wxString mCmd
 
TranslatableString mName
 Name of the Effect (untranslated) More...
 
TranslatableString mPromptName
 
TranslatableString mAction
 
TranslatableString mInfo
 
TranslatableString mAuthor
 
TranslatableString mReleaseVersion
 
TranslatableString mCopyright
 
wxString mManPage
 
wxString mHelpFile
 
bool mHelpFileExists
 
FilePath mHelpPage
 
EffectType mType
 
EffectType mPromptType
 
bool mEnablePreview
 
bool mDebugButton
 
bool mDebug
 
bool mRedirectOutput
 
bool mProjectChanged
 
wxString mDebugOutputStr
 
TranslatableString mDebugOutput
 
int mVersion
 
sampleCount mMaxLen
 
int mTrackIndex
 
bool mFirstInGroup
 
double mOutputTime
 
unsigned mCount
 
unsigned mNumSelectedChannels
 
wxArrayString mCategories
 
wxString mProps
 
wxString mPerTrackProps
 
bool mRestoreSplits
 
int mMergeClips
 
- Protected Attributes inherited from EffectBase
double mF0 {}
 
double mF1 {}
 
wxArrayString mPresetNames
 
unsigned mUIFlags { 0 }
 

Private Member Functions

bool ProcessOne (NyxContext &nyxContext, EffectOutputTracks *pOutputs)
 
const TranslatableStringInitializationError () const
 
wxString EscapeString (const wxString &inStr)
 
FileExtensions ParseFileExtensions (const wxString &text)
 
FileNames::FileType ParseFileType (const wxString &text)
 
FileNames::FileTypes ParseFileTypes (const wxString &text)
 
void OutputCallback (int c)
 
void OSCallback ()
 
void ParseFile ()
 
bool ParseProgram (wxInputStream &stream)
 
bool Parse (Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
 
std::pair< bool, FilePathCheckHelpPage () const
 

Static Private Member Functions

static FilePaths GetNyquistSearchPath ()
 
static wxString NyquistToWxString (const char *nyqString)
 
static std::vector< EnumValueSymbolParseChoice (const wxString &text)
 
static void StaticOutputCallback (int c, void *userdata)
 
static void StaticOSCallback (void *userdata)
 
static TranslatableString UnQuoteMsgid (const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
 
static wxString UnQuote (const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
 

Static Private Attributes

static int mReentryCount = 0
 

Friends

class NyquistEffectsModule
 

Additional Inherited Members

- Public Types inherited from StatefulEffectBase
using MessagePackage = EffectInstance::MessagePackage
 
- Public Types inherited from EffectPlugin
using EffectSettingsAccessPtr = std::shared_ptr< EffectSettingsAccess >
 
using InstancePointer = std::shared_ptr< EffectInstanceEx >
 
using InstanceFinder = std::function< std::optional< InstancePointer >(EffectSettings &settings) >
 
- Public Types inherited from EffectDefinitionInterface
enum class  RealtimeSince : unsigned { Never , After_3_1 , Always }
 In which versions of Audacity was an effect realtime capable? More...
 
- Static Public Member Functions inherited from EffectWithSettings< NyquistSettings, StatefulEffect >
static NyquistSettingsGetSettings (EffectSettings &settings)
 Assume settings originated from MakeSettings() and copies thereof. More...
 
static const NyquistSettingsGetSettings (const EffectSettings &settings)
 Assume settings originated from MakeSettings() and copies thereof. More...
 
static NyquistSettingsFetchParameters (StatefulEffect &, EffectSettings &s)
 
- Static Public Member Functions inherited from Effect
static EffectFetchParameters (Effect &e, EffectSettings &)
 
- Static Public Member Functions inherited from EffectBase
static std::optional< InstancePointerFindInstance (EffectPlugin &plugin)
 
static InstanceFinder DefaultInstanceFinder (EffectPlugin &plugin)
 
- Static Public Member Functions inherited from EffectDefinitionInterface
static Identifier GetSquashedName (const Identifier &ident)
 A utility that strips spaces and CamelCases a name. More...
 
- Static Public Attributes inherited from EffectPlugin
static const wxString kUserPresetIdent = wxT("User Preset:")
 
static const wxString kFactoryPresetIdent = wxT("Factory Preset:")
 
static const wxString kCurrentSettingsIdent = wxT("<Current Settings>")
 
static const wxString kFactoryDefaultsIdent = wxT("<Factory Defaults>")
 

Detailed Description

An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class.

Definition at line 75 of file NyquistBase.h.

Constructor & Destructor Documentation

◆ NyquistBase()

NyquistBase::NyquistBase ( const wxString &  fName)
Parameters
fNameFile name of the Nyquist script defining this effect. If an empty string, then prompt the user for the Nyquist code to interpret.

Definition at line 56 of file NyquistBase.cpp.

57 : mIsPrompt { fName == NYQUIST_PROMPT_ID }
58{
59 mAction = XO("Applying Nyquist Effect...");
60 mExternal = false;
61 mCompiler = false;
62 mTrace = false;
63 mRedirectOutput = false;
64 mDebug = false;
65 mIsSal = false;
66 mOK = false;
67 mAuthor = XO("n/a");
68 mReleaseVersion = XO("n/a");
69 mCopyright = XO("n/a");
70
71 // set clip/split handling when applying over clip boundary.
72 mRestoreSplits = true; // Default: Restore split lines.
73 mMergeClips = -1; // Default (auto): Merge if length remains unchanged.
74
75 mVersion = 4;
76
77 mStop = false;
78 mBreak = false;
79 mCont = false;
80 mIsTool = false;
81
83
84 // Interactive Nyquist
85 if (mIsPrompt)
86 {
89 mIsTool = true;
92 mOK = true;
93 return;
94 }
95
96 if (fName == NYQUIST_WORKER_ID)
97 {
98 // Effect spawned from Nyquist Prompt
99 /* i18n-hint: It is acceptable to translate this the same as for "Nyquist
100 * Prompt" */
101 mName = XO("Nyquist Worker");
102 return;
103 }
104
105 mFileName = fName;
106 // Use the file name verbatim as effect name.
107 // This is only a default name, overridden if we find a $name line:
108 mName = Verbatim(mFileName.GetName());
109 mFileModified = mFileName.GetModificationTime();
110 ParseFile();
111
112 if (!mOK && mInitError.empty())
113 mInitError = XO("Ill-formed Nyquist plug-in header");
114}
@ EffectTypeTool
XO("Cut/Copy/Paste")
#define NYQ_MAX_LEN
Definition: NyquistBase.cpp:51
#define NYQUIST_WORKER_ID
Definition: NyquistBase.h:25
#define NYQUIST_PROMPT_ID
#define NYQUIST_PROMPT_NAME
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
const bool mIsPrompt
Definition: NyquistBase.h:251
bool mCompiler
Definition: NyquistBase.h:241
void ParseFile()
TranslatableString mCopyright
Definition: NyquistBase.h:267
TranslatableString mInitError
Definition: NyquistBase.h:253
TranslatableString mPromptName
Definition: NyquistBase.h:259
EffectType mType
Definition: NyquistBase.h:272
wxFileName mFileName
Name of the Nyquist script file this effect is loaded from.
Definition: NyquistBase.h:233
wxDateTime mFileModified
When the script was last modified on disk.
Definition: NyquistBase.h:234
bool mRedirectOutput
Definition: NyquistBase.h:279
TranslatableString mAction
Definition: NyquistBase.h:260
TranslatableString mReleaseVersion
Definition: NyquistBase.h:266
bool mRestoreSplits
Definition: NyquistBase.h:302
bool mExternal
Definition: NyquistBase.h:244
EffectType mPromptType
Definition: NyquistBase.h:273
TranslatableString mAuthor
Definition: NyquistBase.h:262
TranslatableString mName
Name of the Effect (untranslated)
Definition: NyquistBase.h:257
sampleCount mMaxLen
Definition: NyquistBase.h:290

References EffectTypeTool, mAction, mAuthor, mBreak, mCompiler, mCont, mCopyright, mDebug, mExternal, mFileModified, mFileName, mIsPrompt, mIsSal, mIsTool, mMaxLen, mMergeClips, mName, mOK, mPromptName, mPromptType, mRedirectOutput, mReleaseVersion, mRestoreSplits, mStop, mTrace, mType, mVersion, NYQ_MAX_LEN, NYQUIST_PROMPT_NAME, NYQUIST_WORKER_ID, ParseFile(), Verbatim(), and XO().

Here is the call graph for this function:

◆ ~NyquistBase()

NyquistBase::~NyquistBase ( )
virtual

Definition at line 116 of file NyquistBase.cpp.

117{
118}

Member Function Documentation

◆ Break()

void NyquistBase::Break ( )

Definition at line 1875 of file NyquistBase.cpp.

1876{
1877 mBreak = true;
1878}

References mBreak.

◆ CheckHelpPage()

std::pair< bool, FilePath > NyquistBase::CheckHelpPage ( ) const
private

Definition at line 165 of file NyquistBase.cpp.

166{
168 wxString fileName;
169
170 for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
171 {
172 fileName = wxFileName(paths[i] + wxT("/") + mHelpFile).GetFullPath();
173 if (wxFileExists(fileName))
174 {
175 return { true, fileName };
176 }
177 }
178 return { false, wxEmptyString };
179}
wxT("CloseDown"))
wxString mHelpFile
Definition: NyquistBase.h:269
static FilePaths GetNyquistSearchPath()

References GetNyquistSearchPath(), mHelpFile, and wxT().

Referenced by ParseProgram().

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

◆ Continue()

void NyquistBase::Continue ( )

Definition at line 1880 of file NyquistBase.cpp.

1881{
1882 mCont = true;
1883}

References mCont.

◆ DoLoadSettings()

bool NyquistBase::DoLoadSettings ( const CommandParameters parms,
EffectSettings settings 
)

Definition at line 354 of file NyquistBase.cpp.

356{
357 // Due to a constness problem that happens when using the prompt, we need
358 // to be ready to switch the params to a local instance.
359 const CommandParameters* pParms = &parms;
360 CommandParameters localParms;
361
362 if (mIsPrompt)
363 {
364 parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
365 parms.Read(KEY_Parameters, &mParameters, wxEmptyString);
366
367 if (!mInputCmd.empty())
368 {
370 }
371
372 if (!mParameters.empty())
373 {
374 pParms = &localParms;
375 localParms.SetParameters(mParameters);
376 }
377
378 if (!IsBatchProcessing())
379 {
381 }
382
385 mExternal = true;
386
387 if (!IsBatchProcessing())
388 {
389 return true;
390 }
391 }
392
393 // Constants to document what the true/false values mean.
394 const auto kTestOnly = true;
395 const auto kTestAndSet = false;
396
397 // badCount will encompass both actual bad values and missing values.
398 // We probably never actually have bad values when using the dialogs
399 // since the dialog validation will catch them.
400 int badCount;
401 // When batch processing, we just ignore missing/bad parameters.
402 // We'll end up using defaults in those cases.
403 if (!IsBatchProcessing())
404 {
405 badCount = SetLispVarsFromParameters(*pParms, kTestOnly);
406 if (badCount > 0)
407 return false;
408 }
409
410 badCount = SetLispVarsFromParameters(*pParms, kTestAndSet);
411 // We never do anything with badCount here.
412 // It might be non zero, for missing parameters, and we allow that,
413 // and don't distinguish that from an out-of-range value.
414 return true;
415}
static const wxChar * KEY_Command
Definition: NyquistBase.cpp:53
static const wxChar * KEY_Parameters
Definition: NyquistBase.cpp:54
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool SetParameters(const wxString &parms)
bool IsBatchProcessing() const override
Definition: Effect.cpp:295
wxString mInputCmd
Definition: NyquistBase.h:254
wxString mParameters
Definition: NyquistBase.h:255
bool ParseCommand(const wxString &cmd)
int SetLispVarsFromParameters(const CommandParameters &parms, bool bTestOnly)

References EffectTypeTool, Effect::IsBatchProcessing(), KEY_Command, KEY_Parameters, mExternal, mInputCmd, mIsPrompt, mIsTool, mParameters, mPromptType, mType, ParseCommand(), SetLispVarsFromParameters(), and CommandParameters::SetParameters().

Referenced by LoadSettings().

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

◆ EnablesDebug()

bool NyquistBase::EnablesDebug ( ) const
overridevirtual

Whether the effect dialog should have a Debug button; default, always false.

Reimplemented from EffectDefinitionInterface.

Definition at line 220 of file NyquistBase.cpp.

221{
222 return mDebugButton;
223}
bool mDebugButton
Definition: NyquistBase.h:276

References mDebugButton.

◆ EscapeString()

wxString NyquistBase::EscapeString ( const wxString &  inStr)
private

Definition at line 1747 of file NyquistBase.cpp.

1748{
1749 wxString str = inStr;
1750
1751 str.Replace(wxT("\\"), wxT("\\\\"));
1752 str.Replace(wxT("\""), wxT("\\\""));
1753
1754 return str;
1755}
#define str(a)

References str, and wxT().

Referenced by Process(), and ProcessOne().

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

◆ GetClassification()

EffectType NyquistBase::GetClassification ( ) const
overridevirtual

Determines which menu it appears in; default same as GetType().

Reimplemented from EffectDefinitionInterface.

Definition at line 193 of file NyquistBase.cpp.

194{
195 if (mIsTool)
196 return EffectTypeTool;
197 return mType;
198}

References EffectTypeTool, mIsTool, and mType.

◆ GetCtrlValue()

double NyquistBase::GetCtrlValue ( const wxString &  s)
staticprotected

Definition at line 1942 of file NyquistBase.cpp.

1943{
1944 /* For this to work correctly requires that the plug-in header is
1945 * parsed on each run so that the correct value for "half-srate" may
1946 * be determined.
1947 *
1948 auto project = FindProject();
1949 if (project && s.IsSameAs(wxT("half-srate"), false)) {
1950 auto rate =
1951 TrackList::Get( *project ).Selected< const WaveTrack >()
1952 .min( &WaveTrack::GetRate );
1953 return (rate / 2.0);
1954 }
1955 */
1956
1958}
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:109

References Internat::CompatibleToDouble().

Referenced by Parse(), SaveSettings(), SetLispVarsFromParameters(), NyquistEffect::TransferDataFromEffectWindow(), and VisitSettings().

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

◆ GetDescription()

TranslatableString NyquistBase::GetDescription ( ) const
overridevirtual

Reimplemented from Effect.

Definition at line 155 of file NyquistBase.cpp.

156{
157 return mCopyright;
158}

References mCopyright.

◆ GetFamily()

EffectFamilySymbol NyquistBase::GetFamily ( ) const
overridevirtual

Report identifier and user-visible name of the effect protocol.

Reimplemented from Effect.

Definition at line 200 of file NyquistBase.cpp.

201{
203}
#define NYQUISTEFFECTS_FAMILY
Definition: EffectBase.h:141

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistBase::GetNyquistSearchPath ( )
staticprivate

Definition at line 2750 of file NyquistBase.cpp.

2751{
2752 const auto& audacityPathList = FileNames::AudacityPathList();
2753 FilePaths pathList;
2754
2755 for (size_t i = 0; i < audacityPathList.size(); i++)
2756 {
2757 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2758 FileNames::AddUniquePathToPathList(prefix + wxT("nyquist"), pathList);
2759 FileNames::AddUniquePathToPathList(prefix + wxT("plugins"), pathList);
2760 FileNames::AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList);
2761 }
2762 pathList.push_back(FileNames::PlugInDir());
2763
2764 return pathList;
2765}
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
FILES_API FilePath PlugInDir()
The user plug-in directory (not a system one)
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...

References FileNames::AddUniquePathToPathList(), FileNames::AudacityPathList(), FileNames::PlugInDir(), and wxT().

Referenced by NyquistEffectsModule::AutoRegisterPlugins(), CheckHelpPage(), NyquistEffectsModule::FindModulePaths(), and Process().

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

◆ GetPath()

PluginPath NyquistBase::GetPath ( ) const
overridevirtual

Reimplemented from Effect.

Definition at line 122 of file NyquistBase.cpp.

123{
124 if (mIsPrompt)
125 return NYQUIST_PROMPT_ID;
126
127 return mFileName.GetFullPath();
128}

References mFileName, mIsPrompt, and NYQUIST_PROMPT_ID.

◆ GetSymbol()

ComponentInterfaceSymbol NyquistBase::GetSymbol ( ) const
overridevirtual

Reimplemented from Effect.

Definition at line 130 of file NyquistBase.cpp.

131{
132 if (mIsPrompt)
134
135 return mName;
136}

References mIsPrompt, mName, NYQUIST_PROMPT_ID, and NYQUIST_PROMPT_NAME.

◆ GetType()

EffectType NyquistBase::GetType ( ) const
overridevirtual

Type determines how it behaves.

Implements EffectDefinitionInterface.

Definition at line 188 of file NyquistBase.cpp.

189{
190 return mType;
191}

References mType.

Referenced by Process(), and ProcessOne().

Here is the caller graph for this function:

◆ GetVendor()

VendorSymbol NyquistBase::GetVendor ( ) const
overridevirtual

Reimplemented from Effect.

Definition at line 138 of file NyquistBase.cpp.

139{
140 if (mIsPrompt)
141 {
142 return XO("Audacity");
143 }
144
145 return mAuthor;
146}

References mAuthor, mIsPrompt, and XO().

Here is the call graph for this function:

◆ GetVersion()

wxString NyquistBase::GetVersion ( ) const
overridevirtual

Reimplemented from Effect.

Definition at line 148 of file NyquistBase.cpp.

149{
150 // Are Nyquist version strings really supposed to be translatable?
151 // See commit a06e561 which used XO for at least one of them
153}
wxString Translation() const

References mReleaseVersion, and TranslatableString::Translation().

Here is the call graph for this function:

◆ HelpPage()

FilePath NyquistBase::HelpPage ( ) const
overridevirtual

Fully qualified local help file name, default is empty.

Reimplemented from EffectDefinitionInterface.

Definition at line 181 of file NyquistBase.cpp.

182{
183 return mHelpPage;
184}
FilePath mHelpPage
Definition: NyquistBase.h:271

References mHelpPage.

◆ Init()

bool NyquistBase::Init ( )
overridevirtual

Default implementation does nothing, returns true

Reimplemented from StatefulEffectBase.

Definition at line 491 of file NyquistBase.cpp.

492{
493 // When Nyquist Prompt spawns an effect GUI, Init() is called for Nyquist
494 // Prompt, and then again for the spawned (mExternal) effect.
495
496 // EffectType may not be defined in script, so
497 // reset each time we call the Nyquist Prompt.
498 if (mIsPrompt)
499 {
501 // Reset effect type each time we call the Nyquist Prompt.
503 mIsSpectral = false;
504 mDebugButton = true; // Debug button always enabled for Nyquist Prompt.
506 true; // Preview button always enabled for Nyquist Prompt.
507 mVersion = 4;
508 }
509
510 // As of Audacity 2.1.2 rc1, 'spectral' effects are allowed only if
511 // the selected track(s) are in a spectrogram view, and there is at
512 // least one frequency bound and Spectral Selection is enabled for the
513 // selected track(s) - (but don't apply to Nyquist Prompt).
514
515 if (!mIsPrompt && mIsSpectral)
516 {
517 // Completely skip the spectral editing limitations if there is no
518 // project because that is editing of macro parameters
519 if (const auto project = FindProject())
520 {
521 bool bAllowSpectralEditing = false;
522 bool hasSpectral = false;
523 for (auto t : TrackList::Get(*project).Selected<const WaveTrack>())
524 {
525 // Find() not Get() to avoid creation-on-demand of views in case we
526 // are only previewing
527 const auto displays = GetDisplaysHook::Call(t);
528 hasSpectral |= displays.end() !=
529 std::find(
530 displays.begin(), displays.end(),
532 WaveChannelViewConstants::Spectrum, {} });
533
534 if (
535 hasSpectral &&
537 {
538 bAllowSpectralEditing = true;
539 break;
540 }
541 }
542
543 if (!bAllowSpectralEditing || ((mF0 < 0.0) && (mF1 < 0.0)))
544 {
545 using namespace BasicUI;
546 if (!hasSpectral)
548 XO("Enable track spectrogram view before\n"
549 "applying 'Spectral' effects."),
550 MessageBoxOptions {}.IconStyle(Icon::Error));
551 else
553 XO("To use 'Spectral effects', enable 'Spectral Selection'\n"
554 "in the track Spectrogram settings and select the\n"
555 "frequency range for the effect to act von."),
556 MessageBoxOptions {}.IconStyle(Icon::Error));
557 return false;
558 }
559 }
560 }
561
562 if (!mIsPrompt && !mExternal)
563 {
564 // TODO: (bugs):
565 // 1) If there is more than one plug-in with the same name,
566 // GetModificationTime may pick the wrong one. 2) If the ;type is changed
567 // after the effect has been registered, the plug-in will appear in the
568 // wrong menu.
569
570 // TODO: If we want to auto-add parameters from spectral selection,
571 // we will need to modify this test.
572 // Note that removing it stops the caching of parameter values,
573 //(during this session).
574 if (mFileName.GetModificationTime().IsLaterThan(mFileModified))
575 {
576 // If the effect has internal state, save and restore it.
577 // If the effect is stateless, saving and restoring don't matter.
578 auto dummySettings = MakeSettings();
579 constexpr auto key = L"TemporarySettings";
580 SaveUserPreset(key, dummySettings);
581
583 ParseFile();
584 mFileModified = mFileName.GetModificationTime();
585
586 // Ignore failure
587 (void)LoadUserPreset(key, dummySettings);
588 }
589 }
590
591 return true;
592}
static const AudacityProject::AttachedObjects::RegisteredFactory key
const auto project
double mF0
Definition: EffectBase.h:105
double mF1
Definition: EffectBase.h:106
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:220
bool SaveUserPreset(const RegistryPath &name, const EffectSettings &settings) const override
Save settings in the configuration file as a user-named preset.
Definition: Effect.cpp:143
OptionalMessage LoadUserPreset(const RegistryPath &name, EffectSettings &settings) const override
Definition: Effect.cpp:130
EffectSettings MakeSettings() const override
Definition: Effect.h:156
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
bool mIsSpectral
Definition: NyquistBase.h:245
bool mEnablePreview
Definition: NyquistBase.h:275
bool SpectralSelectionEnabled() const
static SpectrogramSettings & Get(const WaveTrack &track)
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:967
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287
MessageBoxOptions && IconStyle(Icon style) &&
Definition: BasicUI.h:104

References GlobalHook< GetDisplaysHook, std::vector< WaveChannelSubViewType >(const WaveTrack *)>::Call(), EffectBase::FindProject(), TrackList::Get(), SpectrogramSettings::Get(), BasicUI::MessageBoxOptions::IconStyle(), mDebugButton, mEnablePreview, EffectBase::mF0, EffectBase::mF1, mIsPrompt, mIsSpectral, mName, mPromptName, mPromptType, mType, mVersion, project, TrackList::Selected(), BasicUI::ShowMessageBox(), SpectrogramSettings::SpectralSelectionEnabled(), and XO().

Here is the call graph for this function:

◆ InitializationError()

const TranslatableString & NyquistBase::InitializationError ( ) const
inlineprivate

Definition at line 172 of file NyquistBase.h.

173 {
174 return mInitError;
175 }

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ IsDefault()

bool NyquistBase::IsDefault ( ) const
overridevirtual

Whether the effect sorts "above the line" in the menus.

Reimplemented from Effect.

Definition at line 215 of file NyquistBase.cpp.

216{
217 return mIsPrompt;
218}

References mIsPrompt.

◆ IsInteractive()

bool NyquistBase::IsInteractive ( ) const
overridevirtual

Whether the effect needs a dialog for entry of settings.

Reimplemented from Effect.

Definition at line 205 of file NyquistBase.cpp.

206{
207 if (mIsPrompt)
208 {
209 return true;
210 }
211
212 return mControls.size() != 0;
213}
std::vector< NyqControl > mControls
Definition: NyquistBase.h:287

References mControls, and mIsPrompt.

◆ IsOk()

bool NyquistBase::IsOk ( )

Definition at line 2767 of file NyquistBase.cpp.

2768{
2769 return mOK;
2770}

References mOK.

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ LoadSettings()

bool NyquistBase::LoadSettings ( const CommandParameters parms,
EffectSettings settings 
) const
overridevirtual

Restore settings from keys and values.

Returns
true on success

Reimplemented from Effect.

Definition at line 347 of file NyquistBase.cpp.

349{
350 // To do: externalize state so const_cast isn't needed
351 return const_cast<NyquistBase*>(this)->DoLoadSettings(parms, settings);
352}
static Settings & settings()
Definition: TrackInfo.cpp:51
An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class.
Definition: NyquistBase.h:77
bool DoLoadSettings(const CommandParameters &parms, EffectSettings &settings)

References DoLoadSettings(), and settings().

Referenced by EVT_COMMAND_RANGE(), and VisitSettings().

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

◆ ManualPage()

ManualPageID NyquistBase::ManualPage ( ) const
overridevirtual

Name of a page in the Audacity alpha manual, default is empty.

Reimplemented from EffectDefinitionInterface.

Definition at line 160 of file NyquistBase.cpp.

161{
162 return mIsPrompt ? wxString("Nyquist_Prompt") : mManPage;
163}
wxString mManPage
Definition: NyquistBase.h:268

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

wxString NyquistBase::NyquistToWxString ( const char *  nyqString)
staticprivate

Definition at line 1732 of file NyquistBase.cpp.

1733{
1734 wxString str(nyqString, wxConvUTF8);
1735 if (nyqString != NULL && nyqString[0] && str.empty())
1736 {
1737 // invalid UTF-8 string, convert as Latin-1
1738 str = _(
1739 "[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1740 // TODO: internationalization of strings from Nyquist effects, at least
1741 // from those shipped with Audacity
1742 str += LAT1CTOWX(nyqString);
1743 }
1744 return str;
1745}
#define LAT1CTOWX(X)
Definition: Internat.h:158
#define _(s)
Definition: Internat.h:73

References _, LAT1CTOWX, and str.

Referenced by ProcessOne().

Here is the caller graph for this function:

◆ OSCallback()

void NyquistBase::OSCallback ( )
private

Definition at line 2729 of file NyquistBase.cpp.

2730{
2731 if (mStop)
2732 {
2733 mStop = false;
2734 nyx_stop();
2735 }
2736 else if (mBreak)
2737 {
2738 mBreak = false;
2739 nyx_break();
2740 }
2741 else if (mCont)
2742 {
2743 mCont = false;
2744 nyx_continue();
2745 }
2746
2748}

References GlobalHook< YieldIfNeededHook, void()>::Call(), mBreak, mCont, and mStop.

Here is the call graph for this function:

◆ OutputCallback()

void NyquistBase::OutputCallback ( int  c)
private

Definition at line 2712 of file NyquistBase.cpp.

2713{
2714 // Always collect Nyquist error messages for normal plug-ins
2715 if (!mRedirectOutput)
2716 {
2717 mDebugOutputStr += (wxChar)c;
2718 return;
2719 }
2720
2721 std::cout << (char)c;
2722}
wxString mDebugOutputStr
Definition: NyquistBase.h:281

References mDebugOutputStr, and mRedirectOutput.

◆ Parse()

bool NyquistBase::Parse ( Tokenizer tokenizer,
const wxString &  line,
bool  eof,
bool  first 
)
private

Definition at line 2069 of file NyquistBase.cpp.

2071{
2072 if (!tzer.Tokenize(line, eof, first ? 1 : 0, 0))
2073 return false;
2074
2075 const auto& tokens = tzer.tokens;
2076 int len = tokens.size();
2077 if (len < 1)
2078 {
2079 return true;
2080 }
2081
2082 // Consistency decision is for "plug-in" as the correct spelling
2083 // "plugin" (deprecated) is allowed as an undocumented convenience.
2084 if (
2085 len == 2 && tokens[0] == wxT("nyquist") &&
2086 (tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin")))
2087 {
2088 mOK = true;
2089 return true;
2090 }
2091
2092 if (len >= 2 && tokens[0] == wxT("type"))
2093 {
2094 wxString tok = tokens[1];
2095 mIsTool = false;
2096 if (tok == wxT("tool"))
2097 {
2098 mIsTool = true;
2100 // we allow
2101 // ;type tool
2102 // ;type tool process
2103 // ;type tool generate
2104 // ;type tool analyze
2105 // The last three are placed in the tool menu, but are processed as
2106 // process, generate or analyze.
2107 if (len >= 3)
2108 tok = tokens[2];
2109 }
2110
2111 if (tok == wxT("process"))
2112 {
2114 }
2115 else if (tok == wxT("generate"))
2116 {
2118 }
2119 else if (tok == wxT("analyze"))
2120 {
2122 }
2123
2124 if (len >= 3 && tokens[2] == wxT("spectral"))
2125 {
2126 ;
2127 mIsSpectral = true;
2128 }
2129 return true;
2130 }
2131
2132 if (len == 2 && tokens[0] == wxT("codetype"))
2133 {
2134 // This will stop ParseProgram() from doing a best guess as program type.
2135 if (tokens[1] == wxT("lisp"))
2136 {
2137 mIsSal = false;
2138 mFoundType = true;
2139 }
2140 else if (tokens[1] == wxT("sal"))
2141 {
2142 mIsSal = true;
2143 mFoundType = true;
2144 }
2145 return true;
2146 }
2147
2148 if (len >= 2 && tokens[0] == wxT("debugflags"))
2149 {
2150 for (int i = 1; i < len; i++)
2151 {
2152 // "trace" sets *tracenable* (LISP) or *sal-traceback* (SAL)
2153 // and displays debug window IF there is anything to show.
2154 if (tokens[i] == wxT("trace"))
2155 {
2156 mTrace = true;
2157 }
2158 else if (tokens[i] == wxT("notrace"))
2159 {
2160 mTrace = false;
2161 }
2162 else if (tokens[i] == wxT("compiler"))
2163 {
2164 mCompiler = true;
2165 }
2166 else if (tokens[i] == wxT("nocompiler"))
2167 {
2168 mCompiler = false;
2169 }
2170 }
2171 return true;
2172 }
2173
2174 // We support versions 1, 2 and 3
2175 // (Version 2 added support for string parameters.)
2176 // (Version 3 added support for choice parameters.)
2177 // (Version 4 added support for project/track/selection information.)
2178 if (len >= 2 && tokens[0] == wxT("version"))
2179 {
2180 long v;
2181 tokens[1].ToLong(&v);
2182 if (v < 1 || v > 4)
2183 {
2184 // This is an unsupported plug-in version
2185 mOK = false;
2186 mInitError =
2187 XO("This version of Audacity does not support Nyquist plug-in version %ld")
2188 .Format(v);
2189 return true;
2190 }
2191 mVersion = (int)v;
2192 }
2193
2194 if (len >= 2 && tokens[0] == wxT("name"))
2195 {
2196 // Names do not yet support context strings for translations, or
2197 // internal names distinct from visible English names.
2198 // (See also comments in NyquistEffectsModule::AutoRegisterPlugins)
2199 auto name = UnQuote(tokens[1]);
2200 // Strip ... from name if it's present, perhaps in third party plug-ins
2201 // Menu system puts ... back if there are any controls
2202 // This redundant naming convention must NOT be followed for
2203 // shipped Nyquist effects with internationalization. Else the msgid
2204 // later looked up will lack the ... and will not be found.
2205 if (name.EndsWith(wxT("...")))
2206 name = name.RemoveLast(3);
2207 mName = TranslatableString { name, {} };
2208 return true;
2209 }
2210
2211 if (len >= 2 && tokens[0] == wxT("action"))
2212 {
2213 mAction = TranslatableString { UnQuote(tokens[1]), {} };
2214 return true;
2215 }
2216
2217 if (len >= 2 && tokens[0] == wxT("info"))
2218 {
2219 mInfo = TranslatableString { UnQuote(tokens[1]), {} };
2220 return true;
2221 }
2222
2223 if (len >= 2 && tokens[0] == wxT("preview"))
2224 {
2225 if (tokens[1] == wxT("enabled") || tokens[1] == wxT("true"))
2226 {
2227 mEnablePreview = true;
2228 SetLinearEffectFlag(false);
2229 }
2230 else if (tokens[1] == wxT("linear"))
2231 {
2232 mEnablePreview = true;
2233 SetLinearEffectFlag(true);
2234 }
2235 else if (tokens[1] == wxT("selection"))
2236 {
2237 mEnablePreview = true;
2239 }
2240 else if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false"))
2241 {
2242 mEnablePreview = false;
2243 }
2244 return true;
2245 }
2246
2247 // Maximum number of samples to be processed. This can help the
2248 // progress bar if effect does not process all of selection.
2249 if (len >= 2 && tokens[0] == wxT("maxlen"))
2250 {
2251 long long v; // Note that Nyquist may overflow at > 2^31 samples (bug 439)
2252 tokens[1].ToLongLong(&v);
2253 mMaxLen = (sampleCount)v;
2254 }
2255
2256 if (len >= 2 && tokens[0] == wxT("mergeclips"))
2257 {
2258 long v;
2259 // -1 = auto (default), 0 = don't merge clips, 1 = do merge clips
2260 tokens[1].ToLong(&v);
2261 mMergeClips = v;
2262 return true;
2263 }
2264
2265 if (len >= 2 && tokens[0] == wxT("restoresplits"))
2266 {
2267 long v;
2268 // Splits are restored by default. Set to 0 to prevent.
2269 tokens[1].ToLong(&v);
2270 mRestoreSplits = !!v;
2271 return true;
2272 }
2273
2274 if (len >= 2 && tokens[0] == wxT("author"))
2275 {
2276 mAuthor = TranslatableString { UnQuote(tokens[1]), {} };
2277 return true;
2278 }
2279
2280 if (len >= 2 && tokens[0] == wxT("release"))
2281 {
2282 // Value must be quoted if the release version string contains spaces.
2283 mReleaseVersion = TranslatableString { UnQuote(tokens[1]), {} };
2284 return true;
2285 }
2286
2287 if (len >= 2 && tokens[0] == wxT("copyright"))
2288 {
2289 mCopyright = TranslatableString { UnQuote(tokens[1]), {} };
2290 return true;
2291 }
2292
2293 // Page name in Audacity development manual
2294 if (len >= 2 && tokens[0] == wxT("manpage"))
2295 {
2296 // do not translate
2297 mManPage = UnQuote(tokens[1], false);
2298 return true;
2299 }
2300
2301 // Local Help file
2302 if (len >= 2 && tokens[0] == wxT("helpfile"))
2303 {
2304 // do not translate
2305 mHelpFile = UnQuote(tokens[1], false);
2306 return true;
2307 }
2308
2309 // Debug button may be disabled for release plug-ins.
2310 if (len >= 2 && tokens[0] == wxT("debugbutton"))
2311 {
2312 if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false"))
2313 {
2314 mDebugButton = false;
2315 }
2316 return true;
2317 }
2318
2319 if (len >= 3 && tokens[0] == wxT("control"))
2320 {
2321 NyqControl ctrl;
2322
2323 if (len == 3 && tokens[1] == wxT("text"))
2324 {
2325 ctrl.var = tokens[1];
2326 ctrl.label = UnQuote(tokens[2]);
2327 ctrl.type = NYQ_CTRL_TEXT;
2328 }
2329 else if (len >= 5)
2330 {
2331 ctrl.var = tokens[1];
2332 ctrl.name = UnQuote(tokens[2]);
2333 // 3 is type, below
2334 ctrl.label = tokens[4];
2335
2336 // valStr may or may not be a quoted string
2337 ctrl.valStr = len > 5 ? tokens[5] : wxString {};
2338 ctrl.val = GetCtrlValue(ctrl.valStr);
2339 if (
2340 ctrl.valStr.length() > 0 &&
2341 (ctrl.valStr[0] == wxT('(') || ctrl.valStr[0] == wxT('"')))
2342 ctrl.valStr = UnQuote(ctrl.valStr);
2343
2344 // 6 is minimum, below
2345 // 7 is maximum, below
2346
2347 if (tokens[3] == wxT("string"))
2348 {
2349 ctrl.type = NYQ_CTRL_STRING;
2350 ctrl.label = UnQuote(ctrl.label);
2351 }
2352 else if (tokens[3] == wxT("choice"))
2353 {
2354 ctrl.type = NYQ_CTRL_CHOICE;
2355 ctrl.choices = ParseChoice(ctrl.label);
2356 ctrl.label = wxT("");
2357 }
2358 else if (tokens[3] == wxT("file"))
2359 {
2360 ctrl.type = NYQ_CTRL_FILE;
2361 ctrl.fileTypes = ParseFileTypes(tokens[6]);
2362 // will determine file dialog styles:
2363 ctrl.highStr = UnQuote(tokens[7]);
2364 ctrl.label = UnQuote(ctrl.label);
2365 }
2366 else
2367 {
2368 ctrl.label = UnQuote(ctrl.label);
2369
2370 if (len < 8)
2371 {
2372 return true;
2373 }
2374
2375 if (
2376 (tokens[3] == wxT("float")) ||
2377 (tokens[3] == wxT("real"))) // Deprecated
2378 ctrl.type = NYQ_CTRL_FLOAT;
2379 else if (tokens[3] == wxT("int"))
2380 ctrl.type = NYQ_CTRL_INT;
2381 else if (tokens[3] == wxT("float-text"))
2383 else if (tokens[3] == wxT("int-text"))
2384 ctrl.type = NYQ_CTRL_INT_TEXT;
2385 else if (tokens[3] == wxT("time"))
2386 ctrl.type = NYQ_CTRL_TIME;
2387 else
2388 {
2389 wxString str;
2390 str.Printf(
2391 wxT(
2392 "Bad Nyquist 'control' type specification: '%s' in plug-in file '%s'.\nControl not created."),
2393 tokens[3], mFileName.GetFullPath());
2394
2395 // Too disturbing to show alert before Audacity frame is up.
2396 // EffectUIServices::DoMessageBox(*this,
2397 // str,
2398 // wxOK | wxICON_EXCLAMATION,
2399 // XO("Nyquist Warning") );
2400
2401 // Note that the AudacityApp's mLogger has not yet been created,
2402 // so this brings up an alert box, but after the Audacity frame
2403 // is up.
2404 wxLogWarning(str);
2405 return true;
2406 }
2407
2408 ctrl.lowStr = UnQuote(tokens[6]);
2409 if (
2410 ctrl.type == NYQ_CTRL_INT_TEXT &&
2411 ctrl.lowStr.IsSameAs(wxT("nil"), false))
2412 {
2413 ctrl.low = INT_MIN;
2414 }
2415 else if (
2416 ctrl.type == NYQ_CTRL_FLOAT_TEXT &&
2417 ctrl.lowStr.IsSameAs(wxT("nil"), false))
2418 {
2419 ctrl.low = -(FLT_MAX);
2420 }
2421 else if (
2422 ctrl.type == NYQ_CTRL_TIME &&
2423 ctrl.lowStr.IsSameAs(wxT("nil"), false))
2424 {
2425 ctrl.low = 0.0;
2426 }
2427 else
2428 {
2429 ctrl.low = GetCtrlValue(ctrl.lowStr);
2430 }
2431
2432 ctrl.highStr = UnQuote(tokens[7]);
2433 if (
2434 ctrl.type == NYQ_CTRL_INT_TEXT &&
2435 ctrl.highStr.IsSameAs(wxT("nil"), false))
2436 {
2437 ctrl.high = INT_MAX;
2438 }
2439 else if (
2440 (ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
2441 ctrl.type == NYQ_CTRL_TIME) &&
2442 ctrl.highStr.IsSameAs(wxT("nil"), false))
2443 {
2444 ctrl.high = FLT_MAX;
2445 }
2446 else
2447 {
2448 ctrl.high = GetCtrlValue(ctrl.highStr);
2449 }
2450
2451 if (ctrl.high < ctrl.low)
2452 {
2453 ctrl.high = ctrl.low;
2454 }
2455
2456 if (ctrl.val < ctrl.low)
2457 {
2458 ctrl.val = ctrl.low;
2459 }
2460
2461 if (ctrl.val > ctrl.high)
2462 {
2463 ctrl.val = ctrl.high;
2464 }
2465
2466 ctrl.ticks = 1000;
2467 if (
2468 ctrl.type == NYQ_CTRL_INT && (ctrl.high - ctrl.low < ctrl.ticks))
2469 {
2470 ctrl.ticks = (int)(ctrl.high - ctrl.low);
2471 }
2472 }
2473 }
2474
2475 if (!make_iterator_range(mPresetNames).contains(ctrl.var))
2476 {
2477 mControls.push_back(ctrl);
2478 }
2479 }
2480
2481 // Deprecated
2482 if (len >= 2 && tokens[0] == wxT("categories"))
2483 {
2484 for (size_t i = 1; i < tokens.size(); ++i)
2485 {
2486 mCategories.push_back(tokens[i]);
2487 }
2488 }
2489 return true;
2490}
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeProcess
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
@ NYQ_CTRL_STRING
Definition: NyquistBase.h:32
@ NYQ_CTRL_TEXT
Definition: NyquistBase.h:36
@ NYQ_CTRL_TIME
Definition: NyquistBase.h:37
@ NYQ_CTRL_INT_TEXT
Definition: NyquistBase.h:34
@ NYQ_CTRL_INT
Definition: NyquistBase.h:30
@ NYQ_CTRL_CHOICE
Definition: NyquistBase.h:33
@ NYQ_CTRL_FLOAT_TEXT
Definition: NyquistBase.h:35
@ NYQ_CTRL_FILE
Definition: NyquistBase.h:38
@ NYQ_CTRL_FLOAT
Definition: NyquistBase.h:31
wxString name
Definition: TagsEditor.cpp:166
void SetPreviewFullSelectionFlag(bool previewDurationFlag)
Definition: EffectBase.cpp:215
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:210
wxArrayString mPresetNames
Definition: EffectBase.h:108
A control on a NyquistDialog.
Definition: NyquistBase.h:42
wxString highStr
Definition: NyquistBase.h:58
double high
Definition: NyquistBase.h:61
wxString label
Definition: NyquistBase.h:53
wxString name
Definition: NyquistBase.h:52
wxString var
Definition: NyquistBase.h:51
std::vector< EnumValueSymbol > choices
Definition: NyquistBase.h:54
wxString valStr
Definition: NyquistBase.h:56
double low
Definition: NyquistBase.h:60
double val
Definition: NyquistBase.h:59
FileNames::FileTypes fileTypes
Definition: NyquistBase.h:55
wxString lowStr
Definition: NyquistBase.h:57
bool mFoundType
Definition: NyquistBase.h:240
wxArrayString mCategories
Definition: NyquistBase.h:297
static std::vector< EnumValueSymbol > ParseChoice(const wxString &text)
static wxString UnQuote(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
FileNames::FileTypes ParseFileTypes(const wxString &text)
static double GetCtrlValue(const wxString &s)
TranslatableString mInfo
Definition: NyquistBase.h:261
Holds a msgid for the translation catalog; may also bind format arguments.
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19

References NyqControl::choices, EffectTypeAnalyze, EffectTypeGenerate, EffectTypeProcess, EffectTypeTool, NyqControl::fileTypes, GetCtrlValue(), NyqControl::high, NyqControl::highStr, NyqControl::label, NyqControl::low, NyqControl::lowStr, mAction, make_iterator_range(), mAuthor, mCategories, mCompiler, mControls, mCopyright, mDebugButton, mEnablePreview, mFileName, mFoundType, mHelpFile, mInfo, mInitError, mIsSal, mIsSpectral, mIsTool, mManPage, mMaxLen, mMergeClips, mName, mOK, EffectBase::mPresetNames, mReleaseVersion, mRestoreSplits, mTrace, mType, mVersion, NyqControl::name, name, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TEXT, NYQ_CTRL_TIME, ParseChoice(), ParseFileTypes(), EffectBase::SetLinearEffectFlag(), EffectBase::SetPreviewFullSelectionFlag(), str, NyqControl::ticks, NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, NyqControl::type, UnQuote(), NyqControl::val, NyqControl::valStr, NyqControl::var, wxT(), and XO().

Referenced by ParseProgram().

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

◆ ParseChoice()

std::vector< EnumValueSymbol > NyquistBase::ParseChoice ( const wxString &  text)
staticprivate

Definition at line 1757 of file NyquistBase.cpp.

1758{
1759 std::vector<EnumValueSymbol> results;
1760 if (text[0] == wxT('('))
1761 {
1762 // New style: expecting a Lisp-like list of strings
1763 Tokenizer tzer;
1764 tzer.Tokenize(text, true, 1, 1);
1765 auto& choices = tzer.tokens;
1766 wxString extra;
1767 for (auto& choice : choices)
1768 {
1769 auto label = UnQuote(choice, true, &extra);
1770 if (extra.empty())
1771 results.push_back(TranslatableString { label, {} });
1772 else
1773 results.push_back({ extra, TranslatableString { label, {} } });
1774 }
1775 }
1776 else
1777 {
1778 // Old style: expecting a comma-separated list of
1779 // un-internationalized names, ignoring leading and trailing spaces
1780 // on each; and the whole may be quoted
1781 auto choices = wxStringTokenize(
1782 text[0] == wxT('"') ? text.Mid(1, text.length() - 2) : text, wxT(","));
1783 for (auto& choice : choices)
1784 results.push_back({ choice.Trim(true).Trim(false) });
1785 }
1786 return results;
1787}
TranslatableString label
Definition: TagsEditor.cpp:165

References label, NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, UnQuote(), and wxT().

Referenced by Parse().

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

◆ ParseCommand()

bool NyquistBase::ParseCommand ( const wxString &  cmd)
protected

Definition at line 2601 of file NyquistBase.cpp.

2602{
2603 wxStringInputStream stream(cmd + wxT(" "));
2604
2605 return ParseProgram(stream);
2606}
bool ParseProgram(wxInputStream &stream)

References ParseProgram(), and wxT().

Referenced by DoLoadSettings(), SetCommand(), and NyquistEffect::TransferDataFromPromptWindow().

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

◆ ParseFile()

void NyquistBase::ParseFile ( )
private

Definition at line 2593 of file NyquistBase.cpp.

2594{
2595 wxFileInputStream rawStream(mFileName.GetFullPath());
2596 wxBufferedInputStream stream(rawStream, 10000);
2597
2598 ParseProgram(stream);
2599}

References mFileName, and ParseProgram().

Referenced by NyquistBase().

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

◆ ParseFileExtensions()

FileExtensions NyquistBase::ParseFileExtensions ( const wxString &  text)
private

Definition at line 1789 of file NyquistBase.cpp.

1790{
1791 // todo: error handling
1792 FileExtensions results;
1793 if (text[0] == wxT('('))
1794 {
1795 Tokenizer tzer;
1796 tzer.Tokenize(text, true, 1, 1);
1797 for (const auto& token : tzer.tokens)
1798 results.push_back(UnQuote(token));
1799 }
1800 return results;
1801}

References NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, UnQuote(), and wxT().

Referenced by ParseFileType().

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

◆ ParseFileType()

FileNames::FileType NyquistBase::ParseFileType ( const wxString &  text)
private

Definition at line 1803 of file NyquistBase.cpp.

1804{
1805 // todo: error handling
1806 FileNames::FileType result;
1807 if (text[0] == wxT('('))
1808 {
1809 Tokenizer tzer;
1810 tzer.Tokenize(text, true, 1, 1);
1811 auto& tokens = tzer.tokens;
1812 if (tokens.size() == 2)
1813 result = { UnQuoteMsgid(tokens[0]), ParseFileExtensions(tokens[1]) };
1814 }
1815 return result;
1816}
FileExtensions ParseFileExtensions(const wxString &text)
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)

References ParseFileExtensions(), NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, UnQuoteMsgid(), and wxT().

Referenced by ParseFileTypes().

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

◆ ParseFileTypes()

FileNames::FileTypes NyquistBase::ParseFileTypes ( const wxString &  text)
private

Definition at line 1818 of file NyquistBase.cpp.

1819{
1820 // todo: error handling
1821 FileNames::FileTypes results;
1822 if (text[0] == wxT('('))
1823 {
1824 Tokenizer tzer;
1825 tzer.Tokenize(text, true, 1, 1);
1826 auto& types = tzer.tokens;
1827 if (!types.empty() && types[0][0] == wxT('('))
1828 for (auto& type : types)
1829 results.push_back(ParseFileType(type));
1830 }
1831 if (results.empty())
1832 {
1833 // Old-style is a specially formatted string, maybe translated
1834 // Parse it for compatibility
1835 auto str = UnQuote(text);
1836 auto pieces = wxSplit(str, '|');
1837 // Should have an even number
1838 auto size = pieces.size();
1839 if (size % 2 == 1)
1840 --size, pieces.pop_back();
1841 for (size_t ii = 0; ii < size; ii += 2)
1842 {
1843 FileExtensions extensions;
1844 auto extensionStrings = wxSplit(pieces[ii + 1], ';');
1845 for (const auto& extensionString : extensionStrings)
1846 if (extensionString.StartsWith(wxT("*.")))
1847 {
1848 auto ext = extensionString.substr(2);
1849 if (ext == wxT("*"))
1850 // "*.*" to match all
1851 ext.clear();
1852 extensions.push_back(ext);
1853 }
1854 results.push_back({ Verbatim(pieces[ii]), extensions });
1855 }
1856 }
1857 return results;
1858}
std::vector< FileType > FileTypes
Definition: FileNames.h:75
FileNames::FileType ParseFileType(const wxString &text)

References ParseFileType(), size, str, NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, UnQuote(), Verbatim(), and wxT().

Referenced by Parse().

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

◆ ParseProgram()

bool NyquistBase::ParseProgram ( wxInputStream &  stream)
private

Definition at line 2492 of file NyquistBase.cpp.

2493{
2494 if (!stream.IsOk())
2495 {
2496 mInitError = XO("Could not open file");
2497 return false;
2498 }
2499
2500 wxTextInputStream pgm(stream, wxT(" \t"), wxConvAuto());
2501
2502 mCmd = wxT("");
2503 mCmd.Alloc(10000);
2504 mIsSal = false;
2505 mControls.clear();
2506 mCategories.clear();
2507 mIsSpectral = false;
2508 mManPage = wxEmptyString; // If not wxEmptyString, must be a page in the
2509 // Audacity manual.
2510 mHelpFile =
2511 wxEmptyString; // If not wxEmptyString, must be a valid HTML help file.
2512 mHelpFileExists = false;
2513 mDebug = false;
2514 mTrace = false;
2515 mDebugButton = true; // Debug button enabled by default.
2516 mEnablePreview = true; // Preview button enabled by default.
2517
2518 // Bug 1934.
2519 // All Nyquist plug-ins should have a ';type' field, but if they don't we
2520 // default to being an Effect.
2522
2523 mFoundType = false;
2524 while (!stream.Eof() && stream.IsOk())
2525 {
2526 wxString line = pgm.ReadLine();
2527 if (
2528 line.length() > 1 &&
2529 // New in 2.3.0: allow magic comment lines to start with $
2530 // The trick is that xgettext will not consider such lines comments
2531 // and will extract the strings they contain
2532 (line[0] == wxT(';') || line[0] == wxT('$')))
2533 {
2534 Tokenizer tzer;
2535 unsigned nLines = 1;
2536 bool done;
2537 // Allow continuations within control lines.
2538 bool control = line[0] == wxT('$') || line.StartsWith(wxT(";control"));
2539 do
2540 done = Parse(tzer, line, !control || stream.Eof(), nLines == 1);
2541 while (!done && (line = pgm.ReadLine(), ++nLines, true));
2542
2543 // Don't pass these lines to the interpreter, so it doesn't get
2544 // confused by $, but pass blanks, so that SAL effects compile with
2545 // proper line numbers
2546 while (nLines--)
2547 mCmd += wxT('\n');
2548 }
2549 else
2550 {
2551 if (!mFoundType && line.length() > 0)
2552 {
2553 if (
2554 line[0] == wxT('(') ||
2555 (line[0] == wxT('#') && line.length() > 1 &&
2556 line[1] == wxT('|')))
2557 {
2558 mIsSal = false;
2559 mFoundType = true;
2560 }
2561 else if (line.Upper().Find(wxT("RETURN")) != wxNOT_FOUND)
2562 {
2563 mIsSal = true;
2564 mFoundType = true;
2565 }
2566 }
2567 mCmd += line + wxT("\n");
2568 }
2569 }
2570 if (!mFoundType && mIsPrompt)
2571 {
2572 using namespace BasicUI;
2573 /* i1n-hint: SAL and LISP are names for variant syntaxes for the
2574 Nyquist programming language. Leave them, and 'return', untranslated. */
2576 XO("Your code looks like SAL syntax, but there is no \'return\' statement.\n\
2577For SAL, use a return statement such as:\n\treturn *track* * 0.1\n\
2578or for LISP, begin with an open parenthesis such as:\n\t(mult *track* 0.1)\n ."),
2579 MessageBoxOptions {}.IconStyle(Icon::Error));
2580 /* i18n-hint: refers to programming "languages" */
2581 mInitError = XO("Could not determine language");
2582 return false;
2583 // Else just throw it at Nyquist to see what happens
2584 }
2585
2586 const auto helpStuff = CheckHelpPage();
2587 mHelpFileExists = helpStuff.first;
2588 mHelpPage = helpStuff.second;
2589
2590 return true;
2591}
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
bool mHelpFileExists
Definition: NyquistBase.h:270
wxString mCmd
Definition: NyquistBase.h:256
std::pair< bool, FilePath > CheckHelpPage() const

References CheckHelpPage(), EffectTypeProcess, BasicUI::MessageBoxOptions::IconStyle(), mCategories, mCmd, mControls, mDebug, mDebugButton, mEnablePreview, mFoundType, mHelpFile, mHelpFileExists, mHelpPage, mInitError, mIsPrompt, mIsSal, mIsSpectral, mManPage, mTrace, mType, Parse(), BasicUI::ShowMessageBox(), wxT(), and XO().

Referenced by ParseCommand(), and ParseFile().

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

◆ Process()

bool NyquistBase::Process ( EffectInstance instance,
EffectSettings settings 
)
overridevirtual

Implements StatefulEffectBase.

Definition at line 644 of file NyquistBase.cpp.

645{
646 if (mIsPrompt && mControls.size() > 0 && !IsBatchProcessing())
647 {
648 auto& nyquistSettings = GetSettings(settings);
649 auto cleanup = finally([&] {
650 // Free up memory
651 nyquistSettings.proxySettings = {};
652 });
654 proxy.SetCommand(mInputCmd);
655 proxy.mDebug = nyquistSettings.proxyDebug;
656 proxy.mControls = move(nyquistSettings.controls);
657 auto result = Delegate(proxy, nyquistSettings.proxySettings);
658 if (result)
659 {
660 mT0 = proxy.mT0;
661 mT1 = proxy.mT1;
662 }
663 return result;
664 }
665
666 // Check for reentrant Nyquist commands.
667 // I'm choosing to mark skipped Nyquist commands as successful even though
668 // they are skipped. The reason is that when Nyquist calls out to a chain,
669 // and that chain contains Nyquist, it will be clearer if the chain
670 // completes skipping Nyquist, rather than doing nothing at all.
671 if (mReentryCount > 0)
672 return true;
673
674 // Restore the reentry counter (to zero) when we exit.
675 auto countRestorer = valueRestorer(mReentryCount);
678
679 bool success = true;
680 int nEffectsSoFar = EffectOutputTracks::nEffectsDone;
681 mProjectChanged = false;
683 em.SetSkipStateFlag(false);
684
685 // This code was added in a fix for bug 2392 (no preview for Nyquist)
686 // It was commented out in a fix for bug 2428 (no progress dialog from a
687 // macro)
688 // if (mExternal) {
689 // mProgress->Hide();
690 //}
691
692 mOutputTime = 0;
693 mCount = 0;
694 const auto scale =
695 (GetType() == EffectTypeProcess ? 0.5 : 1.0) / GetNumWaveGroups();
696
697 mStop = false;
698 mBreak = false;
699 mCont = false;
700
701 mTrackIndex = 0;
702
703 // If in tool mode, then we don't do anything with the track and selection.
704 const bool bOnePassTool = (GetType() == EffectTypeTool);
705
706 // We must copy all the tracks, because Paste needs label tracks to ensure
707 // correct sync-lock group behavior when the timeline is affected; then we
708 // just want to operate on the selected wave tracks
709 std::optional<EffectOutputTracks> oOutputs;
710 if (!bOnePassTool)
711 oOutputs.emplace(
713 true, false);
714
716 bOnePassTool ?
717 0 :
718 oOutputs->Get().Selected<const WaveTrack>().sum(&WaveTrack::NChannels);
719
720 mDebugOutput = {};
721 if (!mHelpFile.empty() && !mHelpFileExists)
722 {
724 XO("error: File \"%s\" specified in header but not found in plug-in path.\n")
725 .Format(mHelpFile);
726 }
727
728 if (mVersion >= 4)
729 {
730 auto project = FindProject();
731
732 mProps = wxEmptyString;
733
734 mProps += wxString::Format(
735 wxT("(putprop '*AUDACITY* (list %d %d %d) 'VERSION)\n"),
736 AUDACITY_VERSION, AUDACITY_RELEASE, AUDACITY_REVISION);
737 wxString lang = gPrefs->Read(wxT("/Locale/Language"), wxT(""));
738 lang =
739 (lang.empty()) ?
741 lang;
742 mProps += wxString::Format(
743 wxT("(putprop '*AUDACITY* \"%s\" 'LANGUAGE)\n"), lang);
744
745 mProps += wxString::Format(
746 wxT("(setf *DECIMAL-SEPARATOR* #\\%c)\n"),
747 wxNumberFormatter::GetDecimalSeparator());
748
749 mProps += wxString::Format(
750 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'BASE)\n"),
752 mProps += wxString::Format(
753 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'DATA)\n"),
755 mProps += wxString::Format(
756 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'HELP)\n"),
757 EscapeString(FileNames::HtmlHelpDir().RemoveLast()));
758 mProps += wxString::Format(
759 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'TEMP)\n"),
761 mProps += wxString::Format(
762 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'SYS-TEMP)\n"),
764 mProps += wxString::Format(
765 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'DOCUMENTS)\n"),
767 mProps += wxString::Format(
768 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'HOME)\n"),
770
772 wxString list;
773 for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
774 {
775 list += wxT("\"") + EscapeString(paths[i]) + wxT("\" ");
776 }
777 list = list.RemoveLast();
778
779 mProps += wxString::Format(
780 wxT("(putprop '*SYSTEM-DIR* (list %s) 'PLUGIN)\n"), list);
781 mProps += wxString::Format(
782 wxT("(putprop '*SYSTEM-DIR* (list %s) 'PLUG-IN)\n"), list);
783 mProps += wxString::Format(
784 wxT("(putprop '*SYSTEM-DIR* \"%s\" 'USER-PLUG-IN)\n"),
786
787 // Date and time:
788 wxDateTime now = wxDateTime::Now();
789 int year = now.GetYear();
790 int doy = now.GetDayOfYear();
791 int dom = now.GetDay();
792 // enumerated constants
793 wxDateTime::Month month = now.GetMonth();
794 wxDateTime::WeekDay day = now.GetWeekDay();
795
796 // Date/time as a list: year, day of year, hour, minute, seconds
797 mProps += wxString::Format(
798 wxT("(setf *SYSTEM-TIME* (list %d %d %d %d %d))\n"), year, doy,
799 now.GetHour(), now.GetMinute(), now.GetSecond());
800
801 mProps += wxString::Format(
802 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DATE)\n"), now.FormatDate());
803 mProps += wxString::Format(
804 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'TIME)\n"), now.FormatTime());
805 mProps += wxString::Format(
806 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'ISO-DATE)\n"),
807 now.FormatISODate());
808 mProps += wxString::Format(
809 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'ISO-TIME)\n"),
810 now.FormatISOTime());
811 mProps +=
812 wxString::Format(wxT("(putprop '*SYSTEM-TIME* %d 'YEAR)\n"), year);
813 mProps += wxString::Format(
814 wxT("(putprop '*SYSTEM-TIME* %d 'DAY)\n"), dom); // day of month
815 mProps +=
816 wxString::Format(wxT("(putprop '*SYSTEM-TIME* %d 'MONTH)\n"), month);
817 mProps += wxString::Format(
818 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'MONTH-NAME)\n"),
819 now.GetMonthName(month));
820 mProps += wxString::Format(
821 wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"),
822 now.GetWeekDayName(day));
823
824 mProps += wxString::Format(
825 wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"),
826 (int)AllProjects {}.size());
827 mProps += wxString::Format(
828 wxT("(putprop '*PROJECT* \"%s\" 'NAME)\n"),
829 EscapeString(project->GetProjectName()));
830
831 int numTracks = 0;
832 int numWave = 0;
833 int numLabel = 0;
834 int numMidi = 0;
835 int numTime = 0;
836 wxString waveTrackList; // track positions of selected audio tracks.
837
838 {
839 auto countRange = TrackList::Get(*project).Any();
840 for (auto t : countRange)
841 {
842 t->TypeSwitch([&](const WaveTrack&) {
843 numWave++;
844 if (t->GetSelected())
845 waveTrackList += wxString::Format(wxT("%d "), 1 + numTracks);
846 });
847 numTracks++;
848 }
849 numLabel = countRange.Filter<const LabelTrack>().size();
850#if defined(USE_MIDI)
851 numMidi = countRange.Filter<const NoteTrack>().size();
852#endif
853 numTime = countRange.Filter<const TimeTrack>().size();
854 }
855
856 // We use Internat::ToString() rather than "%g" here because we
857 // always have to use the dot as decimal separator when giving
858 // numbers to Nyquist, whereas using "%g" will use the user's
859 // decimal separator which may be a comma in some countries.
860 mProps += wxString::Format(
861 wxT("(putprop '*PROJECT* (float %s) 'RATE)\n"),
863 mProps +=
864 wxString::Format(wxT("(putprop '*PROJECT* %d 'TRACKS)\n"), numTracks);
865 mProps += wxString::Format(
866 wxT("(putprop '*PROJECT* %d 'WAVETRACKS)\n"), numWave);
867 mProps += wxString::Format(
868 wxT("(putprop '*PROJECT* %d 'LABELTRACKS)\n"), numLabel);
869 mProps += wxString::Format(
870 wxT("(putprop '*PROJECT* %d 'MIDITRACKS)\n"), numMidi);
871 mProps += wxString::Format(
872 wxT("(putprop '*PROJECT* %d 'TIMETRACKS)\n"), numTime);
873
874 double previewLen = 6.0;
875 gPrefs->Read(wxT("/AudioIO/EffectsPreviewLen"), &previewLen);
876 mProps += wxString::Format(
877 wxT("(putprop '*PROJECT* (float %s) 'PREVIEW-DURATION)\n"),
878 Internat::ToString(previewLen));
879
880 // *PREVIEWP* is true when previewing (better than relying on track view).
881 wxString isPreviewing = (this->IsPreviewing()) ? wxT("T") : wxT("NIL");
882 mProps += wxString::Format(wxT("(setf *PREVIEWP* %s)\n"), isPreviewing);
883
884 mProps += wxString::Format(
885 wxT("(putprop '*SELECTION* (list %s) 'TRACKS)\n"), waveTrackList);
886 mProps += wxString::Format(
887 wxT("(putprop '*SELECTION* %d 'CHANNELS)\n"), mNumSelectedChannels);
888 }
889
890 // Nyquist Prompt does not require a selection, but effects do.
891 if (!bOnePassTool && (mNumSelectedChannels == 0))
892 {
893 auto message = XO("Audio selection required.");
894 using namespace BasicUI;
896 message, MessageBoxOptions {}.IconStyle(Icon::Error));
897 }
898
899 std::optional<TrackIterRange<WaveTrack>> pRange;
900 if (!bOnePassTool)
901 pRange.emplace(oOutputs->Get().Selected<WaveTrack>());
902
903 // Keep track of whether the current track is first selected in its sync-lock
904 // group (we have no idea what the length of the returned audio will be, so
905 // we have to handle sync-lock group behavior the "old" way).
906 mFirstInGroup = true;
907 Track* gtLast = NULL;
908 double progressTot {};
909
910 for (; bOnePassTool || pRange->first != pRange->second;
911 (void)(!pRange || (++pRange->first, true)))
912 {
913 // Prepare to accumulate more debug output in OutputCallback
915 mDebugOutput = Verbatim("%s").Format(std::cref(mDebugOutputStr));
916
917 // New context for each channel group of input
918 NyxContext nyxContext {
919 [this](double frac) { return TotalProgress(frac); }, scale, progressTot
920 };
921 auto& mCurNumChannels = nyxContext.mCurNumChannels;
922 auto& mCurChannelGroup = nyxContext.mCurChannelGroup;
923 auto& mCurTrack = nyxContext.mCurTrack;
924 auto& mCurStart = nyxContext.mCurStart;
925 auto& mCurLen = nyxContext.mCurLen;
926
927 mCurChannelGroup = pRange ? *pRange->first : nullptr;
928 mCurTrack[0] = mCurChannelGroup ?
929 (*mCurChannelGroup->Channels().begin()).get() :
930 nullptr;
931 mCurNumChannels = 1;
932 assert(mCurChannelGroup != nullptr || bOnePassTool);
933 if ((mT1 >= mT0) || bOnePassTool)
934 {
935 if (bOnePassTool)
936 {
937 }
938 else
939 {
940 if (auto channels = mCurChannelGroup->Channels();
941 channels.size() > 1)
942 {
943 // TODO: more-than-two-channels
944 // Pay attention to consistency of mNumSelectedChannels
945 // with the running tally made by this loop!
946 mCurNumChannels = 2;
947
948 mCurTrack[1] = (*++channels.first).get();
949 }
950
951 // Check whether we're in the same group as the last selected track
952 Track* gt = *SyncLock::Group(*mCurChannelGroup).first;
953 mFirstInGroup = !gtLast || (gtLast != gt);
954 gtLast = gt;
955
956 mCurStart = mCurChannelGroup->TimeToLongSamples(mT0);
957 auto end = mCurChannelGroup->TimeToLongSamples(mT1);
958 mCurLen = end - mCurStart;
959
960 wxASSERT(mCurLen <= NYQ_MAX_LEN);
961
962 mCurLen = std::min(mCurLen, mMaxLen);
963 }
964
965 // libnyquist breaks except in LC_NUMERIC=="C".
966 //
967 // Note that we must set the locale to "C" even before calling
968 // nyx_init() because otherwise some effects will not work!
969 //
970 // MB: setlocale is not thread-safe. Should use uselocale()
971 // if available, or fix libnyquist to be locale-independent.
972 // See also http://bugzilla.audacityteam.org/show_bug.cgi?id=642#c9
973 // for further info about this thread safety question.
974 wxString prevlocale = wxSetlocale(LC_NUMERIC, NULL);
975 wxSetlocale(LC_NUMERIC, wxString(wxT("C")));
976
977 nyx_init();
978 nyx_set_os_callback(StaticOSCallback, (void*)this);
979 nyx_capture_output(StaticOutputCallback, (void*)this);
980
981 auto cleanup = finally([&] {
982 nyx_capture_output(NULL, (void*)NULL);
983 nyx_set_os_callback(NULL, (void*)NULL);
984 nyx_cleanup();
985 });
986
987 if (mVersion >= 4)
988 {
989 mPerTrackProps = wxEmptyString;
990 wxString lowHz = wxT("nil");
991 wxString highHz = wxT("nil");
992 wxString centerHz = wxT("nil");
993 wxString bandwidth = wxT("nil");
994
995 if (mF0 >= 0.0)
996 {
997 lowHz.Printf(wxT("(float %s)"), Internat::ToString(mF0));
998 }
999
1000 if (mF1 >= 0.0)
1001 {
1002 highHz.Printf(wxT("(float %s)"), Internat::ToString(mF1));
1003 }
1004
1005 if ((mF0 >= 0.0) && (mF1 >= 0.0))
1006 {
1007 centerHz.Printf(
1008 wxT("(float %s)"), Internat::ToString(sqrt(mF0 * mF1)));
1009 }
1010
1011 if ((mF0 > 0.0) && (mF1 >= mF0))
1012 {
1013 // with very small values, bandwidth calculation may be inf.
1014 // (Observed on Linux)
1015 double bw = log(mF1 / mF0) / log(2.0);
1016 if (!std::isinf(bw))
1017 {
1018 bandwidth.Printf(wxT("(float %s)"), Internat::ToString(bw));
1019 }
1020 }
1021
1022 mPerTrackProps += wxString::Format(
1023 wxT("(putprop '*SELECTION* %s 'LOW-HZ)\n"), lowHz);
1024 mPerTrackProps += wxString::Format(
1025 wxT("(putprop '*SELECTION* %s 'CENTER-HZ)\n"), centerHz);
1026 mPerTrackProps += wxString::Format(
1027 wxT("(putprop '*SELECTION* %s 'HIGH-HZ)\n"), highHz);
1028 mPerTrackProps += wxString::Format(
1029 wxT("(putprop '*SELECTION* %s 'BANDWIDTH)\n"), bandwidth);
1030
1031 const auto t0 =
1032 mCurChannelGroup ? mCurChannelGroup->SnapToSample(mT0) : mT0;
1033 const auto t1 =
1034 mCurChannelGroup ? mCurChannelGroup->SnapToSample(mT1) : mT1;
1035 mPerTrackProps += wxString::Format(
1036 wxT("(putprop '*SELECTION* (float %s) 'START)\n"),
1037 Internat::ToString(t0));
1038 mPerTrackProps += wxString::Format(
1039 wxT("(putprop '*SELECTION* (float %s) 'END)\n"),
1040 Internat::ToString(t1));
1041 }
1042
1043 success = ProcessOne(nyxContext, oOutputs ? &*oOutputs : nullptr);
1044
1045 // Reset previous locale
1046 wxSetlocale(LC_NUMERIC, prevlocale);
1047
1048 if (!success || bOnePassTool)
1049 {
1050 goto finish;
1051 }
1052 progressTot += nyxContext.mProgressIn + nyxContext.mProgressOut;
1053 }
1054
1055 mCount += mCurNumChannels;
1056 }
1057
1058 if (mOutputTime > 0.0)
1059 {
1060 mT1 = mT0 + mOutputTime;
1061 }
1062
1063finish:
1064
1065 // Show debug window if trace set in plug-in header and something to show.
1066 mDebug = (mTrace && !mDebugOutput.Translation().empty()) ? true : mDebug;
1067
1068 if (mDebug && !mRedirectOutput)
1070
1071 // Has rug been pulled from under us by some effect done within Nyquist??
1072 if (!bOnePassTool && (nEffectsSoFar == EffectOutputTracks::nEffectsDone))
1073 {
1074 if (success)
1075 oOutputs->Commit();
1076 }
1077 else
1078 {
1079 // Do not use the results.
1080 // Selection is to be set to whatever it is in the project.
1081 auto project = FindProject();
1082 if (project)
1083 {
1084 auto& selectedRegion = ViewInfo::Get(*project).selectedRegion;
1085 mT0 = selectedRegion.t0();
1086 mT1 = selectedRegion.t1();
1087 }
1088 else
1089 {
1090 mT0 = 0;
1091 mT1 = -1;
1092 }
1093 }
1094
1095 if (!mProjectChanged)
1096 em.SetSkipStateFlag(true);
1097
1098 return success;
1099}
int min(int a, int b)
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:253
static void RegisterFunctions()
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
size_t size() const
Definition: Project.cpp:17
double mT1
Definition: EffectBase.h:123
bool IsPreviewing() const
Definition: EffectBase.h:100
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:116
double mT0
Definition: EffectBase.h:122
bool Delegate(Effect &delegate, EffectSettings &settings, InstanceFinder finder={})
Re-invoke DoEffect on another Effect object that implements the work.
Definition: Effect.cpp:322
bool TotalProgress(double frac, const TranslatableString &={}) const
Definition: Effect.cpp:335
int GetNumWaveGroups() const
Definition: Effect.h:140
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:52
void SetSkipStateFlag(bool flag)
static EffectManager & Get()
std::pair< double, double > TimeInterval
static NyquistSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:166
static wxString ToString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, always uses the dot as decimal separator.
Definition: Internat.cpp:126
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:98
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:78
wxString EscapeString(const wxString &inStr)
bool ProcessOne(NyxContext &nyxContext, EffectOutputTracks *pOutputs)
EffectType GetType() const override
Type determines how it behaves.
wxString mProps
Definition: NyquistBase.h:299
static int mReentryCount
Definition: NyquistBase.h:166
static void StaticOSCallback(void *userdata)
unsigned mNumSelectedChannels
Definition: NyquistBase.h:295
static void StaticOutputCallback(int c, void *userdata)
unsigned mCount
Definition: NyquistBase.h:294
TranslatableString mDebugOutput
Definition: NyquistBase.h:282
bool mProjectChanged
Definition: NyquistBase.h:280
bool mFirstInGroup
Definition: NyquistBase.h:292
wxString mPerTrackProps
Definition: NyquistBase.h:300
double mOutputTime
Definition: NyquistBase.h:293
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
static TrackIterRange< Track > Group(Track &track)
Definition: SyncLock.cpp:150
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:950
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:216
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
size_t NChannels() const override
A constant property.
Definition: WaveTrack.cpp:530
virtual bool Read(const wxString &key, bool *value) const =0
FILES_API FilePath HtmlHelpDir()
FILES_API FilePath BaseDir()
FILES_API FilePath DataDir()
Audacity user data directory.
wxString GetSystemLanguageCode(const FilePaths &pathList)
Definition: Languages.cpp:83
std::string FILES_API GetDocumentsDir()
std::string FILES_API GetTempDir()
std::string FILES_API GetHomeDir()
FILES_API wxString TempDir()
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
__finl float_x4 __vecc sqrt(const float_x4 &a)

References TrackList::Any(), FileNames::AudacityPathList(), FileNames::BaseDir(), GlobalHook< ShowDebugOutputHook, void(const TranslatableString &title, const TranslatableString &message)>::Call(), FileNames::DataDir(), Effect::Delegate(), EffectTypeProcess, EffectTypeTool, details::end(), EscapeString(), EffectBase::FindProject(), TranslatableString::Format(), EffectManager::Get(), ProjectRate::Get(), ViewInfo::Get(), TrackList::Get(), PlatformCompatibility::GetDocumentsDir(), PlatformCompatibility::GetHomeDir(), Effect::GetNumWaveGroups(), GetNyquistSearchPath(), ProjectRate::GetRate(), EffectWithSettings< NyquistSettings, StatefulEffect >::GetSettings(), Languages::GetSystemLanguageCode(), PlatformCompatibility::GetTempDir(), GetType(), gPrefs, SyncLock::Group(), FileNames::HtmlHelpDir(), BasicUI::MessageBoxOptions::IconStyle(), Effect::IsBatchProcessing(), EffectBase::IsPreviewing(), mBreak, mCont, mControls, mCount, mDebug, mDebugOutput, mDebugOutputStr, EffectBase::mF0, EffectBase::mF1, mFirstInGroup, mHelpFile, mHelpFileExists, min(), mInputCmd, mIsPrompt, mMaxLen, mName, mNumSelectedChannels, mOutputTime, mPerTrackProps, mProjectChanged, mProps, mRedirectOutput, mReentryCount, mStop, EffectBase::mT0, EffectBase::mT1, mTrace, mTrackIndex, EffectBase::mTracks, mVersion, WaveTrack::NChannels(), EffectOutputTracks::nEffectsDone, NYQ_MAX_LEN, NYQUIST_WORKER_ID, FileNames::PlugInDir(), ProcessOne(), project, audacity::BasicSettings::Read(), RegisterFunctions(), ViewInfo::selectedRegion, EffectManager::SetSkipStateFlag(), settings(), BasicUI::ShowMessageBox(), AllProjects::size(), size, staffpad::audio::simd::sqrt(), StaticOSCallback(), StaticOutputCallback(), TempDirectory::TempDir(), Internat::ToString(), Effect::TotalProgress(), TranslatableString::Translation(), valueRestorer(), Verbatim(), wxT(), and XO().

Here is the call graph for this function:

◆ ProcessOne()

bool NyquistBase::ProcessOne ( NyxContext nyxContext,
EffectOutputTracks pOutputs 
)
private

Definition at line 1139 of file NyquistBase.cpp.

1141{
1142 const auto mCurNumChannels = nyxContext.mCurNumChannels;
1143 nyx_rval rval;
1144
1145 wxString cmd;
1146 cmd += wxT("(snd-set-latency 0.1)");
1147
1148 // A tool may be using AUD-DO which will potentially invalidate *TRACK*
1149 // so tools do not get *TRACK*.
1150 if (GetType() == EffectTypeTool)
1151 cmd += wxT("(setf S 0.25)\n"); // No Track.
1152 else if (mVersion >= 4)
1153 {
1154 nyx_set_audio_name("*TRACK*");
1155 cmd += wxT("(setf S 0.25)\n");
1156 }
1157 else
1158 {
1159 nyx_set_audio_name("S");
1160 cmd += wxT("(setf *TRACK* '*unbound*)\n");
1161 }
1162
1163 if (mVersion >= 4)
1164 {
1165 cmd += mProps;
1166 cmd += mPerTrackProps;
1167 }
1168
1169 const auto& mCurChannelGroup = nyxContext.mCurChannelGroup;
1170
1171 if ((mVersion >= 4) && (GetType() != EffectTypeTool))
1172 {
1173 // Set the track TYPE and VIEW properties
1174 wxString type;
1175 wxString view;
1176 wxString bitFormat;
1177 wxString spectralEditp;
1178
1179 mCurChannelGroup->TypeSwitch(
1180 [&](const WaveTrack& wt) {
1181 type = wxT("wave");
1182 spectralEditp = SpectrogramSettings::Get(*mCurChannelGroup)
1184 wxT("T") :
1185 wxT("NIL");
1186 view = wxT("NIL");
1187 // Find() not Get() to avoid creation-on-demand of views in case we
1188 // are only previewing
1189 const auto displays = GetDisplaysHook::Call(&wt);
1190 const auto format = [&](decltype(displays[0]) display) {
1191 // Get the English name of the view type, without menu codes,
1192 // as a string that Lisp can examine
1193 return wxString::Format(
1194 wxT("\"%s\""), display.name.Stripped().Debug());
1195 };
1196 if (displays.empty())
1197 ;
1198 else if (displays.size() == 1)
1199 view = format(displays[0]);
1200 else
1201 {
1202 view = wxT("(list");
1203 for (auto display : displays)
1204 view += wxString(wxT(" ")) + format(display);
1205 view += wxT(")");
1206 }
1207 },
1208#if defined(USE_MIDI)
1209 [&](const NoteTrack&) {
1210 type = wxT("midi");
1211 view = wxT("\"Midi\"");
1212 },
1213#endif
1214 [&](const LabelTrack&) {
1215 type = wxT("label");
1216 view = wxT("\"Label\"");
1217 },
1218 [&](const TimeTrack&) {
1219 type = wxT("time");
1220 view = wxT("\"Time\"");
1221 });
1222
1223 cmd +=
1224 wxString::Format(wxT("(putprop '*TRACK* %d 'INDEX)\n"), ++mTrackIndex);
1225 cmd += wxString::Format(
1226 wxT("(putprop '*TRACK* \"%s\" 'NAME)\n"),
1227 EscapeString(mCurChannelGroup->GetName()));
1228 cmd += wxString::Format(wxT("(putprop '*TRACK* \"%s\" 'TYPE)\n"), type);
1229 // Note: "View" property may change when Audacity's choice of track views
1230 // has stabilized.
1231 cmd += wxString::Format(wxT("(putprop '*TRACK* %s 'VIEW)\n"), view);
1232 cmd += wxString::Format(
1233 wxT("(putprop '*TRACK* %d 'CHANNELS)\n"), mCurNumChannels);
1234
1235 // NOTE: Audacity 2.1.3 True if spectral selection is enabled regardless
1236 // of track view.
1237 cmd += wxString::Format(
1238 wxT("(putprop '*TRACK* %s 'SPECTRAL-EDIT-ENABLED)\n"), spectralEditp);
1239
1240 const double startTime = mCurChannelGroup->GetStartTime();
1241 const double endTime = mCurChannelGroup->GetEndTime();
1242
1243 cmd += wxString::Format(
1244 wxT("(putprop '*TRACK* (float %s) 'START-TIME)\n"),
1245 Internat::ToString(startTime));
1246 cmd += wxString::Format(
1247 wxT("(putprop '*TRACK* (float %s) 'END-TIME)\n"),
1248 Internat::ToString(endTime));
1249 cmd += wxString::Format(
1250 wxT(
1251 "(putprop '*TRACK* (float %s) 'GAIN)\n"), // https://github.com/audacity/audacity/issues/7097:
1252 // not to break all
1253 // nyquist scripts out
1254 // there, we keep the old
1255 // name.
1256 Internat::ToString(mCurChannelGroup->GetVolume()));
1257 cmd += wxString::Format(
1258 wxT("(putprop '*TRACK* (float %s) 'PAN)\n"),
1259 Internat::ToString(mCurChannelGroup->GetPan()));
1260 cmd += wxString::Format(
1261 wxT("(putprop '*TRACK* (float %s) 'RATE)\n"),
1262 Internat::ToString(mCurChannelGroup->GetRate()));
1263
1264 switch (mCurChannelGroup->GetSampleFormat())
1265 {
1266 case int16Sample:
1267 bitFormat = wxT("16");
1268 break;
1269 case int24Sample:
1270 bitFormat = wxT("24");
1271 break;
1272 case floatSample:
1273 bitFormat = wxT("32.0");
1274 break;
1275 }
1276 cmd +=
1277 wxString::Format(wxT("(putprop '*TRACK* %s 'FORMAT)\n"), bitFormat);
1278
1279 float maxPeakLevel = 0.0; // Deprecated as of 2.1.3
1280 const auto inClipBoundaries = GetClipBoundaries(
1281 pOutputs ? pOutputs->GetMatchingInput(*mCurChannelGroup) : nullptr);
1282 const auto outClipBoundaries = GetClipBoundaries(mCurChannelGroup);
1283 wxString inClips, outClips, peakString, rmsString;
1284 auto& mCurTrack = nyxContext.mCurTrack;
1285 for (size_t i = 0; i < mCurNumChannels; i++)
1286 {
1287 float maxPeak = 0.0;
1288 if (mCurNumChannels > 1)
1289 {
1290 inClips += wxT("(list ");
1291 outClips += wxT("(list ");
1292 }
1293 inClips += inClipBoundaries;
1294 outClips += outClipBoundaries;
1295 if (mCurNumChannels > 1)
1296 {
1297 inClips += wxT(" )");
1298 outClips += wxT(" )");
1299 }
1300 float min, max;
1302 *mCurTrack[i], mT0, mT1); // may throw
1303 min = pair.first, max = pair.second;
1304 maxPeak = std::max(std::max(fabs(min), fabs(max)), maxPeak);
1305 maxPeakLevel = std::max(maxPeakLevel, maxPeak);
1306
1307 // On Debian, NaN samples give maxPeak = 3.40282e+38 (FLT_MAX)
1308 if (
1309 !std::isinf(maxPeak) && !std::isnan(maxPeak) && (maxPeak < FLT_MAX))
1310 {
1311 peakString += wxString::Format(
1312 wxT("(float %s) "), Internat::ToString(maxPeak));
1313 }
1314 else
1315 {
1316 peakString += wxT("nil ");
1317 }
1318
1319 float rms =
1320 WaveChannelUtilities::GetRMS(*mCurTrack[i], mT0, mT1); // may throw
1321 if (!std::isinf(rms) && !std::isnan(rms))
1322 {
1323 rmsString +=
1324 wxString::Format(wxT("(float %s) "), Internat::ToString(rms));
1325 }
1326 else
1327 {
1328 rmsString += wxT("NIL ");
1329 }
1330 }
1331 // A list of clips for mono, or an array of lists for multi-channel.
1332 cmd += wxString::Format(
1333 wxT("(putprop '*TRACK* %s%s ) 'INCLIPS)\n"),
1334 (mCurNumChannels == 1) ? wxT("(list ") : wxT("(vector "), inClips);
1335 cmd += wxString::Format(
1336 wxT("(putprop '*TRACK* %s%s ) 'CLIPS)\n"),
1337 (mCurNumChannels == 1) ? wxT("(list ") : wxT("(vector "), outClips);
1338
1339 (mCurNumChannels > 1) ?
1340 cmd += wxString::Format(
1341 wxT("(putprop '*SELECTION* (vector %s) 'PEAK)\n"), peakString) :
1342 cmd +=
1343 wxString::Format(wxT("(putprop '*SELECTION* %s 'PEAK)\n"), peakString);
1344
1345 if (
1346 !std::isinf(maxPeakLevel) && !std::isnan(maxPeakLevel) &&
1347 (maxPeakLevel < FLT_MAX))
1348 {
1349 cmd += wxString::Format(
1350 wxT("(putprop '*SELECTION* (float %s) 'PEAK-LEVEL)\n"),
1351 Internat::ToString(maxPeakLevel));
1352 }
1353
1354 (mCurNumChannels > 1) ?
1355 cmd += wxString::Format(
1356 wxT("(putprop '*SELECTION* (vector %s) 'RMS)\n"), rmsString) :
1357 cmd +=
1358 wxString::Format(wxT("(putprop '*SELECTION* %s 'RMS)\n"), rmsString);
1359 }
1360
1361 // If in tool mode, then we don't do anything with the track and selection.
1362 if (GetType() == EffectTypeTool)
1363 nyx_set_audio_params(44100, 0);
1364 else if (GetType() == EffectTypeGenerate)
1365 nyx_set_audio_params(mCurChannelGroup->GetRate(), 0);
1366 else
1367 {
1368 auto curLen = nyxContext.mCurLen.as_long_long();
1369 nyx_set_audio_params(mCurChannelGroup->GetRate(), curLen);
1370 nyx_set_input_audio(
1371 NyxContext::StaticGetCallback, &nyxContext, (int)mCurNumChannels,
1372 curLen, mCurChannelGroup->GetRate());
1373 }
1374
1375 // Restore the Nyquist sixteenth note symbol for Generate plug-ins.
1376 // See http://bugzilla.audacityteam.org/show_bug.cgi?id=490.
1377 if (GetType() == EffectTypeGenerate)
1378 {
1379 cmd += wxT("(setf s 0.25)\n");
1380 }
1381
1382 if (mDebug || mTrace)
1383 {
1384 cmd += wxT("(setf *tracenable* T)\n");
1385 if (mExternal)
1386 {
1387 cmd += wxT("(setf *breakenable* T)\n");
1388 }
1389 }
1390 else
1391 {
1392 // Explicitly disable backtrace and prevent values
1393 // from being carried through to the output.
1394 // This should be the final command before evaluating the Nyquist script.
1395 cmd += wxT("(setf *tracenable* NIL)\n");
1396 }
1397
1398 for (unsigned int j = 0; j < mControls.size(); j++)
1399 {
1400 if (
1401 mControls[j].type == NYQ_CTRL_FLOAT ||
1402 mControls[j].type == NYQ_CTRL_FLOAT_TEXT ||
1403 mControls[j].type == NYQ_CTRL_TIME)
1404 {
1405 // We use Internat::ToString() rather than "%f" here because we
1406 // always have to use the dot as decimal separator when giving
1407 // numbers to Nyquist, whereas using "%f" will use the user's
1408 // decimal separator which may be a comma in some countries.
1409 cmd += wxString::Format(
1410 wxT("(setf %s %s)\n"), mControls[j].var,
1411 Internat::ToString(mControls[j].val, 14));
1412 }
1413 else if (
1414 mControls[j].type == NYQ_CTRL_INT ||
1415 mControls[j].type == NYQ_CTRL_INT_TEXT ||
1416 mControls[j].type == NYQ_CTRL_CHOICE)
1417 {
1418 cmd += wxString::Format(
1419 wxT("(setf %s %d)\n"), mControls[j].var, (int)(mControls[j].val));
1420 }
1421 else if (
1422 mControls[j].type == NYQ_CTRL_STRING ||
1423 mControls[j].type == NYQ_CTRL_FILE)
1424 {
1425 cmd += wxT("(setf ");
1426 // restrict variable names to 7-bit ASCII:
1427 cmd += mControls[j].var;
1428 cmd += wxT(" \"");
1429 cmd += EscapeString(
1430 mControls[j].valStr); // unrestricted value will become quoted UTF-8
1431 cmd += wxT("\")\n");
1432 }
1433 }
1434
1435 if (mIsSal)
1436 {
1437 wxString str = EscapeString(mCmd);
1438 // this is tricky: we need SAL to call main so that we can get a
1439 // SAL traceback in the event of an error (sal-compile catches the
1440 // error and calls sal-error-output), but SAL does not return values.
1441 // We will catch the value in a special global aud:result and if no
1442 // error occurs, we will grab the value with a LISP expression
1443 str += wxT("\nset aud:result = main()\n");
1444
1445 if (mDebug || mTrace)
1446 {
1447 // since we're about to evaluate SAL, remove LISP trace enable and
1448 // break enable (which stops SAL processing) and turn on SAL stack
1449 // trace
1450 cmd += wxT("(setf *tracenable* nil)\n");
1451 cmd += wxT("(setf *breakenable* nil)\n");
1452 cmd += wxT("(setf *sal-traceback* t)\n");
1453 }
1454
1455 if (mCompiler)
1456 {
1457 cmd += wxT("(setf *sal-compiler-debug* t)\n");
1458 }
1459
1460 cmd += wxT("(setf *sal-call-stack* nil)\n");
1461 // if we do not set this here and an error occurs in main, another
1462 // error will be raised when we try to return the value of aud:result
1463 // which is unbound
1464 cmd += wxT("(setf aud:result nil)\n");
1465 cmd += wxT("(sal-compile-audacity \"") + str + wxT("\" t t nil)\n");
1466 // Capture the value returned by main (saved in aud:result), but
1467 // set aud:result to nil so sound results can be evaluated without
1468 // retaining audio in memory
1469 cmd += wxT("(prog1 aud:result (setf aud:result nil))\n");
1470 }
1471 else
1472 {
1473 cmd += mCmd;
1474 }
1475
1476 // Evaluate the expression, which may invoke the get callback, but often does
1477 // not, leaving that to delayed evaluation of the output sound
1478 rval = nyx_eval_expression(cmd.mb_str(wxConvUTF8));
1479
1480 // If we're not showing debug window, log errors and warnings:
1481 const auto output = mDebugOutput.Translation();
1482 if (!output.empty() && !mDebug && !mTrace)
1483 {
1484 /* i18n-hint: An effect "returned" a message.*/
1485 wxLogMessage(wxT("\'%s\' returned:\n%s"), mName.Translation(), output);
1486 }
1487
1488 // Audacity has no idea how long Nyquist processing will take, but
1489 // can monitor audio being returned.
1490 // Anything other than audio should be returned almost instantly
1491 // so notify the user that process has completed (bug 558)
1492 if (
1493 (rval != nyx_audio) &&
1494 ((mCount + mCurNumChannels) == mNumSelectedChannels))
1495 {
1496 if (mCurNumChannels == 1)
1497 {
1498 TrackProgress(mCount, 1.0, XO("Processing complete."));
1499 }
1500 else
1501 {
1502 TrackGroupProgress(mCount, 1.0, XO("Processing complete."));
1503 }
1504 }
1505
1506 if ((rval == nyx_audio) && (GetType() == EffectTypeTool))
1507 {
1508 // Catch this first so that we can also handle other errors.
1509 mDebugOutput =
1510 /* i18n-hint: Don't translate ';type tool'. */
1511 XO("';type tool' effects cannot return audio from Nyquist.\n") +
1513 rval = nyx_error;
1514 }
1515
1516 if ((rval == nyx_labels) && (GetType() == EffectTypeTool))
1517 {
1518 // Catch this first so that we can also handle other errors.
1519 mDebugOutput =
1520 /* i18n-hint: Don't translate ';type tool'. */
1521 XO("';type tool' effects cannot return labels from Nyquist.\n") +
1523 rval = nyx_error;
1524 }
1525
1526 if (rval == nyx_error)
1527 {
1528 // Return value is not valid type.
1529 // Show error in debug window if trace enabled, otherwise log.
1530 if (mTrace)
1531 {
1532 /* i18n-hint: "%s" is replaced by name of plug-in.*/
1533 mDebugOutput = XO("nyx_error returned from %s.\n")
1534 .Format(mName.empty() ? XO("plug-in") : mName) +
1536 mDebug = true;
1537 }
1538 else
1539 {
1540 wxLogMessage(
1541 "Nyquist returned nyx_error:\n%s", mDebugOutput.Translation());
1542 }
1543 return false;
1544 }
1545
1546 if (rval == nyx_list)
1547 {
1548 wxLogMessage("Nyquist returned nyx_list");
1549 if (GetType() == EffectTypeTool)
1550 {
1551 mProjectChanged = true;
1552 }
1553 else
1554 {
1555 BasicUI::ShowMessageBox(XO("Nyquist returned a list."));
1556 }
1557 return true;
1558 }
1559
1560 if (rval == nyx_string)
1561 {
1562 // Assume the string has already been translated within the Lisp runtime
1563 // if necessary, by one of the gettext functions defined below, before it
1564 // is communicated back to C++
1565 auto msg = Verbatim(NyquistToWxString(nyx_get_string()));
1566 if (!msg.empty())
1567 { // Empty string may be used as a No-Op return value.
1569 }
1570 else if (GetType() == EffectTypeTool)
1571 {
1572 // ;tools may change the project with aud-do commands so
1573 // it is essential that the state is added to history.
1574 mProjectChanged = true;
1575 return true;
1576 }
1577 else
1578 {
1579 // A true no-op.
1580 return true;
1581 }
1582
1583 // True if not process type.
1584 // If not returning audio from process effect,
1585 // return first result then stop (disables preview)
1586 // but allow all output from Nyquist Prompt.
1587 return (GetType() != EffectTypeProcess || mIsPrompt);
1588 }
1589
1590 if (rval == nyx_double)
1591 {
1592 auto str = XO("Nyquist returned the value: %f").Format(nyx_get_double());
1594 return (GetType() != EffectTypeProcess || mIsPrompt);
1595 }
1596
1597 if (rval == nyx_int)
1598 {
1599 auto str = XO("Nyquist returned the value: %d").Format(nyx_get_int());
1601 return (GetType() != EffectTypeProcess || mIsPrompt);
1602 }
1603
1604 if (rval == nyx_labels)
1605 {
1606 assert(GetType() != EffectTypeTool); // Guaranteed above
1607 // Therefore bOnePassTool was false in Process()
1608 // Therefore output tracks were allocated
1609 assert(pOutputs);
1610
1611 mProjectChanged = true;
1612 unsigned int numLabels = nyx_get_num_labels();
1613 unsigned int l;
1614 auto ltrack = *pOutputs->Get().Any<LabelTrack>().begin();
1615 if (!ltrack)
1616 {
1617 auto newTrack = std::make_shared<LabelTrack>();
1618 // new track name should be unique among the names in the list of input
1619 // tracks, not output
1620 newTrack->SetName(
1621 inputTracks()->MakeUniqueTrackName(LabelTrack::GetDefaultName()));
1622 ltrack =
1623 static_cast<LabelTrack*>(pOutputs->AddToOutputTracks(newTrack));
1624 }
1625
1626 for (l = 0; l < numLabels; l++)
1627 {
1628 double t0, t1;
1629 const char* str;
1630
1631 // PRL: to do:
1632 // let Nyquist analyzers define more complicated selections
1633 nyx_get_label(l, &t0, &t1, &str);
1634
1635 ltrack->AddLabel(SelectedRegion(t0 + mT0, t1 + mT0), UTF8CTOWX(str));
1636 }
1637 return (GetType() != EffectTypeProcess || mIsPrompt);
1638 }
1639
1640 wxASSERT(rval == nyx_audio);
1641
1642 int outChannels = nyx_get_audio_num_channels();
1643 if (outChannels > (int)mCurNumChannels)
1644 {
1646 XO("Nyquist returned too many audio channels.\n"));
1647 return false;
1648 }
1649
1650 if (outChannels == -1)
1651 {
1653 XO("Nyquist returned one audio channel as an array.\n"));
1654 return false;
1655 }
1656
1657 if (outChannels == 0)
1658 {
1659 BasicUI::ShowMessageBox(XO("Nyquist returned an empty array.\n"));
1660 return false;
1661 }
1662
1663 nyxContext.mOutputTrack = mCurChannelGroup->EmptyCopy();
1664 auto out = nyxContext.mOutputTrack;
1665
1666 // Now fully evaluate the sound
1667 int success = nyx_get_audio(NyxContext::StaticPutCallback, &nyxContext);
1668
1669 // See if GetCallback found read errors
1670 if (auto pException = nyxContext.mpException)
1671 std::rethrow_exception(pException);
1672
1673 if (!success)
1674 return false;
1675
1676 mOutputTime = out->GetEndTime();
1677 if (mOutputTime <= 0)
1678 {
1679 BasicUI::ShowMessageBox(XO("Nyquist returned nil audio.\n"));
1680 return false;
1681 }
1682
1683 WaveTrack::Holder tempTrack;
1684 if (outChannels < static_cast<int>(mCurNumChannels))
1685 {
1686 // Be careful to do this before duplication
1687 out->Flush();
1688 // Must destroy one temporary list before repopulating another with
1689 // correct channel grouping
1690 nyxContext.mOutputTrack.reset();
1691 tempTrack = out->MonoToStereo();
1692 }
1693 else
1694 {
1695 tempTrack = move(nyxContext.mOutputTrack);
1696 out->Flush();
1697 }
1698
1699 {
1700 const bool bMergeClips = (mMergeClips < 0)
1701 // Use sample counts to determine default
1702 // behaviour - times will rarely be equal.
1703 ?
1704 (out->TimeToLongSamples(mT0) +
1705 out->TimeToLongSamples(mOutputTime) ==
1706 out->TimeToLongSamples(mT1)) :
1707 mMergeClips != 0;
1708 PasteTimeWarper warper { mT1, mT0 + tempTrack->GetEndTime() };
1709 mCurChannelGroup->ClearAndPaste(
1710 mT0, mT1, *tempTrack, mRestoreSplits, bMergeClips, &warper);
1711 }
1712
1713 // If we were first in the group adjust non-selected group tracks
1714 if (mFirstInGroup)
1715 {
1716 for (auto t : SyncLock::Group(*mCurChannelGroup))
1717 if (!t->GetSelected() && SyncLock::IsSyncLockSelected(*t))
1718 t->SyncLockAdjust(mT1, mT0 + out->GetEndTime());
1719
1720 // Only the first channel can be first in its group
1721 mFirstInGroup = false;
1722 }
1723
1724 mProjectChanged = true;
1725 return true;
1726}
#define UTF8CTOWX(X)
Definition: Internat.h:157
const TrackList * inputTracks() const
Definition: EffectBase.h:102
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:353
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:343
const Track * GetMatchingInput(const Track &outTrack) const
Gets the matching input track for the given output track if it finds its match, else nullptr.
Track * AddToOutputTracks(const std::shared_ptr< Track > &t)
Use this to add an output track, not corresponding to an input.
TrackList & Get()
Expose the output track list for iterations or even erasures.
static wxString GetDefaultName()
Definition: LabelTrack.cpp:96
static wxString NyquistToWxString(const char *nyqString)
Unit slope but with either a jump (pasting more) or a flat interval (pasting less)
Definition: TimeWarper.h:181
Defines a selected portion of a project.
static bool IsSyncLockSelected(const Track &track)
Definition: SyncLock.cpp:80
std::shared_ptr< WaveTrack > Holder
Definition: WaveTrack.h:247
WAVE_TRACK_API std::pair< float, float > GetMinMax(const WaveChannel &channel, double t0, double t1, bool mayThrow=true)
WAVE_TRACK_API float GetRMS(const WaveChannel &channel, double t0, double t1, bool mayThrow=true)
wxString GetClipBoundaries(const Track *t)
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101
static int StaticPutCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)
static int StaticGetCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)

References EffectOutputTracks::AddToOutputTracks(), TrackList::Any(), sampleCount::as_long_long(), details::begin(), GlobalHook< GetDisplaysHook, std::vector< WaveChannelSubViewType >(const WaveTrack *)>::Call(), EffectTypeGenerate, EffectTypeProcess, EffectTypeTool, TranslatableString::empty(), EscapeString(), floatSample, anonymous_namespace{ExportPCM.cpp}::format, EffectOutputTracks::Get(), SpectrogramSettings::Get(), anonymous_namespace{NyquistBase.cpp}::GetClipBoundaries(), LabelTrack::GetDefaultName(), EffectOutputTracks::GetMatchingInput(), WaveChannelUtilities::GetMinMax(), WaveChannelUtilities::GetRMS(), GetType(), SyncLock::Group(), EffectBase::inputTracks(), int16Sample, int24Sample, SyncLock::IsSyncLockSelected(), mCmd, mCompiler, mControls, mCount, NyquistBase::NyxContext::mCurChannelGroup, NyquistBase::NyxContext::mCurLen, NyquistBase::NyxContext::mCurNumChannels, NyquistBase::NyxContext::mCurTrack, mDebug, mDebugOutput, mExternal, mFirstInGroup, min(), mIsPrompt, mIsSal, mMergeClips, mName, mNumSelectedChannels, mOutputTime, NyquistBase::NyxContext::mOutputTrack, mPerTrackProps, NyquistBase::NyxContext::mpException, mProjectChanged, mProps, mRestoreSplits, EffectBase::mT0, EffectBase::mT1, mTrace, mTrackIndex, mVersion, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TIME, NyquistToWxString(), BasicUI::ShowMessageBox(), SpectrogramSettings::SpectralSelectionEnabled(), NyquistBase::NyxContext::StaticGetCallback(), NyquistBase::NyxContext::StaticPutCallback(), str, Internat::ToString(), Effect::TrackGroupProgress(), Effect::TrackProgress(), TranslatableString::Translation(), Track::TypeSwitch(), UTF8CTOWX, Verbatim(), wxT(), and XO().

Referenced by Process().

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

◆ RedirectOutput()

void NyquistBase::RedirectOutput ( )

Definition at line 1860 of file NyquistBase.cpp.

1861{
1862 mRedirectOutput = true;
1863}

References mRedirectOutput.

Referenced by NyqBench::OnGo().

Here is the caller graph for this function:

◆ resolveFilePath()

void NyquistBase::resolveFilePath ( wxString &  path,
FileExtension  extension = {} 
)
staticprotected

A file path given to Nyquist may be a platform-independent canonicalized form using certain abbreviations that are expanded into the platform-dependent equivalent.

If the path names only a directory, also append "/untitled" plus extension

Definition at line 2779 of file NyquistBase.cpp.

2781{
2782#if defined(__WXMSW__)
2783 path.Replace("/", wxFileName::GetPathSeparator());
2784#endif
2785
2786 path.Trim(true).Trim(false);
2787
2788 typedef std::unordered_map<wxString, FilePath> map;
2789 map pathKeys = {
2790 { "*home*", PlatformCompatibility::GetHomeDir() },
2792 { "*default*", FileNames::DefaultToDocumentsFolder("").GetPath() },
2793 { "*export*", FileNames::FindDefaultPath(FileNames::Operation::Export) },
2794 { "*save*", FileNames::FindDefaultPath(FileNames::Operation::Save) },
2795 { "*config*", FileNames::DataDir() }
2796 };
2797
2798 int characters = path.Find(wxFileName::GetPathSeparator());
2799 if (characters == wxNOT_FOUND) // Just a path or just a file name
2800 {
2801 if (path.empty())
2802 path = "*default*";
2803
2804 if (pathKeys.find(path) != pathKeys.end())
2805 {
2806 // Keyword found, so assume this is the intended directory.
2807 path = pathKeys[path] + wxFileName::GetPathSeparator();
2808 }
2809 else // Just a file name
2810 {
2811 path = pathKeys["*default*"] + wxFileName::GetPathSeparator() + path;
2812 }
2813 }
2814 else // path + file name
2815 {
2816 wxString firstDir = path.Left(characters);
2817 wxString rest = path.Mid(characters);
2818
2819 if (pathKeys.find(firstDir) != pathKeys.end())
2820 {
2821 path = pathKeys[firstDir] + rest;
2822 }
2823 }
2824
2825 wxFileName fname = path;
2826
2827 // If the directory is invalid, better to leave it as is (invalid) so that
2828 // the user sees the error rather than an unexpected file path.
2829 if (fname.wxFileName::IsOk() && fname.GetFullName().empty())
2830 {
2831 path = fname.GetPathWithSep() + _("untitled");
2832 if (!extension.empty())
2833 path = path + '.' + extension;
2834 }
2835}
FILES_API wxFileNameWrapper DefaultToDocumentsFolder(const wxString &preference)
FILES_API FilePath FindDefaultPath(Operation op)

References _, FileNames::DataDir(), FileNames::DefaultToDocumentsFolder(), anonymous_namespace{CloudProjectFileIOExtensions.cpp}::extension, FileNames::FindDefaultPath(), and PlatformCompatibility::GetHomeDir().

Referenced by NyquistEffect::BuildEffectWindow(), NyquistEffect::OnFileButton(), SaveSettings(), and NyquistEffect::TransferDataFromEffectWindow().

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

◆ SaveSettings()

bool NyquistBase::SaveSettings ( const EffectSettings settings,
CommandParameters parms 
) const
overridevirtual

Store settings as keys and values.

The override may assume parms is initially empty

Returns
true on success

Reimplemented from Effect.

Definition at line 295 of file NyquistBase.cpp.

297{
298 if (mIsPrompt)
299 {
300 parms.Write(KEY_Command, mInputCmd);
301 parms.Write(KEY_Parameters, mParameters);
302
303 return true;
304 }
305
306 for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
307 {
308 const NyqControl& ctrl = mControls[c];
309 double d = ctrl.val;
310
311 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
312 {
313 d = GetCtrlValue(ctrl.valStr);
314 }
315
316 if (
317 ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
318 ctrl.type == NYQ_CTRL_TIME)
319 {
320 parms.Write(ctrl.var, d);
321 }
322 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
323 {
324 parms.Write(ctrl.var, (int)d);
325 }
326 else if (ctrl.type == NYQ_CTRL_CHOICE)
327 {
328 // untranslated
329 parms.WriteEnum(
330 ctrl.var, (int)d, ctrl.choices.data(), ctrl.choices.size());
331 }
332 else if (ctrl.type == NYQ_CTRL_STRING)
333 {
334 parms.Write(ctrl.var, ctrl.valStr);
335 }
336 else if (ctrl.type == NYQ_CTRL_FILE)
337 {
338 // Convert the given path string to platform-dependent equivalent
339 resolveFilePath(const_cast<wxString&>(ctrl.valStr));
340 parms.Write(ctrl.var, ctrl.valStr);
341 }
342 }
343
344 return true;
345}
#define UNINITIALIZED_CONTROL
Definition: NyquistBase.h:26
bool WriteEnum(const wxString &key, int value, const EnumValueSymbol choices[], size_t nChoices)
static void resolveFilePath(wxString &path, FileExtension extension={})

References NyqControl::choices, GetCtrlValue(), KEY_Command, KEY_Parameters, mControls, mInputCmd, mIsPrompt, mParameters, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TIME, resolveFilePath(), NyqControl::type, UNINITIALIZED_CONTROL, NyqControl::val, NyqControl::valStr, NyqControl::var, and CommandParameters::WriteEnum().

Referenced by EVT_COMMAND_RANGE(), and VisitSettings().

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

◆ SetCommand()

void NyquistBase::SetCommand ( const wxString &  cmd)

Definition at line 1865 of file NyquistBase.cpp.

1866{
1867 mExternal = true;
1868
1869 if (cmd.size())
1870 {
1871 ParseCommand(cmd);
1872 }
1873}

References mExternal, and ParseCommand().

Referenced by EVT_COMMAND_RANGE(), and NyqBench::OnGo().

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

◆ SetLispVarsFromParameters()

int NyquistBase::SetLispVarsFromParameters ( const CommandParameters parms,
bool  bTestOnly 
)

Definition at line 421 of file NyquistBase.cpp.

423{
424 int badCount = 0;
425 // First pass verifies values
426 for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
427 {
428 NyqControl& ctrl = mControls[c];
429 bool good = false;
430
431 // This GetCtrlValue code is preserved from former code,
432 // but probably is pointless. The value d isn't used later,
433 // and GetCtrlValue does not appear to have important needed
434 // side effects.
435 if (!bTestOnly)
436 {
437 double d = ctrl.val;
438 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
439 {
440 d = GetCtrlValue(ctrl.valStr);
441 }
442 }
443
444 if (
445 ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
446 ctrl.type == NYQ_CTRL_TIME)
447 {
448 double val;
449 good =
450 parms.Read(ctrl.var, &val) && val >= ctrl.low && val <= ctrl.high;
451 if (good && !bTestOnly)
452 ctrl.val = val;
453 }
454 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
455 {
456 int val;
457 good =
458 parms.Read(ctrl.var, &val) && val >= ctrl.low && val <= ctrl.high;
459 if (good && !bTestOnly)
460 ctrl.val = (double)val;
461 }
462 else if (ctrl.type == NYQ_CTRL_CHOICE)
463 {
464 int val;
465 // untranslated
466 good = parms.ReadEnum(
467 ctrl.var, &val, ctrl.choices.data(), ctrl.choices.size()) &&
468 val != wxNOT_FOUND;
469 if (good && !bTestOnly)
470 ctrl.val = (double)val;
471 }
472 else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
473 {
474 wxString val;
475 good = parms.Read(ctrl.var, &val);
476 if (good && !bTestOnly)
477 ctrl.valStr = val;
478 }
479 else if (ctrl.type == NYQ_CTRL_TEXT)
480 {
481 // This "control" is just fixed text (nothing to save or restore),
482 // Does not count for good/bad counting.
483 good = true;
484 }
485 badCount += !good ? 1 : 0;
486 }
487 return badCount;
488}
bool ReadEnum(const wxString &key, int *pi, const EnumValueSymbol choices[], size_t nChoices, const ObsoleteMap obsoletes[]=nullptr, size_t nObsoletes=0) const

References NyqControl::choices, GetCtrlValue(), NyqControl::high, NyqControl::low, mControls, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TEXT, NYQ_CTRL_TIME, CommandParameters::ReadEnum(), NyqControl::type, UNINITIALIZED_CONTROL, NyqControl::val, NyqControl::valStr, and NyqControl::var.

Referenced by DoLoadSettings().

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

◆ StaticOSCallback()

void NyquistBase::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2724 of file NyquistBase.cpp.

2725{
2726 ((NyquistBase*)This)->OSCallback();
2727}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

void NyquistBase::StaticOutputCallback ( int  c,
void *  userdata 
)
staticprivate

Definition at line 2707 of file NyquistBase.cpp.

2708{
2709 ((NyquistBase*)This)->OutputCallback(c);
2710}

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistBase::Stop ( )

Definition at line 1885 of file NyquistBase.cpp.

1886{
1887 mStop = true;
1888}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistBase::ToTimeFormat ( double  t)
protected

Definition at line 2847 of file NyquistBase.cpp.

2848{
2849 int seconds = static_cast<int>(t);
2850 int hh = seconds / 3600;
2851 int mm = seconds % 3600;
2852 mm = mm / 60;
2853 return wxString::Format("%d:%d:%.3f", hh, mm, t - (hh * 3600 + mm * 60));
2854}

Referenced by NyquistEffect::OnTime().

Here is the caller graph for this function:

◆ UnQuote()

wxString NyquistBase::UnQuote ( const wxString &  s,
bool  allowParens = true,
wxString *  pExtraString = nullptr 
)
staticprivate

Definition at line 1936 of file NyquistBase.cpp.

1938{
1939 return UnQuoteMsgid(s, allowParens, pExtraString).Translation();
1940}

References TranslatableString::Translation(), and UnQuoteMsgid().

Referenced by Parse(), ParseChoice(), ParseFileExtensions(), ParseFileTypes(), and UnQuoteMsgid().

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

◆ UnQuoteMsgid()

TranslatableString NyquistBase::UnQuoteMsgid ( const wxString &  s,
bool  allowParens = true,
wxString *  pExtraString = nullptr 
)
staticprivate

Definition at line 1890 of file NyquistBase.cpp.

1892{
1893 if (pExtraString)
1894 *pExtraString = wxString {};
1895
1896 int len = s.length();
1897 if (len >= 2 && s[0] == wxT('\"') && s[len - 1] == wxT('\"'))
1898 {
1899 auto unquoted = s.Mid(1, len - 2);
1900 // Sorry, no context strings, yet
1901 // (See also comments in NyquistEffectsModule::AutoRegisterPlugins)
1902 return TranslatableString { unquoted, {} };
1903 }
1904 else if (
1905 allowParens && len >= 2 && s[0] == wxT('(') && s[len - 1] == wxT(')'))
1906 {
1907 Tokenizer tzer;
1908 tzer.Tokenize(s, true, 1, 1);
1909 auto& tokens = tzer.tokens;
1910 if (tokens.size() > 1)
1911 {
1912 if (pExtraString && tokens[1][0] == '(')
1913 {
1914 // A choice with a distinct internal string form like
1915 // ("InternalString" (_ "Visible string"))
1916 // Recur to find the two strings
1917 *pExtraString = UnQuote(tokens[0], false);
1918 return UnQuoteMsgid(tokens[1]);
1919 }
1920 else
1921 {
1922 // Assume the first token was _ -- we don't check that
1923 // And the second is the string, which is internationalized
1924 // Sorry, no context strings, yet
1925 return UnQuoteMsgid(tokens[1], false);
1926 }
1927 }
1928 else
1929 return {};
1930 }
1931 else
1932 // If string was not quoted, assume no translation exists
1933 return Verbatim(s);
1934}

References NyquistBase::Tokenizer::Tokenize(), NyquistBase::Tokenizer::tokens, UnQuote(), UnQuoteMsgid(), Verbatim(), and wxT().

Referenced by ParseFileType(), UnQuote(), and UnQuoteMsgid().

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

◆ validatePath()

bool NyquistBase::validatePath ( wxString  path)
protected

Definition at line 2837 of file NyquistBase.cpp.

2838{
2839 wxFileName fname = path;
2840 wxString dir = fname.GetPath();
2841
2842 return (
2843 fname.wxFileName::IsOk() && wxFileName::DirExists(dir) &&
2844 !fname.GetFullName().empty());
2845}

Referenced by NyquistEffect::TransferDataFromEffectWindow().

Here is the caller graph for this function:

◆ VisitSettings() [1/2]

bool NyquistBase::VisitSettings ( ConstSettingsVisitor visitor,
const EffectSettings settings 
) const
overridevirtual

Visit settings (read-only), if defined. false means no defined settings. Default implementation returns false

Reimplemented from Effect.

Definition at line 233 of file NyquistBase.cpp.

235{
236 // For now we assume Nyquist can do get and set better than VisitSettings
237 // can, And so we ONLY use it for getting the signature.
238 if (auto pGa = dynamic_cast<ShuttleGetAutomation*>(&visitor))
239 {
240 SaveSettings(settings, *pGa->mpEap);
241 return true;
242 }
243
244 // Get the "definition," only for the help or info commands
245 if (mExternal)
246 return true;
247
248 if (mIsPrompt)
249 {
250 visitor.Define(mInputCmd, KEY_Command, wxString {});
251 visitor.Define(mParameters, KEY_Parameters, wxString {});
252 return true;
253 }
254
255 for (const auto& ctrl : mControls)
256 {
257 double d = ctrl.val;
258
259 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
260 d = GetCtrlValue(ctrl.valStr);
261
262 if (
263 ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
264 ctrl.type == NYQ_CTRL_TIME)
265 visitor.Define(
266 d, static_cast<const wxChar*>(ctrl.var.c_str()), (double)0.0,
267 ctrl.low, ctrl.high, 1.0);
268 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
269 {
270 int x = d;
271 visitor.Define(
272 x, static_cast<const wxChar*>(ctrl.var.c_str()), 0,
273 static_cast<int>(ctrl.low), static_cast<int>(ctrl.high), 1);
274 // parms.Write(ctrl.var, (int) d);
275 }
276 else if (ctrl.type == NYQ_CTRL_CHOICE)
277 {
278 // untranslated
279 int x = d;
280 // parms.WriteEnum(ctrl.var, (int) d, choices);
281 visitor.DefineEnum(
282 x, static_cast<const wxChar*>(ctrl.var.c_str()), 0,
283 ctrl.choices.data(), ctrl.choices.size());
284 }
285 else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
286 {
287 visitor.Define(
288 ctrl.valStr, ctrl.var, wxString {}, ctrl.lowStr, ctrl.highStr);
289 // parms.Write(ctrl.var, ctrl.valStr);
290 }
291 }
292 return true;
293}
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
virtual void Define(Arg< bool > var, const wxChar *key, bool vdefault, bool vmin=false, bool vmax=false, bool vscl=false)
virtual void DefineEnum(Arg< int > var, const wxChar *key, int vdefault, const EnumValueSymbol strings[], size_t nStrings)
SettingsVisitor that gets parameter values into a string.

References SettingsVisitorBase< Const >::Define(), SettingsVisitorBase< Const >::DefineEnum(), GetCtrlValue(), KEY_Command, KEY_Parameters, mControls, mExternal, mInputCmd, mIsPrompt, mParameters, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TIME, SaveSettings(), settings(), and UNINITIALIZED_CONTROL.

Here is the call graph for this function:

◆ VisitSettings() [2/2]

bool NyquistBase::VisitSettings ( SettingsVisitor visitor,
EffectSettings settings 
)
overridevirtual

Visit settings (and maybe change them), if defined. false means no defined settings. Default implementation returns false

Reimplemented from Effect.

Definition at line 225 of file NyquistBase.cpp.

227{
228 if (auto pSa = dynamic_cast<ShuttleSetAutomation*>(&visitor))
229 LoadSettings(*pSa->mpEap, settings);
230 return true;
231}
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
SettingsVisitor that sets parameters to a value (from a string)

References LoadSettings(), and settings().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ NyquistEffectsModule

friend class NyquistEffectsModule
friend

Definition at line 305 of file NyquistBase.h.

Member Data Documentation

◆ mAction

TranslatableString NyquistBase::mAction
protected

Definition at line 260 of file NyquistBase.h.

Referenced by NyquistBase(), and Parse().

◆ mAuthor

TranslatableString NyquistBase::mAuthor
protected

Definition at line 262 of file NyquistBase.h.

Referenced by GetVendor(), NyquistBase(), and Parse().

◆ mBreak

bool NyquistBase::mBreak
protected

Definition at line 237 of file NyquistBase.h.

Referenced by Break(), NyquistBase(), OSCallback(), and Process().

◆ mCategories

wxArrayString NyquistBase::mCategories
protected

Definition at line 297 of file NyquistBase.h.

Referenced by Parse(), and ParseProgram().

◆ mCmd

wxString NyquistBase::mCmd
protected

Definition at line 256 of file NyquistBase.h.

Referenced by ParseProgram(), and ProcessOne().

◆ mCompiler

bool NyquistBase::mCompiler
protected

Definition at line 241 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), and ProcessOne().

◆ mCont

bool NyquistBase::mCont
protected

Definition at line 238 of file NyquistBase.h.

Referenced by Continue(), NyquistBase(), OSCallback(), and Process().

◆ mControls

std::vector<NyqControl> NyquistBase::mControls

◆ mCopyright

TranslatableString NyquistBase::mCopyright
protected

Definition at line 267 of file NyquistBase.h.

Referenced by GetDescription(), NyquistBase(), and Parse().

◆ mCount

unsigned NyquistBase::mCount
protected

Definition at line 294 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mDebug

bool NyquistBase::mDebug
protected

Definition at line 278 of file NyquistBase.h.

Referenced by NyquistBase(), ParseProgram(), Process(), and ProcessOne().

◆ mDebugButton

bool NyquistBase::mDebugButton
protected

Definition at line 276 of file NyquistBase.h.

Referenced by EnablesDebug(), Init(), Parse(), and ParseProgram().

◆ mDebugOutput

TranslatableString NyquistBase::mDebugOutput
protected

Definition at line 282 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mDebugOutputStr

wxString NyquistBase::mDebugOutputStr
protected

Definition at line 281 of file NyquistBase.h.

Referenced by OutputCallback(), and Process().

◆ mEnablePreview

bool NyquistBase::mEnablePreview
protected

Definition at line 275 of file NyquistBase.h.

Referenced by Init(), Parse(), ParseProgram(), and NyquistEffect::TransferDataToWindow().

◆ mExternal

bool NyquistBase::mExternal
protected

Definition at line 244 of file NyquistBase.h.

Referenced by DoLoadSettings(), NyquistBase(), ProcessOne(), SetCommand(), and VisitSettings().

◆ mFileModified

wxDateTime NyquistBase::mFileModified
protected

When the script was last modified on disk.

Definition at line 234 of file NyquistBase.h.

Referenced by NyquistBase().

◆ mFileName

wxFileName NyquistBase::mFileName
protected

Name of the Nyquist script file this effect is loaded from.

Definition at line 233 of file NyquistBase.h.

Referenced by GetPath(), NyquistBase(), NyquistEffect::OnLoad(), NyquistEffect::OnSave(), Parse(), and ParseFile().

◆ mFirstInGroup

bool NyquistBase::mFirstInGroup
protected

Definition at line 292 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mFoundType

bool NyquistBase::mFoundType
protected

Definition at line 240 of file NyquistBase.h.

Referenced by Parse(), and ParseProgram().

◆ mHelpFile

wxString NyquistBase::mHelpFile
protected

Definition at line 269 of file NyquistBase.h.

Referenced by CheckHelpPage(), Parse(), ParseProgram(), and Process().

◆ mHelpFileExists

bool NyquistBase::mHelpFileExists
protected

Definition at line 270 of file NyquistBase.h.

Referenced by ParseProgram(), and Process().

◆ mHelpPage

FilePath NyquistBase::mHelpPage
protected

Definition at line 271 of file NyquistBase.h.

Referenced by HelpPage(), and ParseProgram().

◆ mInfo

TranslatableString NyquistBase::mInfo
protected

Definition at line 261 of file NyquistBase.h.

Referenced by Parse().

◆ mInitError

TranslatableString NyquistBase::mInitError
protected

Definition at line 253 of file NyquistBase.h.

Referenced by Parse(), and ParseProgram().

◆ mInputCmd

wxString NyquistBase::mInputCmd
protected

◆ mIsPrompt

const bool NyquistBase::mIsPrompt
protected

True if the code to execute is obtained interactively from the user via the "Nyquist Effect Prompt", or "Nyquist Prompt", false for all other effects (lisp code read from files)

Definition at line 251 of file NyquistBase.h.

Referenced by DoLoadSettings(), GetPath(), GetSymbol(), GetVendor(), Init(), IsDefault(), IsInteractive(), ManualPage(), NyquistBase(), ParseProgram(), NyquistEffect::PopulateOrExchange(), Process(), ProcessOne(), SaveSettings(), NyquistEffect::TransferDataFromWindow(), NyquistEffect::TransferDataToWindow(), and VisitSettings().

◆ mIsSal

bool NyquistBase::mIsSal
protected

Definition at line 243 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), ParseProgram(), and ProcessOne().

◆ mIsSpectral

bool NyquistBase::mIsSpectral
protected

Definition at line 245 of file NyquistBase.h.

Referenced by Init(), Parse(), and ParseProgram().

◆ mIsTool

bool NyquistBase::mIsTool
protected

Definition at line 246 of file NyquistBase.h.

Referenced by DoLoadSettings(), GetClassification(), NyquistBase(), and Parse().

◆ mManPage

wxString NyquistBase::mManPage
protected

Definition at line 268 of file NyquistBase.h.

Referenced by ManualPage(), Parse(), and ParseProgram().

◆ mMaxLen

sampleCount NyquistBase::mMaxLen
protected

Definition at line 290 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), and Process().

◆ mMergeClips

int NyquistBase::mMergeClips
protected

Definition at line 303 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), and ProcessOne().

◆ mName

TranslatableString NyquistBase::mName
protected

Name of the Effect (untranslated)

Definition at line 257 of file NyquistBase.h.

Referenced by GetSymbol(), Init(), NyquistBase(), Parse(), Process(), and ProcessOne().

◆ mNumSelectedChannels

unsigned NyquistBase::mNumSelectedChannels
protected

Definition at line 295 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mOK

bool NyquistBase::mOK
protected

Definition at line 252 of file NyquistBase.h.

Referenced by IsOk(), NyquistBase(), and Parse().

◆ mOutputTime

double NyquistBase::mOutputTime
protected

Definition at line 293 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mParameters

wxString NyquistBase::mParameters
protected

Definition at line 255 of file NyquistBase.h.

Referenced by DoLoadSettings(), SaveSettings(), and VisitSettings().

◆ mPerTrackProps

wxString NyquistBase::mPerTrackProps
protected

Definition at line 300 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mProjectChanged

bool NyquistBase::mProjectChanged
protected

Definition at line 280 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mPromptName

TranslatableString NyquistBase::mPromptName
protected

Definition at line 259 of file NyquistBase.h.

Referenced by Init(), and NyquistBase().

◆ mPromptType

EffectType NyquistBase::mPromptType
protected

Definition at line 273 of file NyquistBase.h.

Referenced by DoLoadSettings(), Init(), and NyquistBase().

◆ mProps

wxString NyquistBase::mProps
protected

Definition at line 299 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mRedirectOutput

bool NyquistBase::mRedirectOutput
protected

Definition at line 279 of file NyquistBase.h.

Referenced by NyquistBase(), OutputCallback(), Process(), and RedirectOutput().

◆ mReentryCount

int NyquistBase::mReentryCount = 0
staticprivate

Definition at line 166 of file NyquistBase.h.

Referenced by Process().

◆ mReleaseVersion

TranslatableString NyquistBase::mReleaseVersion
protected

Definition at line 266 of file NyquistBase.h.

Referenced by GetVersion(), NyquistBase(), and Parse().

◆ mRestoreSplits

bool NyquistBase::mRestoreSplits
protected

Definition at line 302 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), and ProcessOne().

◆ mStop

bool NyquistBase::mStop
protected

Definition at line 236 of file NyquistBase.h.

Referenced by NyquistBase(), OSCallback(), Process(), and Stop().

◆ mTrace

bool NyquistBase::mTrace
protected

Definition at line 242 of file NyquistBase.h.

Referenced by NyquistBase(), Parse(), ParseProgram(), Process(), and ProcessOne().

◆ mTrackIndex

int NyquistBase::mTrackIndex
protected

Definition at line 291 of file NyquistBase.h.

Referenced by Process(), and ProcessOne().

◆ mType

EffectType NyquistBase::mType
protected

◆ mVersion

int NyquistBase::mVersion
protected

Definition at line 284 of file NyquistBase.h.

Referenced by Init(), NyquistBase(), Parse(), Process(), and ProcessOne().

◆ mXlispPath

wxString NyquistBase::mXlispPath
protected

Definition at line 230 of file NyquistBase.h.


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