Audacity 3.2.0
Classes | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
NyquistEffect Class Referencefinal

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

#include <Nyquist.h>

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

Classes

struct  Tokenizer
 

Public Member Functions

 NyquistEffect (const wxString &fName)
 
virtual ~NyquistEffect ()
 
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
 
int ShowHostInterface (EffectPlugin &plugin, wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false) override
 
std::unique_ptr< EffectEditorPopulateOrExchange (ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
 Add controls to effect panel; always succeeds. More...
 
bool TransferDataToWindow (const EffectSettings &settings) override
 
bool TransferDataFromWindow (EffectSettings &settings) override
 
void RedirectOutput ()
 
void SetCommand (const wxString &cmd)
 
void Continue ()
 
void Break ()
 
void Stop ()
 
- 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
 
EffectType GetType () const override
 Type determines how it behaves. 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...
 
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 NumericFormatSymbol 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)
 Re-invoke DoEffect on another Effect object that implements the work. More...
 
- Public Member Functions inherited from EffectBase
 EffectBase ()
 
 ~EffectBase () override
 
void SetTracks (TrackList *pTracks)
 
bool DoEffect (EffectSettings &settings, const InstanceFinder &finder, double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, const EffectSettingsAccessPtr &pAccess) override
 
- 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 void Preview (EffectSettingsAccess &access, std::function< void()> updateUI, bool dryOnly)=0
 Calculate temporary tracks of limited length with effect applied and play. More...
 
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 Member Functions inherited from StatefulEffectUIServices
 ~StatefulEffectUIServices () override
 
std::unique_ptr< EffectEditorPopulateUI (const EffectPlugin &plugin, ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const override
 Allows PopulateOrExchange to return null. More...
 
virtual std::unique_ptr< EffectEditorPopulateOrExchange (ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs)
 Add controls to effect panel; always succeeds. More...
 
virtual bool TransferDataToWindow (const EffectSettings &settings)
 
virtual bool TransferDataFromWindow (EffectSettings &settings)
 
- Public Member Functions inherited from BasicEffectUIServices
int ShowClientInterface (const EffectPlugin &plugin, wxWindow &parent, wxDialog &dialog, EffectEditor *pEditor, bool forceModal) const override
 
void ExportPresets (const EffectPlugin &plugin, const EffectSettings &settings) const override
 
OptionalMessage ImportPresets (const EffectPlugin &plugin, EffectSettings &settings) const override
 
void ShowOptions (const EffectPlugin &plugin) const override
 
bool ValidateUI (const EffectPlugin &context, EffectSettings &) const override
 
bool CloseUI () const override
 
- Public Member Functions inherited from EffectUIServices
virtual ~EffectUIServices ()
 
virtual int ShowHostInterface (EffectPlugin &plugin, wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false)
 
virtual int ShowClientInterface (const EffectPlugin &plugin, wxWindow &parent, wxDialog &dialog, EffectEditor *pEditor, bool forceModal=false) const =0
 
virtual std::unique_ptr< EffectEditorPopulateUI (const EffectPlugin &plugin, ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const =0
 Adds controls to a panel that is given as the parent window of S More...
 
virtual void ExportPresets (const EffectPlugin &plugin, const EffectSettings &settings) const =0
 
virtual OptionalMessage ImportPresets (const EffectPlugin &plugin, EffectSettings &settings) const =0
 
virtual void ShowOptions (const EffectPlugin &plugin) const =0
 
virtual bool ValidateUI (const EffectPlugin &context, EffectSettings &settings) const =0
 
virtual bool CloseUI () const =0
 

Private Types

using Buffer = std::unique_ptr< float[]>
 

Private Member Functions

bool ProcessOne ()
 
void BuildPromptWindow (ShuttleGui &S)
 
void BuildEffectWindow (ShuttleGui &S)
 
bool TransferDataToPromptWindow ()
 
bool TransferDataToEffectWindow ()
 
bool TransferDataFromPromptWindow ()
 
bool TransferDataFromEffectWindow ()
 
bool IsOk ()
 
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)
 
int GetCallback (float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
 
int PutCallback (float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
 
void OutputCallback (int c)
 
void OSCallback ()
 
void ParseFile ()
 
bool ParseCommand (const wxString &cmd)
 
bool ParseProgram (wxInputStream &stream)
 
bool Parse (Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
 
void OnLoad (wxCommandEvent &evt)
 
void OnSave (wxCommandEvent &evt)
 
void OnDebug (wxCommandEvent &evt)
 
void OnText (wxCommandEvent &evt)
 
void OnSlider (wxCommandEvent &evt)
 
void OnChoice (wxCommandEvent &evt)
 
void OnTime (wxCommandEvent &evt)
 
void OnFileButton (wxCommandEvent &evt)
 
bool validatePath (wxString path)
 
wxString ToTimeFormat (double t)
 
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 int StaticGetCallback (float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)
 
static int StaticPutCallback (float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)
 
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 double GetCtrlValue (const wxString &s)
 
static void resolveFilePath (wxString &path, FileExtension extension={})
 

Private Attributes

wxWeakRef< wxWindow > mUIParent {}
 
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
 
std::vector< NyqControlmControls
 
unsigned mCurNumChannels
 
WaveTrackmCurTrack [2]
 
sampleCount mCurStart [2]
 
sampleCount mCurLen
 
sampleCount mMaxLen
 
int mTrackIndex
 
bool mFirstInGroup
 
double mOutputTime
 
unsigned mCount
 
unsigned mNumSelectedChannels
 
double mProgressIn
 
double mProgressOut
 
double mProgressTot
 
double mScale
 
Buffer mCurBuffer [2]
 
sampleCount mCurBufferStart [2]
 
size_t mCurBufferLen [2]
 
WaveTrackmOutputTrack [2]
 
wxArrayString mCategories
 
wxString mProps
 
wxString mPerTrackProps
 
bool mRestoreSplits
 
int mMergeClips
 
wxTextCtrl * mCommandText
 
std::exception_ptr mpException {}
 

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...
 
- Public Types inherited from EffectUIServices
enum  : long { DefaultMessageBoxStyle = wxOK | wxCENTRE }
 
- 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 void IncEffectCounter ()
 
- 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 Member Functions inherited from EffectUIServices
static int DoMessageBox (const EffectPlugin &plugin, const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
 
- Public Attributes inherited from EffectBase
TrackListmTracks {}
 
- 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>")
 
- 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, const WaveTrack *pRight, sampleCount *start, sampleCount *len)
 
void CopyInputTracks (bool allSyncLockSelected=false)
 
TrackAddToOutputTracks (const std::shared_ptr< Track > &t)
 
- Protected Member Functions inherited from EffectBase
virtual std::any BeginPreview (const EffectSettings &settings)
 Called when Preview() starts, to allow temporary effect state changes. More...
 
void Preview (EffectSettingsAccess &access, std::function< void()> updateUI, bool dryOnly) final
 Calculate temporary tracks of limited length with effect applied and play. More...
 
virtual bool CheckWhetherSkipEffect (const EffectSettings &settings) const =0
 After Init(), tell whether Process() should be skipped. More...
 
virtual double CalcPreviewInputLength (const EffectSettings &settings, double previewLength) const =0
 
void SetLinearEffectFlag (bool linearEffectFlag)
 
void SetPreviewFullSelectionFlag (bool previewDurationFlag)
 
bool IsPreviewing () const
 
void IncludeNotSelectedPreviewTracks (bool includeNotSelected)
 
void ReplaceProcessedTracks (const bool bGoodResult)
 
const TrackListinputTracks () const
 
const AudacityProjectFindProject () const
 
- Protected Attributes inherited from EffectBase
BasicUI::ProgressDialogmProgress {}
 
double mProjectRate {}
 
WaveTrackFactorymFactory {}
 
std::shared_ptr< TrackListmOutputTracks
 
double mT0 {}
 
double mT1 {}
 
wxArrayString mPresetNames
 
unsigned mUIFlags { 0 }
 
- Static Protected Attributes inherited from EffectBase
static int nEffectsDone = 0
 

Detailed Description

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

Definition at line 74 of file Nyquist.h.

Member Typedef Documentation

◆ Buffer

using NyquistEffect::Buffer = std::unique_ptr<float[]>
private

Definition at line 297 of file Nyquist.h.

Constructor & Destructor Documentation

◆ NyquistEffect()

NyquistEffect::NyquistEffect ( 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.

◆ ~NyquistEffect()

NyquistEffect::~NyquistEffect ( )
virtual

Definition at line 201 of file Nyquist.cpp.

202{
203}

Member Function Documentation

◆ Break()

void NyquistEffect::Break ( )

Definition at line 1865 of file Nyquist.cpp.

1866{
1867 mBreak = true;
1868}
bool mBreak
Definition: Nyquist.h:233

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2912 of file Nyquist.cpp.

2913{
2914 wxScrolledWindow *scroller = S.Style(wxVSCROLL | wxTAB_TRAVERSAL)
2915 .StartScroller(2);
2916 {
2917 S.StartMultiColumn(4);
2918 {
2919 for (size_t i = 0; i < mControls.size(); i++)
2920 {
2921 NyqControl & ctrl = mControls[i];
2922
2923 if (ctrl.type == NYQ_CTRL_TEXT)
2924 {
2925 S.EndMultiColumn();
2926 S.StartHorizontalLay(wxALIGN_LEFT, 0);
2927 {
2928 S.AddSpace(0, 10);
2929 S.AddFixedText( Verbatim( ctrl.label ), false );
2930 }
2931 S.EndHorizontalLay();
2932 S.StartMultiColumn(4);
2933 }
2934 else
2935 {
2936 auto prompt = XXO("%s:").Format( ctrl.name );
2937 S.AddPrompt( prompt );
2938
2939 if (ctrl.type == NYQ_CTRL_STRING)
2940 {
2941 S.AddSpace(10, 10);
2942
2943 auto item = S.Id(ID_Text + i)
2944 .Validator<wxGenericValidator>(&ctrl.valStr)
2945 .Name( prompt )
2946 .AddTextBox( {}, wxT(""), 50);
2947 }
2948 else if (ctrl.type == NYQ_CTRL_CHOICE)
2949 {
2950 S.AddSpace(10, 10);
2951
2952 S.Id(ID_Choice + i).AddChoice( {},
2953 Msgids( ctrl.choices.data(), ctrl.choices.size() ) );
2954 }
2955 else if (ctrl.type == NYQ_CTRL_TIME)
2956 {
2957 S.AddSpace(10, 10);
2958
2959 const auto options = NumericTextCtrl::Options{}
2960 .AutoPos(true)
2961 .MenuEnabled(true)
2962 .ReadOnly(false);
2963
2964 NumericTextCtrl *time = safenew
2965 NumericTextCtrl(S.GetParent(), (ID_Time + i),
2968 ctrl.val,
2970 options);
2971 S
2972 .Name( prompt )
2973 .Position(wxALIGN_LEFT | wxALL)
2974 .AddWindow(time);
2975 }
2976 else if (ctrl.type == NYQ_CTRL_FILE)
2977 {
2978 S.AddSpace(10, 10);
2979
2980 // Get default file extension if specified in wildcards
2981 FileExtension defaultExtension;
2982 if (!ctrl.fileTypes.empty()) {
2983 const auto &type = ctrl.fileTypes[0];
2984 if ( !type.extensions.empty() )
2985 defaultExtension = type.extensions[0];
2986 }
2987 resolveFilePath(ctrl.valStr, defaultExtension);
2988
2989 wxTextCtrl *item = S.Id(ID_Text+i)
2990 .Name( prompt )
2991 .AddTextBox( {}, wxT(""), 40);
2992 item->SetValidator(wxGenericValidator(&ctrl.valStr));
2993
2994 if (ctrl.label.empty())
2995 // We'd expect wxFileSelectorPromptStr to already be translated, but apparently not.
2996 ctrl.label = wxGetTranslation( wxFileSelectorPromptStr );
2997 S.Id(ID_FILE + i).AddButton(
2998 Verbatim(ctrl.label), wxALIGN_LEFT);
2999 }
3000 else
3001 {
3002 // Integer or Real
3003 if (ctrl.type == NYQ_CTRL_INT_TEXT || ctrl.type == NYQ_CTRL_FLOAT_TEXT)
3004 {
3005 S.AddSpace(10, 10);
3006 }
3007
3008 S.Id(ID_Text+i);
3009 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT)
3010 {
3011 double range = ctrl.high - ctrl.low;
3012 S.Validator<FloatingPointValidator<double>>(
3013 // > 12 decimal places can cause rounding errors in display.
3014 12, &ctrl.val,
3015 // Set number of decimal places
3016 (range < 10
3017 ? NumValidatorStyle::THREE_TRAILING_ZEROES
3018 : range < 100
3019 ? NumValidatorStyle::TWO_TRAILING_ZEROES
3020 : NumValidatorStyle::ONE_TRAILING_ZERO),
3021 ctrl.low, ctrl.high
3022 );
3023 }
3024 else
3025 {
3026 S.Validator<IntegerValidator<double>>(
3027 &ctrl.val, NumValidatorStyle::DEFAULT,
3028 (int) ctrl.low, (int) ctrl.high);
3029 }
3030 wxTextCtrl *item = S
3031 .Name( prompt )
3032 .AddTextBox( {}, wxT(""),
3033 (ctrl.type == NYQ_CTRL_INT_TEXT ||
3034 ctrl.type == NYQ_CTRL_FLOAT_TEXT) ? 25 : 12);
3035
3036 if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_FLOAT)
3037 {
3038 S.Id(ID_Slider + i)
3039 .Style(wxSL_HORIZONTAL)
3040 .MinSize( { 150, -1 } )
3041 .AddSlider( {}, 0, ctrl.ticks, 0);
3042 }
3043 }
3044
3045 if (ctrl.type != NYQ_CTRL_FILE)
3046 {
3047 if (ctrl.type == NYQ_CTRL_CHOICE || ctrl.label.empty())
3048 {
3049 S.AddSpace(10, 10);
3050 }
3051 else
3052 {
3053 S.AddUnits( Verbatim( ctrl.label ) );
3054 }
3055 }
3056 }
3057 }
3058 }
3059 S.EndMultiColumn();
3060 }
3061 S.EndScroller();
3062
3063 scroller->SetScrollRate(0, 20);
3064
3065 // This fools NVDA into not saying "Panel" when the dialog gets focus
3066 scroller->SetName(wxT("\a"));
3067 scroller->SetLabel(wxT("\a"));
3068}
wxT("CloseDown"))
XXO("&Cut/Copy/Paste Toolbar")
wxString FileExtension
File extension, not including any leading dot.
Definition: Identifier.h:224
#define safenew
Definition: MemoryX.h:10
@ ID_FILE
Definition: Nyquist.cpp:109
@ ID_Choice
Definition: Nyquist.cpp:107
@ ID_Slider
Definition: Nyquist.cpp:105
ID_Text
Definition: Nyquist.cpp:132
NyquistEffect::OnText ID_Time
Definition: Nyquist.cpp:136
@ NYQ_CTRL_STRING
Definition: Nyquist.h:32
@ NYQ_CTRL_TEXT
Definition: Nyquist.h:36
@ NYQ_CTRL_TIME
Definition: Nyquist.h:37
@ NYQ_CTRL_INT_TEXT
Definition: Nyquist.h:34
@ NYQ_CTRL_INT
Definition: Nyquist.h:30
@ NYQ_CTRL_CHOICE
Definition: Nyquist.h:33
@ NYQ_CTRL_FLOAT_TEXT
Definition: Nyquist.h:35
@ NYQ_CTRL_FILE
Definition: Nyquist.h:38
@ NYQ_CTRL_FLOAT
Definition: Nyquist.h:31
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
#define S(N)
Definition: ToChars.cpp:64
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
double mProjectRate
Definition: EffectBase.h:105
virtual NumericFormatSymbol GetSelectionFormat()
Definition: Effect.cpp:195
A control on a NyquistDialog.
Definition: Nyquist.h:42
double high
Definition: Nyquist.h:61
wxString label
Definition: Nyquist.h:53
wxString name
Definition: Nyquist.h:52
int ticks
Definition: Nyquist.h:62
std::vector< EnumValueSymbol > choices
Definition: Nyquist.h:54
int type
Definition: Nyquist.h:50
wxString valStr
Definition: Nyquist.h:56
double low
Definition: Nyquist.h:60
double val
Definition: Nyquist.h:59
FileNames::FileTypes fileTypes
Definition: Nyquist.h:55
std::vector< NyqControl > mControls
Definition: Nyquist.h:280
static void resolveFilePath(wxString &path, FileExtension extension={})
Definition: Nyquist.cpp:3312
Options & MenuEnabled(bool enable)
Options & AutoPos(bool enable)
Options & ReadOnly(bool enable)

References NumericTextCtrl::Options::AutoPos(), NyqControl::choices, NyqControl::fileTypes, Effect::GetSelectionFormat(), NyqControl::high, ID_Choice, ID_FILE, ID_Slider, ID_Text, ID_Time, NyqControl::label, NyqControl::low, mControls, NumericTextCtrl::Options::MenuEnabled(), EffectBase::mProjectRate, Msgids(), NyqControl::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, NumericTextCtrl::Options::ReadOnly(), resolveFilePath(), S, safenew, NyqControl::ticks, NumericConverter::TIME, NyqControl::type, NyqControl::val, NyqControl::valStr, Verbatim(), wxT(), and XXO().

Referenced by PopulateOrExchange().

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

◆ BuildPromptWindow()

void NyquistEffect::BuildPromptWindow ( ShuttleGui S)
private

Definition at line 2880 of file Nyquist.cpp.

2881{
2882 S.StartVerticalLay();
2883 {
2884 S.StartMultiColumn(3, wxEXPAND);
2885 {
2886 S.SetStretchyCol(1);
2887
2888 S.AddVariableText(XO("Enter Nyquist Command: "));
2889
2890 S.AddSpace(1, 1);
2891 }
2892 S.EndMultiColumn();
2893
2894 S.StartHorizontalLay(wxEXPAND, 1);
2895 {
2896 mCommandText = S.Focus()
2897 .MinSize( { 500, 200 } )
2898 .AddTextWindow(wxT(""));
2899 }
2900 S.EndHorizontalLay();
2901
2902 S.StartHorizontalLay(wxALIGN_CENTER, 0);
2903 {
2904 S.Id(ID_Load).AddButton(XXO("&Load"));
2905 S.Id(ID_Save).AddButton(XXO("&Save"));
2906 }
2907 S.EndHorizontalLay();
2908 }
2909 S.EndVerticalLay();
2910}
XO("Cut/Copy/Paste")
@ ID_Load
Definition: Nyquist.cpp:102
@ ID_Save
Definition: Nyquist.cpp:103
wxTextCtrl * mCommandText
Definition: Nyquist.h:312

References ID_Load, ID_Save, mCommandText, S, wxT(), XO(), and XXO().

Referenced by PopulateOrExchange().

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

◆ CheckHelpPage()

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

Definition at line 253 of file Nyquist.cpp.

254{
256 wxString fileName;
257
258 for (size_t i = 0, cnt = paths.size(); i < cnt; i++) {
259 fileName = wxFileName(paths[i] + wxT("/") + mHelpFile).GetFullPath();
260 if (wxFileExists(fileName))
261 {
262 return { true, fileName };
263 }
264 }
265 return { false, wxEmptyString };
266}
wxString mHelpFile
Definition: Nyquist.h:264
static FilePaths GetNyquistSearchPath()
Definition: Nyquist.cpp:2661

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 NyquistEffect::Continue ( )

Definition at line 1870 of file Nyquist.cpp.

1871{
1872 mCont = true;
1873}
bool mCont
Definition: Nyquist.h:234

References mCont.

◆ DoLoadSettings()

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

Definition at line 430 of file Nyquist.cpp.

432{
433 // Due to a constness problem that happens when using the prompt, we need
434 // to be ready to switch the params to a local instance.
435 const CommandParameters* pParms = &parms;
436 CommandParameters localParms;
437
438 if (mIsPrompt)
439 {
440 parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
441 parms.Read(KEY_Parameters, &mParameters, wxEmptyString);
442
443 if (!mInputCmd.empty())
444 {
446 }
447
448 if (!mParameters.empty())
449 {
450 pParms = &localParms;
451 localParms.SetParameters(mParameters);
452 }
453
454 if (!IsBatchProcessing())
455 {
457 }
458
461 mExternal = true;
462
463 if (!IsBatchProcessing())
464 {
465 return true;
466 }
467 }
468
469 // Constants to document what the true/false values mean.
470 const auto kTestOnly = true;
471 const auto kTestAndSet = false;
472
473 // badCount will encompass both actual bad values and missing values.
474 // We probably never actually have bad values when using the dialogs
475 // since the dialog validation will catch them.
476 int badCount;
477 // When batch processing, we just ignore missing/bad parameters.
478 // We'll end up using defaults in those cases.
479 if (!IsBatchProcessing()) {
480 badCount = SetLispVarsFromParameters(*pParms, kTestOnly);
481 if (badCount > 0)
482 return false;
483 }
484
485 badCount = SetLispVarsFromParameters(*pParms, kTestAndSet);
486 // We never do anything with badCount here.
487 // It might be non zero, for missing parameters, and we allow that,
488 // and don't distinguish that from an out-of-range value.
489 return true;
490}
@ EffectTypeTool
static const wxChar * KEY_Command
Definition: Nyquist.cpp:117
static const wxChar * KEY_Parameters
Definition: Nyquist.cpp:118
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:302
EffectType mType
Definition: Nyquist.h:267
bool ParseCommand(const wxString &cmd)
Definition: Nyquist.cpp:2505
int SetLispVarsFromParameters(const CommandParameters &parms, bool bTestOnly)
Definition: Nyquist.cpp:496
const bool mIsPrompt
Definition: Nyquist.h:247
wxString mInputCmd
Definition: Nyquist.h:250
bool mExternal
Definition: Nyquist.h:240
bool mIsTool
Definition: Nyquist.h:242
wxString mParameters
Definition: Nyquist.h:251
EffectType mPromptType
Definition: Nyquist.h:268

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 NyquistEffect::EnablesDebug ( ) const
overridevirtual

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

Reimplemented from EffectDefinitionInterface.

Definition at line 1149 of file Nyquist.cpp.

1150{
1151 return mDebugButton;
1152}
bool mDebugButton
Definition: Nyquist.h:271

References mDebugButton.

◆ EscapeString()

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

Definition at line 1743 of file Nyquist.cpp.

1744{
1745 wxString str = inStr;
1746
1747 str.Replace(wxT("\\"), wxT("\\\\"));
1748 str.Replace(wxT("\""), wxT("\\\""));
1749
1750 return str;
1751}
#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:

◆ GetCallback()

int NyquistEffect::GetCallback ( float *  buffer,
int  channel,
int64_t  start,
int64_t  len,
int64_t  totlen 
)
private

Definition at line 2520 of file Nyquist.cpp.

2522{
2523 if (mCurBuffer[ch]) {
2524 if ((mCurStart[ch] + start) < mCurBufferStart[ch] ||
2525 (mCurStart[ch] + start)+len >
2527 mCurBuffer[ch].reset();
2528 }
2529 }
2530
2531 if (!mCurBuffer[ch]) {
2532 mCurBufferStart[ch] = (mCurStart[ch] + start);
2534
2535 if (mCurBufferLen[ch] < (size_t) len) {
2537 }
2538
2539 mCurBufferLen[ch] =
2541 mCurStart[ch] + mCurLen - mCurBufferStart[ch] );
2542
2543 // C++20
2544 // mCurBuffer[ch] = std::make_unique_for_overwrite(mCurBufferLen[ch]);
2545 mCurBuffer[ch] = Buffer{ safenew float[ mCurBufferLen[ch] ] };
2546 try {
2547 mCurTrack[ch]->GetFloats( mCurBuffer[ch].get(),
2549 }
2550 catch ( ... ) {
2551 // Save the exception object for re-throw when out of the library
2552 mpException = std::current_exception();
2553 return -1;
2554 }
2555 }
2556
2557 // We have guaranteed above that this is nonnegative and bounded by
2558 // mCurBufferLen[ch]:
2559 auto offset = ( mCurStart[ch] + start - mCurBufferStart[ch] ).as_size_t();
2560 const void *src = &mCurBuffer[ch][offset];
2561 std::memcpy(buffer, src, len * sizeof(float));
2562
2563 if (ch == 0) {
2564 double progress = mScale *
2565 ( (start+len)/ mCurLen.as_double() );
2566
2567 if (progress > mProgressIn) {
2568 mProgressIn = progress;
2569 }
2570
2572 return -1;
2573 }
2574 }
2575
2576 return 0;
2577}
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
bool TotalProgress(double frac, const TranslatableString &={}) const
Definition: Effect.cpp:338
Buffer mCurBuffer[2]
Definition: Nyquist.h:298
double mProgressOut
Definition: Nyquist.h:293
std::exception_ptr mpException
Definition: Nyquist.h:314
double mScale
Definition: Nyquist.h:295
size_t mCurBufferLen[2]
Definition: Nyquist.h:300
double mProgressIn
Definition: Nyquist.h:292
std::unique_ptr< float[]> Buffer
Definition: Nyquist.h:297
WaveTrack * mCurTrack[2]
Definition: Nyquist.h:283
sampleCount mCurStart[2]
Definition: Nyquist.h:284
sampleCount mCurLen
Definition: Nyquist.h:285
double mProgressTot
Definition: Nyquist.h:294
sampleCount mCurBufferStart[2]
Definition: Nyquist.h:299
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
Definition: SampleTrack.h:82
size_t GetBestBlockSize(sampleCount t) const override
This returns a nonnegative number of samples meant to size a memory buffer.
Definition: WaveTrack.cpp:1593
size_t GetIdealBlockSize()
Definition: WaveTrack.cpp:1633
double as_double() const
Definition: SampleCount.h:46

References sampleCount::as_double(), WaveTrack::GetBestBlockSize(), SampleTrack::GetFloats(), WaveTrack::GetIdealBlockSize(), limitSampleBufferSize(), mCurBuffer, mCurBufferLen, mCurBufferStart, mCurLen, mCurStart, mCurTrack, mpException, mProgressIn, mProgressOut, mProgressTot, mScale, safenew, and Effect::TotalProgress().

Referenced by StaticGetCallback().

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

◆ GetClassification()

EffectType NyquistEffect::GetClassification ( ) const
overridevirtual

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

Reimplemented from EffectDefinitionInterface.

Definition at line 281 of file Nyquist.cpp.

282{
283 if (mIsTool)
284 return EffectTypeTool;
285 return mType;
286}

References EffectTypeTool, mIsTool, and mType.

◆ GetCtrlValue()

double NyquistEffect::GetCtrlValue ( const wxString &  s)
staticprivate

Definition at line 1927 of file Nyquist.cpp.

1928{
1929 /* For this to work correctly requires that the plug-in header is
1930 * parsed on each run so that the correct value for "half-srate" may
1931 * be determined.
1932 *
1933 auto project = FindProject();
1934 if (project && s.IsSameAs(wxT("half-srate"), false)) {
1935 auto rate =
1936 TrackList::Get( *project ).Selected< const WaveTrack >()
1937 .min( &WaveTrack::GetRate );
1938 return (rate / 2.0);
1939 }
1940 */
1941
1943}
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:133

References Internat::CompatibleToDouble().

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

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

◆ GetDescription()

TranslatableString NyquistEffect::GetDescription ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 240 of file Nyquist.cpp.

241{
242 return mCopyright;
243}
TranslatableString mCopyright
Definition: Nyquist.h:262

References mCopyright.

◆ GetFamily()

EffectFamilySymbol NyquistEffect::GetFamily ( ) const
overridevirtual

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

Implements EffectDefinitionInterface.

Definition at line 288 of file Nyquist.cpp.

289{
291}
#define NYQUISTEFFECTS_FAMILY
Definition: EffectBase.h:150

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistEffect::GetNyquistSearchPath ( )
staticprivate

Definition at line 2661 of file Nyquist.cpp.

2662{
2663 const auto &audacityPathList = FileNames::AudacityPathList();
2664 FilePaths pathList;
2665
2666 for (size_t i = 0; i < audacityPathList.size(); i++)
2667 {
2668 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2669 FileNames::AddUniquePathToPathList(prefix + wxT("nyquist"), pathList);
2670 FileNames::AddUniquePathToPathList(prefix + wxT("plugins"), pathList);
2671 FileNames::AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList);
2672 }
2673 pathList.push_back(FileNames::PlugInDir());
2674
2675 return pathList;
2676}
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 NyquistEffect::GetPath ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 207 of file Nyquist.cpp.

208{
209 if (mIsPrompt)
210 return NYQUIST_PROMPT_ID;
211
212 return mFileName.GetFullPath();
213}
#define NYQUIST_PROMPT_ID
wxFileName mFileName
Name of the Nyquist script file this effect is loaded from.
Definition: Nyquist.h:229

References mFileName, mIsPrompt, and NYQUIST_PROMPT_ID.

◆ GetSymbol()

ComponentInterfaceSymbol NyquistEffect::GetSymbol ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 215 of file Nyquist.cpp.

216{
217 if (mIsPrompt)
219
220 return mName;
221}
#define NYQUIST_PROMPT_NAME
TranslatableString mName
Name of the Effect (untranslated)
Definition: Nyquist.h:253

References mIsPrompt, mName, NYQUIST_PROMPT_ID, and NYQUIST_PROMPT_NAME.

◆ GetType()

EffectType NyquistEffect::GetType ( ) const
overridevirtual

Type determines how it behaves.

Implements EffectDefinitionInterface.

Definition at line 276 of file Nyquist.cpp.

277{
278 return mType;
279}

References mType.

Referenced by Process(), and ProcessOne().

Here is the caller graph for this function:

◆ GetVendor()

VendorSymbol NyquistEffect::GetVendor ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 223 of file Nyquist.cpp.

224{
225 if (mIsPrompt)
226 {
227 return XO("Audacity");
228 }
229
230 return mAuthor;
231}
TranslatableString mAuthor
Definition: Nyquist.h:257

References mAuthor, mIsPrompt, and XO().

Here is the call graph for this function:

◆ GetVersion()

wxString NyquistEffect::GetVersion ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 233 of file Nyquist.cpp.

234{
235 // Are Nyquist version strings really supposed to be translatable?
236 // See commit a06e561 which used XO for at least one of them
238}
TranslatableString mReleaseVersion
Definition: Nyquist.h:261
wxString Translation() const

References mReleaseVersion, and TranslatableString::Translation().

Here is the call graph for this function:

◆ HelpPage()

FilePath NyquistEffect::HelpPage ( ) const
overridevirtual

Fully qualified local help file name, default is empty.

Reimplemented from EffectDefinitionInterface.

Definition at line 269 of file Nyquist.cpp.

270{
271 return mHelpPage;
272}
FilePath mHelpPage
Definition: Nyquist.h:266

References mHelpPage.

◆ Init()

bool NyquistEffect::Init ( )
overridevirtual

Default implementation does nothing, returns true

Reimplemented from StatefulEffectBase.

Definition at line 565 of file Nyquist.cpp.

566{
567 // When Nyquist Prompt spawns an effect GUI, Init() is called for Nyquist Prompt,
568 // and then again for the spawned (mExternal) effect.
569
570 // EffectType may not be defined in script, so
571 // reset each time we call the Nyquist Prompt.
572 if (mIsPrompt) {
574 // Reset effect type each time we call the Nyquist Prompt.
576 mIsSpectral = false;
577 mDebugButton = true; // Debug button always enabled for Nyquist Prompt.
578 mEnablePreview = true; // Preview button always enabled for Nyquist Prompt.
579 mVersion = 4;
580 }
581
582 // As of Audacity 2.1.2 rc1, 'spectral' effects are allowed only if
583 // the selected track(s) are in a spectrogram view, and there is at
584 // least one frequency bound and Spectral Selection is enabled for the
585 // selected track(s) - (but don't apply to Nyquist Prompt).
586
587 if (!mIsPrompt && mIsSpectral) {
588 // Completely skip the spectral editing limitations if there is no
589 // project because that is editing of macro parameters
590 if (const auto project = FindProject()) {
591 bool bAllowSpectralEditing = false;
592 bool hasSpectral = false;
593 for ( auto t :
594 TrackList::Get( *project ).Selected< const WaveTrack >() ) {
595 // Find() not Get() to avoid creation-on-demand of views in case we are
596 // only previewing
597 auto pView = WaveTrackView::Find( t );
598 if ( pView ) {
599 const auto displays = pView->GetDisplays();
600 if (displays.end() != std::find(
601 displays.begin(), displays.end(),
602 WaveTrackSubView::Type{ WaveTrackViewConstants::Spectrum, {} }))
603 hasSpectral = true;
604 }
605 if ( hasSpectral &&
607 bAllowSpectralEditing = true;
608 break;
609 }
610 }
611
612 if (!bAllowSpectralEditing || ((mF0 < 0.0) && (mF1 < 0.0))) {
613 if (!hasSpectral) {
615 XO("Enable track spectrogram view before\n"
616 "applying 'Spectral' effects."),
617 wxOK | wxICON_EXCLAMATION | wxCENTRE,
618 XO("Error") );
619 } else {
621 XO("To use 'Spectral effects', enable 'Spectral Selection'\n"
622 "in the track Spectrogram settings and select the\n"
623 "frequency range for the effect to act on."),
624 wxOK | wxICON_EXCLAMATION | wxCENTRE,
625 XO("Error") );
626 }
627 return false;
628 }
629 }
630 }
631
632 if (!mIsPrompt && !mExternal)
633 {
634 //TODO: (bugs):
635 // 1) If there is more than one plug-in with the same name, GetModificationTime may pick the wrong one.
636 // 2) If the ;type is changed after the effect has been registered, the plug-in will appear in the wrong menu.
637
638 //TODO: If we want to auto-add parameters from spectral selection,
639 //we will need to modify this test.
640 //Note that removing it stops the caching of parameter values,
641 //(during this session).
642 if (mFileName.GetModificationTime().IsLaterThan(mFileModified))
643 {
644 // If the effect has internal state, save and restore it.
645 // If the effect is stateless, saving and restoring don't matter.
646 auto dummySettings = MakeSettings();
647 constexpr auto key = L"TemporarySettings";
648 SaveUserPreset(key, dummySettings);
649
651 ParseFile();
652 mFileModified = mFileName.GetModificationTime();
653
654 // Ignore failure
655 (void) LoadUserPreset(key, dummySettings);
656 }
657 }
658
659 return true;
660}
static const AudacityProject::AttachedObjects::RegisteredFactory key
#define NYQ_MAX_LEN
Definition: Nyquist.cpp:113
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:311
bool SaveUserPreset(const RegistryPath &name, const EffectSettings &settings) const override
Save settings in the configuration file as a user-named preset.
Definition: Effect.cpp:151
OptionalMessage LoadUserPreset(const RegistryPath &name, EffectSettings &settings) const override
Definition: Effect.cpp:138
static int DoMessageBox(const EffectPlugin &plugin, const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
EffectSettings MakeSettings() const override
Definition: Effect.h:167
bool mIsSpectral
Definition: Nyquist.h:241
bool mEnablePreview
Definition: Nyquist.h:270
int mVersion
Definition: Nyquist.h:279
TranslatableString mPromptName
Definition: Nyquist.h:254
wxDateTime mFileModified
When the script was last modified on disk.
Definition: Nyquist.h:230
sampleCount mMaxLen
Definition: Nyquist.h:286
void ParseFile()
Definition: Nyquist.cpp:2497
bool SpectralSelectionEnabled() const
static SpectrogramSettings & Get(const WaveTrack &track)
Mutative access to attachment even if the track argument is const.
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:487
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1457
A Track that contains audio waveform data.
Definition: WaveTrack.h:51
static WaveTrackView * Find(WaveTrack *pTrack)

References EffectUIServices::DoMessageBox(), WaveTrackView::Find(), EffectBase::FindProject(), TrackList::Get(), SpectrogramSettings::Get(), mDebugButton, mEnablePreview, mIsPrompt, mIsSpectral, mName, mPromptName, mPromptType, mType, mVersion, TrackList::Selected(), SpectrogramSettings::SpectralSelectionEnabled(), and XO().

Here is the call graph for this function:

◆ InitializationError()

const TranslatableString & NyquistEffect::InitializationError ( ) const
inlineprivate

Definition at line 159 of file Nyquist.h.

159{ return mInitError; }
TranslatableString mInitError
Definition: Nyquist.h:249

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ IsDefault()

bool NyquistEffect::IsDefault ( ) const
overridevirtual

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

Implements EffectDefinitionInterface.

Definition at line 303 of file Nyquist.cpp.

304{
305 return mIsPrompt;
306}

References mIsPrompt.

◆ IsInteractive()

bool NyquistEffect::IsInteractive ( ) const
overridevirtual

Whether the effect needs a dialog for entry of settings.

Implements EffectDefinitionInterface.

Definition at line 293 of file Nyquist.cpp.

294{
295 if (mIsPrompt)
296 {
297 return true;
298 }
299
300 return mControls.size() != 0;
301}

References mControls, and mIsPrompt.

◆ IsOk()

bool NyquistEffect::IsOk ( )
private

Definition at line 3072 of file Nyquist.cpp.

3073{
3074 return mOK;
3075}

References mOK.

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ LoadSettings()

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

Restore settings from keys and values.

Returns
true on success

Implements EffectSettingsManager.

Definition at line 423 of file Nyquist.cpp.

425{
426 // To do: externalize state so const_cast isn't needed
427 return const_cast<NyquistEffect*>(this)->DoLoadSettings(parms, settings);
428}
static Settings & settings()
Definition: TrackInfo.cpp:87
An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class.
Definition: Nyquist.h:76
bool DoLoadSettings(const CommandParameters &parms, EffectSettings &settings)
Definition: Nyquist.cpp:430

References DoLoadSettings(), and settings().

Referenced by ShowHostInterface(), and VisitSettings().

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

◆ ManualPage()

ManualPageID NyquistEffect::ManualPage ( ) const
overridevirtual

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

Reimplemented from EffectDefinitionInterface.

Definition at line 245 of file Nyquist.cpp.

246{
247 return mIsPrompt
248 ? wxString("Nyquist_Prompt")
249 : mManPage;
250}
wxString mManPage
Definition: Nyquist.h:263

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

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

Definition at line 1730 of file Nyquist.cpp.

1731{
1732 wxString str(nyqString, wxConvUTF8);
1733 if (nyqString != NULL && nyqString[0] && str.empty()) {
1734 // invalid UTF-8 string, convert as Latin-1
1735 str = _("[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1736 // TODO: internationalization of strings from Nyquist effects, at least
1737 // from those shipped with Audacity
1738 str += LAT1CTOWX(nyqString);
1739 }
1740 return str;
1741}
#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:

◆ OnChoice()

void NyquistEffect::OnChoice ( wxCommandEvent &  evt)
private

Definition at line 3181 of file Nyquist.cpp.

3182{
3183 mControls[evt.GetId() - ID_Choice].val = (double) evt.GetInt();
3184}

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3217 of file Nyquist.cpp.

3218{
3219 int i = evt.GetId() - ID_FILE;
3220 NyqControl & ctrl = mControls[i];
3221
3222 // Get style flags:
3223 // Ensure legal combinations so that wxWidgets does not throw an assert error.
3224 unsigned int flags = 0;
3225 if (!ctrl.highStr.empty())
3226 {
3227 wxStringTokenizer tokenizer(ctrl.highStr, ",");
3228 while ( tokenizer.HasMoreTokens() )
3229 {
3230 wxString token = tokenizer.GetNextToken().Trim(true).Trim(false);
3231 if (token.IsSameAs("open", false))
3232 {
3233 flags |= wxFD_OPEN;
3234 flags &= ~wxFD_SAVE;
3235 flags &= ~wxFD_OVERWRITE_PROMPT;
3236 }
3237 else if (token.IsSameAs("save", false))
3238 {
3239 flags |= wxFD_SAVE;
3240 flags &= ~wxFD_OPEN;
3241 flags &= ~wxFD_MULTIPLE;
3242 flags &= ~wxFD_FILE_MUST_EXIST;
3243 }
3244 else if (token.IsSameAs("overwrite", false) && !(flags & wxFD_OPEN))
3245 {
3246 flags |= wxFD_OVERWRITE_PROMPT;
3247 }
3248 else if (token.IsSameAs("exists", false) && !(flags & wxFD_SAVE))
3249 {
3250 flags |= wxFD_FILE_MUST_EXIST;
3251 }
3252 else if (token.IsSameAs("multiple", false) && !(flags & wxFD_SAVE))
3253 {
3254 flags |= wxFD_MULTIPLE;
3255 }
3256 }
3257 }
3258
3259 resolveFilePath(ctrl.valStr);
3260
3261 wxFileName fname = ctrl.valStr;
3262 wxString defaultDir = fname.GetPath();
3263 wxString defaultFile = fname.GetName();
3264 auto message = XO("Select a file");
3265
3266 if (flags & wxFD_MULTIPLE)
3267 message = XO("Select one or more files");
3268 else if (flags & wxFD_SAVE)
3269 message = XO("Save file as");
3270
3271 FileDialogWrapper openFileDialog(mUIParent->FindWindow(ID_FILE + i),
3272 message,
3273 defaultDir,
3274 defaultFile,
3275 ctrl.fileTypes,
3276 flags); // styles
3277
3278 if (openFileDialog.ShowModal() == wxID_CANCEL)
3279 {
3280 return;
3281 }
3282
3283 wxString path;
3284 // When multiple files selected, return file paths as a list of quoted strings.
3285 if (flags & wxFD_MULTIPLE)
3286 {
3287 wxArrayString selectedFiles;
3288 openFileDialog.GetPaths(selectedFiles);
3289
3290 for (size_t sf = 0; sf < selectedFiles.size(); sf++) {
3291 path += "\"";
3292 path += selectedFiles[sf];
3293 path += "\"";
3294 }
3295 ctrl.valStr = path;
3296 }
3297 else
3298 {
3299 ctrl.valStr = openFileDialog.GetPath();
3300 }
3301
3302 mUIParent->FindWindow(ID_Text + i)->GetValidator()->TransferToWindow();
3303}
wxString highStr
Definition: Nyquist.h:58
wxWeakRef< wxWindow > mUIParent
Definition: Nyquist.h:142

References NyqControl::fileTypes, FileDialog::GetPath(), FileDialog::GetPaths(), NyqControl::highStr, ID_FILE, ID_Text, mControls, mUIParent, resolveFilePath(), FileDialog::ShowModal(), NyqControl::valStr, and XO().

Here is the call graph for this function:

◆ OnLoad()

void NyquistEffect::OnLoad ( wxCommandEvent &  evt)
private

Definition at line 3084 of file Nyquist.cpp.

3085{
3086 if (mCommandText->IsModified())
3087 {
3088 if (wxNO == EffectUIServices::DoMessageBox(*this,
3089 XO("Current program has been modified.\nDiscard changes?"),
3090 wxYES_NO ) )
3091 {
3092 return;
3093 }
3094 }
3095
3096 FileDialogWrapper dlog(
3097 mUIParent,
3098 XO("Load Nyquist script"),
3099 mFileName.GetPath(),
3100 wxEmptyString,
3101 {
3102 NyquistScripts,
3103 LispScripts,
3104 FileNames::TextFiles,
3105 FileNames::AllFiles
3106 },
3107 wxFD_OPEN | wxRESIZE_BORDER);
3108
3109 if (dlog.ShowModal() != wxID_OK)
3110 {
3111 return;
3112 }
3113
3114 mFileName = dlog.GetPath();
3115
3116 if (!mCommandText->LoadFile(mFileName.GetFullPath()))
3117 {
3118 EffectUIServices::DoMessageBox(*this, XO("File could not be loaded"));
3119 }
3120}

References EffectUIServices::DoMessageBox(), FileDialog::GetPath(), mCommandText, mFileName, mUIParent, FileDialog::ShowModal(), and XO().

Here is the call graph for this function:

◆ OnSave()

void NyquistEffect::OnSave ( wxCommandEvent &  evt)
private

Definition at line 3122 of file Nyquist.cpp.

3123{
3124 FileDialogWrapper dlog(
3125 mUIParent,
3126 XO("Save Nyquist script"),
3127 mFileName.GetPath(),
3128 mFileName.GetFullName(),
3129 {
3130 NyquistScripts,
3131 LispScripts,
3132 FileNames::AllFiles
3133 },
3134 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
3135
3136 if (dlog.ShowModal() != wxID_OK)
3137 {
3138 return;
3139 }
3140
3141 mFileName = dlog.GetPath();
3142
3143 if (!mCommandText->SaveFile(mFileName.GetFullPath()))
3144 {
3145 EffectUIServices::DoMessageBox(*this, XO("File could not be saved"));
3146 }
3147}

References EffectUIServices::DoMessageBox(), FileDialog::GetPath(), mCommandText, mFileName, mUIParent, FileDialog::ShowModal(), and XO().

Here is the call graph for this function:

◆ OnSlider()

void NyquistEffect::OnSlider ( wxCommandEvent &  evt)
private

Definition at line 3149 of file Nyquist.cpp.

3150{
3151 int i = evt.GetId() - ID_Slider;
3152 NyqControl & ctrl = mControls[i];
3153
3154 int val = evt.GetInt();
3155 double range = ctrl.high - ctrl.low;
3156 double newVal = (val / (double)ctrl.ticks) * range + ctrl.low;
3157
3158 // Determine precision for displayed number
3159 int precision = range < 1.0 ? 3 :
3160 range < 10.0 ? 2 :
3161 range < 100.0 ? 1 :
3162 0;
3163
3164 // If the value is at least one tick different from the current value
3165 // change it (this prevents changes from manually entered values unless
3166 // the slider actually moved)
3167 if (fabs(newVal - ctrl.val) >= (1 / (double)ctrl.ticks) * range &&
3168 fabs(newVal - ctrl.val) >= pow(0.1, precision) / 2)
3169 {
3170 // First round to the appropriate precision
3171 newVal *= pow(10.0, precision);
3172 newVal = floor(newVal + 0.5);
3173 newVal /= pow(10.0, precision);
3174
3175 ctrl.val = newVal;
3176
3177 mUIParent->FindWindow(ID_Text + i)->GetValidator()->TransferToWindow();
3178 }
3179}

References NyqControl::high, ID_Slider, ID_Text, NyqControl::low, mControls, mUIParent, NyqControl::ticks, and NyqControl::val.

◆ OnText()

void NyquistEffect::OnText ( wxCommandEvent &  evt)
private

Definition at line 3392 of file Nyquist.cpp.

3393{
3394 int i = evt.GetId() - ID_Text;
3395
3396 NyqControl & ctrl = mControls[i];
3397
3398 if (wxDynamicCast(evt.GetEventObject(), wxWindow)->GetValidator()->TransferFromWindow())
3399 {
3400 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_INT)
3401 {
3402 int pos = (int)floor((ctrl.val - ctrl.low) /
3403 (ctrl.high - ctrl.low) * ctrl.ticks + 0.5);
3404
3405 wxSlider *slider = (wxSlider *)mUIParent->FindWindow(ID_Slider + i);
3406 slider->SetValue(pos);
3407 }
3408 }
3409}

References NyqControl::high, ID_Slider, ID_Text, NyqControl::low, mControls, mUIParent, NYQ_CTRL_FLOAT, NYQ_CTRL_INT, NyqControl::ticks, NyqControl::type, and NyqControl::val.

◆ OnTime()

void NyquistEffect::OnTime ( wxCommandEvent &  evt)
private

Definition at line 3186 of file Nyquist.cpp.

3187{
3188 int i = evt.GetId() - ID_Time;
3189 static double value = 0.0;
3190 NyqControl & ctrl = mControls[i];
3191
3192 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
3193 double val = n->GetValue();
3194
3195 // Observed that two events transmitted on each control change (Linux)
3196 // so skip if value has not changed.
3197 if (val != value) {
3198 if (val < ctrl.low || val > ctrl.high) {
3199 const auto message = XO("Value range:\n%s to %s")
3200 .Format( ToTimeFormat(ctrl.low), ToTimeFormat(ctrl.high) );
3202 message,
3203 wxOK | wxCENTRE,
3204 XO("Value Error") );
3205 }
3206
3207 if (val < ctrl.low)
3208 val = ctrl.low;
3209 else if (val > ctrl.high)
3210 val = ctrl.high;
3211
3212 n->SetValue(val);
3213 value = val;
3214 }
3215}
void SetValue(double newValue)
wxString ToTimeFormat(double t)
Definition: Nyquist.cpp:3382

References EffectUIServices::DoMessageBox(), NumericConverter::GetValue(), NyqControl::high, ID_Time, NyqControl::low, mControls, mUIParent, NumericTextCtrl::SetValue(), ToTimeFormat(), and XO().

Here is the call graph for this function:

◆ OSCallback()

void NyquistEffect::OSCallback ( )
private

Definition at line 2631 of file Nyquist.cpp.

2632{
2633 if (mStop) {
2634 mStop = false;
2635 nyx_stop();
2636 }
2637 else if (mBreak) {
2638 mBreak = false;
2639 nyx_break();
2640 }
2641 else if (mCont) {
2642 mCont = false;
2643 nyx_continue();
2644 }
2645
2646 // LLL: STF figured out that yielding while the effect is being applied
2647 // produces an EXTREME slowdown. It appears that yielding is not
2648 // really necessary on Linux and Windows.
2649 //
2650 // However, on the Mac, the spinning cursor appears during longer
2651 // Nyquist processing and that may cause the user to think Audacity
2652 // has crashed or hung. In addition, yielding or not on the Mac
2653 // doesn't seem to make much of a difference in execution time.
2654 //
2655 // So, yielding on the Mac only...
2656#if defined(__WXMAC__)
2657 wxYieldIfNeeded();
2658#endif
2659}
bool mStop
Definition: Nyquist.h:232

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2615 of file Nyquist.cpp.

2616{
2617 // Always collect Nyquist error messages for normal plug-ins
2618 if (!mRedirectOutput) {
2619 mDebugOutputStr += (wxChar)c;
2620 return;
2621 }
2622
2623 std::cout << (char)c;
2624}
bool mRedirectOutput
Definition: Nyquist.h:274
wxString mDebugOutputStr
Definition: Nyquist.h:276

References mDebugOutputStr, and mRedirectOutput.

◆ Parse()

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

Definition at line 2044 of file Nyquist.cpp.

2046{
2047 if ( !tzer.Tokenize(line, eof, first ? 1 : 0, 0) )
2048 return false;
2049
2050 const auto &tokens = tzer.tokens;
2051 int len = tokens.size();
2052 if (len < 1) {
2053 return true;
2054 }
2055
2056 // Consistency decision is for "plug-in" as the correct spelling
2057 // "plugin" (deprecated) is allowed as an undocumented convenience.
2058 if (len == 2 && tokens[0] == wxT("nyquist") &&
2059 (tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin"))) {
2060 mOK = true;
2061 return true;
2062 }
2063
2064 if (len >= 2 && tokens[0] == wxT("type")) {
2065 wxString tok = tokens[1];
2066 mIsTool = false;
2067 if (tok == wxT("tool")) {
2068 mIsTool = true;
2070 // we allow
2071 // ;type tool
2072 // ;type tool process
2073 // ;type tool generate
2074 // ;type tool analyze
2075 // The last three are placed in the tool menu, but are processed as
2076 // process, generate or analyze.
2077 if (len >= 3)
2078 tok = tokens[2];
2079 }
2080
2081 if (tok == wxT("process")) {
2083 }
2084 else if (tok == wxT("generate")) {
2086 }
2087 else if (tok == wxT("analyze")) {
2089 }
2090
2091 if (len >= 3 && tokens[2] == wxT("spectral")) {;
2092 mIsSpectral = true;
2093 }
2094 return true;
2095 }
2096
2097 if (len == 2 && tokens[0] == wxT("codetype")) {
2098 // This will stop ParseProgram() from doing a best guess as program type.
2099 if (tokens[1] == wxT("lisp")) {
2100 mIsSal = false;
2101 mFoundType = true;
2102 }
2103 else if (tokens[1] == wxT("sal")) {
2104 mIsSal = true;
2105 mFoundType = true;
2106 }
2107 return true;
2108 }
2109
2110 if (len >= 2 && tokens[0] == wxT("debugflags")) {
2111 for (int i = 1; i < len; i++) {
2112 // "trace" sets *tracenable* (LISP) or *sal-traceback* (SAL)
2113 // and displays debug window IF there is anything to show.
2114 if (tokens[i] == wxT("trace")) {
2115 mTrace = true;
2116 }
2117 else if (tokens[i] == wxT("notrace")) {
2118 mTrace = false;
2119 }
2120 else if (tokens[i] == wxT("compiler")) {
2121 mCompiler = true;
2122 }
2123 else if (tokens[i] == wxT("nocompiler")) {
2124 mCompiler = false;
2125 }
2126 }
2127 return true;
2128 }
2129
2130 // We support versions 1, 2 and 3
2131 // (Version 2 added support for string parameters.)
2132 // (Version 3 added support for choice parameters.)
2133 // (Version 4 added support for project/track/selection information.)
2134 if (len >= 2 && tokens[0] == wxT("version")) {
2135 long v;
2136 tokens[1].ToLong(&v);
2137 if (v < 1 || v > 4) {
2138 // This is an unsupported plug-in version
2139 mOK = false;
2140 mInitError = XO(
2141"This version of Audacity does not support Nyquist plug-in version %ld")
2142 .Format( v );
2143 return true;
2144 }
2145 mVersion = (int) v;
2146 }
2147
2148 if (len >= 2 && tokens[0] == wxT("name")) {
2149 // Names do not yet support context strings for translations, or
2150 // internal names distinct from visible English names.
2151 // (See also comments in NyquistEffectsModule::AutoRegisterPlugins)
2152 auto name = UnQuote(tokens[1]);
2153 // Strip ... from name if it's present, perhaps in third party plug-ins
2154 // Menu system puts ... back if there are any controls
2155 // This redundant naming convention must NOT be followed for
2156 // shipped Nyquist effects with internationalization. Else the msgid
2157 // later looked up will lack the ... and will not be found.
2158 if (name.EndsWith(wxT("...")))
2159 name = name.RemoveLast(3);
2160 mName = TranslatableString{ name, {} };
2161 return true;
2162 }
2163
2164 if (len >= 2 && tokens[0] == wxT("action")) {
2165 mAction = TranslatableString{ UnQuote(tokens[1]), {} };
2166 return true;
2167 }
2168
2169 if (len >= 2 && tokens[0] == wxT("info")) {
2170 mInfo = TranslatableString{ UnQuote(tokens[1]), {} };
2171 return true;
2172 }
2173
2174 if (len >= 2 && tokens[0] == wxT("preview")) {
2175 if (tokens[1] == wxT("enabled") || tokens[1] == wxT("true")) {
2176 mEnablePreview = true;
2177 SetLinearEffectFlag(false);
2178 }
2179 else if (tokens[1] == wxT("linear")) {
2180 mEnablePreview = true;
2181 SetLinearEffectFlag(true);
2182 }
2183 else if (tokens[1] == wxT("selection")) {
2184 mEnablePreview = true;
2186 }
2187 else if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
2188 mEnablePreview = false;
2189 }
2190 return true;
2191 }
2192
2193 // Maximum number of samples to be processed. This can help the
2194 // progress bar if effect does not process all of selection.
2195 if (len >= 2 && tokens[0] == wxT("maxlen")) {
2196 long long v; // Note that Nyquist may overflow at > 2^31 samples (bug 439)
2197 tokens[1].ToLongLong(&v);
2198 mMaxLen = (sampleCount) v;
2199 }
2200
2201#if defined(EXPERIMENTAL_NYQUIST_SPLIT_CONTROL)
2202 if (len >= 2 && tokens[0] == wxT("mergeclips")) {
2203 long v;
2204 // -1 = auto (default), 0 = don't merge clips, 1 = do merge clips
2205 tokens[1].ToLong(&v);
2206 mMergeClips = v;
2207 return true;
2208 }
2209
2210 if (len >= 2 && tokens[0] == wxT("restoresplits")) {
2211 long v;
2212 // Splits are restored by default. Set to 0 to prevent.
2213 tokens[1].ToLong(&v);
2214 mRestoreSplits = !!v;
2215 return true;
2216 }
2217#endif
2218
2219 if (len >= 2 && tokens[0] == wxT("author")) {
2220 mAuthor = TranslatableString{ UnQuote(tokens[1]), {} };
2221 return true;
2222 }
2223
2224 if (len >= 2 && tokens[0] == wxT("release")) {
2225 // Value must be quoted if the release version string contains spaces.
2227 TranslatableString{ UnQuote(tokens[1]), {} };
2228 return true;
2229 }
2230
2231 if (len >= 2 && tokens[0] == wxT("copyright")) {
2232 mCopyright = TranslatableString{ UnQuote(tokens[1]), {} };
2233 return true;
2234 }
2235
2236 // Page name in Audacity development manual
2237 if (len >= 2 && tokens[0] == wxT("manpage")) {
2238 // do not translate
2239 mManPage = UnQuote(tokens[1], false);
2240 return true;
2241 }
2242
2243 // Local Help file
2244 if (len >= 2 && tokens[0] == wxT("helpfile")) {
2245 // do not translate
2246 mHelpFile = UnQuote(tokens[1], false);
2247 return true;
2248 }
2249
2250 // Debug button may be disabled for release plug-ins.
2251 if (len >= 2 && tokens[0] == wxT("debugbutton")) {
2252 if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
2253 mDebugButton = false;
2254 }
2255 return true;
2256 }
2257
2258
2259 if (len >= 3 && tokens[0] == wxT("control")) {
2260 NyqControl ctrl;
2261
2262 if (len == 3 && tokens[1] == wxT("text")) {
2263 ctrl.var = tokens[1];
2264 ctrl.label = UnQuote( tokens[2] );
2265 ctrl.type = NYQ_CTRL_TEXT;
2266 }
2267 else if (len >= 5)
2268 {
2269 ctrl.var = tokens[1];
2270 ctrl.name = UnQuote( tokens[2] );
2271 // 3 is type, below
2272 ctrl.label = tokens[4];
2273
2274 // valStr may or may not be a quoted string
2275 ctrl.valStr = len > 5 ? tokens[5] : wxString{};
2276 ctrl.val = GetCtrlValue(ctrl.valStr);
2277 if (ctrl.valStr.length() > 0 &&
2278 (ctrl.valStr[0] == wxT('(') ||
2279 ctrl.valStr[0] == wxT('"')))
2280 ctrl.valStr = UnQuote( ctrl.valStr );
2281
2282 // 6 is minimum, below
2283 // 7 is maximum, below
2284
2285 if (tokens[3] == wxT("string")) {
2286 ctrl.type = NYQ_CTRL_STRING;
2287 ctrl.label = UnQuote( ctrl.label );
2288 }
2289 else if (tokens[3] == wxT("choice")) {
2290 ctrl.type = NYQ_CTRL_CHOICE;
2291 ctrl.choices = ParseChoice(ctrl.label);
2292 ctrl.label = wxT("");
2293 }
2294 else if (tokens[3] == wxT("file")) {
2295 ctrl.type = NYQ_CTRL_FILE;
2296 ctrl.fileTypes = ParseFileTypes(tokens[6]);
2297 // will determine file dialog styles:
2298 ctrl.highStr = UnQuote( tokens[7] );
2299 ctrl.label = UnQuote(ctrl.label);
2300 }
2301 else {
2302 ctrl.label = UnQuote( ctrl.label );
2303
2304 if (len < 8) {
2305 return true;
2306 }
2307
2308 if ((tokens[3] == wxT("float")) ||
2309 (tokens[3] == wxT("real"))) // Deprecated
2310 ctrl.type = NYQ_CTRL_FLOAT;
2311 else if (tokens[3] == wxT("int"))
2312 ctrl.type = NYQ_CTRL_INT;
2313 else if (tokens[3] == wxT("float-text"))
2315 else if (tokens[3] == wxT("int-text"))
2316 ctrl.type = NYQ_CTRL_INT_TEXT;
2317 else if (tokens[3] == wxT("time"))
2318 ctrl.type = NYQ_CTRL_TIME;
2319 else
2320 {
2321 wxString str;
2322 str.Printf(wxT("Bad Nyquist 'control' type specification: '%s' in plug-in file '%s'.\nControl not created."),
2323 tokens[3], mFileName.GetFullPath());
2324
2325 // Too disturbing to show alert before Audacity frame is up.
2326 // EffectUIServices::DoMessageBox(*this,
2327 // str,
2328 // wxOK | wxICON_EXCLAMATION,
2329 // XO("Nyquist Warning") );
2330
2331 // Note that the AudacityApp's mLogger has not yet been created,
2332 // so this brings up an alert box, but after the Audacity frame is up.
2333 wxLogWarning(str);
2334 return true;
2335 }
2336
2337 ctrl.lowStr = UnQuote( tokens[6] );
2338 if (ctrl.type == NYQ_CTRL_INT_TEXT && ctrl.lowStr.IsSameAs(wxT("nil"), false)) {
2339 ctrl.low = INT_MIN;
2340 }
2341 else if (ctrl.type == NYQ_CTRL_FLOAT_TEXT && ctrl.lowStr.IsSameAs(wxT("nil"), false)) {
2342 ctrl.low = -(FLT_MAX);
2343 }
2344 else if (ctrl.type == NYQ_CTRL_TIME && ctrl.lowStr.IsSameAs(wxT("nil"), false)) {
2345 ctrl.low = 0.0;
2346 }
2347 else {
2348 ctrl.low = GetCtrlValue(ctrl.lowStr);
2349 }
2350
2351 ctrl.highStr = UnQuote( tokens[7] );
2352 if (ctrl.type == NYQ_CTRL_INT_TEXT && ctrl.highStr.IsSameAs(wxT("nil"), false)) {
2353 ctrl.high = INT_MAX;
2354 }
2355 else if ((ctrl.type == NYQ_CTRL_FLOAT_TEXT || ctrl.type == NYQ_CTRL_TIME) &&
2356 ctrl.highStr.IsSameAs(wxT("nil"), false))
2357 {
2358 ctrl.high = FLT_MAX;
2359 }
2360 else {
2361 ctrl.high = GetCtrlValue(ctrl.highStr);
2362 }
2363
2364 if (ctrl.high < ctrl.low) {
2365 ctrl.high = ctrl.low;
2366 }
2367
2368 if (ctrl.val < ctrl.low) {
2369 ctrl.val = ctrl.low;
2370 }
2371
2372 if (ctrl.val > ctrl.high) {
2373 ctrl.val = ctrl.high;
2374 }
2375
2376 ctrl.ticks = 1000;
2377 if (ctrl.type == NYQ_CTRL_INT &&
2378 (ctrl.high - ctrl.low < ctrl.ticks)) {
2379 ctrl.ticks = (int)(ctrl.high - ctrl.low);
2380 }
2381 }
2382 }
2383
2384 if( ! make_iterator_range( mPresetNames ).contains( ctrl.var ) )
2385 {
2386 mControls.push_back(ctrl);
2387 }
2388 }
2389
2390 // Deprecated
2391 if (len >= 2 && tokens[0] == wxT("categories")) {
2392 for (size_t i = 1; i < tokens.size(); ++i) {
2393 mCategories.push_back(tokens[i]);
2394 }
2395 }
2396 return true;
2397}
const TranslatableString name
Definition: Distortion.cpp:76
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeProcess
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:448
void SetPreviewFullSelectionFlag(bool previewDurationFlag)
Definition: EffectBase.cpp:219
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:214
wxArrayString mPresetNames
Definition: EffectBase.h:118
wxString var
Definition: Nyquist.h:51
wxString lowStr
Definition: Nyquist.h:57
static double GetCtrlValue(const wxString &s)
Definition: Nyquist.cpp:1927
bool mRestoreSplits
Definition: Nyquist.h:309
bool mFoundType
Definition: Nyquist.h:236
FileNames::FileTypes ParseFileTypes(const wxString &text)
Definition: Nyquist.cpp:1813
int mMergeClips
Definition: Nyquist.h:310
TranslatableString mAction
Definition: Nyquist.h:255
bool mCompiler
Definition: Nyquist.h:237
wxArrayString mCategories
Definition: Nyquist.h:304
static std::vector< EnumValueSymbol > ParseChoice(const wxString &text)
Definition: Nyquist.cpp:1753
static wxString UnQuote(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1921
bool mTrace
Definition: Nyquist.h:238
bool mIsSal
Definition: Nyquist.h:239
TranslatableString mInfo
Definition: Nyquist.h:256
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, name, NyqControl::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, NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 > NyquistEffect::ParseChoice ( const wxString &  text)
staticprivate

Definition at line 1753 of file Nyquist.cpp.

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

References label, NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 NyquistEffect::ParseCommand ( const wxString &  cmd)
private

Definition at line 2505 of file Nyquist.cpp.

2506{
2507 wxStringInputStream stream(cmd + wxT(" "));
2508
2509 return ParseProgram(stream);
2510}
bool ParseProgram(wxInputStream &stream)
Definition: Nyquist.cpp:2399

References ParseProgram(), and wxT().

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

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

◆ ParseFile()

void NyquistEffect::ParseFile ( )
private

Definition at line 2497 of file Nyquist.cpp.

2498{
2499 wxFileInputStream rawStream(mFileName.GetFullPath());
2500 wxBufferedInputStream stream(rawStream, 10000);
2501
2502 ParseProgram(stream);
2503}

References mFileName, and ParseProgram().

Here is the call graph for this function:

◆ ParseFileExtensions()

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

Definition at line 1785 of file Nyquist.cpp.

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

References NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 NyquistEffect::ParseFileType ( const wxString &  text)
private

Definition at line 1798 of file Nyquist.cpp.

1799{
1800 // todo: error handling
1801 FileNames::FileType result;
1802 if (text[0] == wxT('(')) {
1803 Tokenizer tzer;
1804 tzer.Tokenize(text, true, 1, 1);
1805 auto &tokens = tzer.tokens;
1806 if ( tokens.size() == 2 )
1807 result =
1808 { UnQuoteMsgid( tokens[0] ), ParseFileExtensions( tokens[1] ) };
1809 }
1810 return result;
1811}
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1880
FileExtensions ParseFileExtensions(const wxString &text)
Definition: Nyquist.cpp:1785

References ParseFileExtensions(), NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 NyquistEffect::ParseFileTypes ( const wxString &  text)
private

Definition at line 1813 of file Nyquist.cpp.

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

References ParseFileType(), size, str, NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 NyquistEffect::ParseProgram ( wxInputStream &  stream)
private

Definition at line 2399 of file Nyquist.cpp.

2400{
2401 if (!stream.IsOk())
2402 {
2403 mInitError = XO("Could not open file");
2404 return false;
2405 }
2406
2407 wxTextInputStream pgm(stream, wxT(" \t"), wxConvAuto());
2408
2409 mCmd = wxT("");
2410 mCmd.Alloc(10000);
2411 mIsSal = false;
2412 mControls.clear();
2413 mCategories.clear();
2414 mIsSpectral = false;
2415 mManPage = wxEmptyString; // If not wxEmptyString, must be a page in the Audacity manual.
2416 mHelpFile = wxEmptyString; // If not wxEmptyString, must be a valid HTML help file.
2417 mHelpFileExists = false;
2418 mDebug = false;
2419 mTrace = false;
2420 mDebugButton = true; // Debug button enabled by default.
2421 mEnablePreview = true; // Preview button enabled by default.
2422
2423 // Bug 1934.
2424 // All Nyquist plug-ins should have a ';type' field, but if they don't we default to
2425 // being an Effect.
2427
2428 mFoundType = false;
2429 while (!stream.Eof() && stream.IsOk())
2430 {
2431 wxString line = pgm.ReadLine();
2432 if (line.length() > 1 &&
2433 // New in 2.3.0: allow magic comment lines to start with $
2434 // The trick is that xgettext will not consider such lines comments
2435 // and will extract the strings they contain
2436 (line[0] == wxT(';') || line[0] == wxT('$')) )
2437 {
2438 Tokenizer tzer;
2439 unsigned nLines = 1;
2440 bool done;
2441 // Allow continuations within control lines.
2442 bool control =
2443 line[0] == wxT('$') || line.StartsWith( wxT(";control") );
2444 do
2445 done = Parse(tzer, line, !control || stream.Eof(), nLines == 1);
2446 while(!done &&
2447 (line = pgm.ReadLine(), ++nLines, true));
2448
2449 // Don't pass these lines to the interpreter, so it doesn't get confused
2450 // by $, but pass blanks,
2451 // so that SAL effects compile with proper line numbers
2452 while (nLines --)
2453 mCmd += wxT('\n');
2454 }
2455 else
2456 {
2457 if(!mFoundType && line.length() > 0) {
2458 if (line[0] == wxT('(') ||
2459 (line[0] == wxT('#') && line.length() > 1 && line[1] == wxT('|')))
2460 {
2461 mIsSal = false;
2462 mFoundType = true;
2463 }
2464 else if (line.Upper().Find(wxT("RETURN")) != wxNOT_FOUND)
2465 {
2466 mIsSal = true;
2467 mFoundType = true;
2468 }
2469 }
2470 mCmd += line + wxT("\n");
2471 }
2472 }
2473 if (!mFoundType && mIsPrompt)
2474 {
2475 /* i1n-hint: SAL and LISP are names for variant syntaxes for the
2476 Nyquist programming language. Leave them, and 'return', untranslated. */
2478 XO(
2479"Your code looks like SAL syntax, but there is no \'return\' statement.\n\
2480For SAL, use a return statement such as:\n\treturn *track* * 0.1\n\
2481or for LISP, begin with an open parenthesis such as:\n\t(mult *track* 0.1)\n ."),
2483 XO("Error in Nyquist code") );
2484 /* i18n-hint: refers to programming "languages" */
2485 mInitError = XO("Could not determine language");
2486 return false;
2487 // Else just throw it at Nyquist to see what happens
2488 }
2489
2490 const auto helpStuff = CheckHelpPage();
2491 mHelpFileExists = helpStuff.first;
2492 mHelpPage = helpStuff.second;
2493
2494 return true;
2495}
std::pair< bool, FilePath > CheckHelpPage() const
Definition: Nyquist.cpp:253
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
Definition: Nyquist.cpp:2044
bool mHelpFileExists
Definition: Nyquist.h:265
bool mDebug
Definition: Nyquist.h:273
wxString mCmd
Definition: Nyquist.h:252

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

Referenced by ParseCommand(), and ParseFile().

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

◆ PopulateOrExchange()

std::unique_ptr< EffectEditor > NyquistEffect::PopulateOrExchange ( ShuttleGui S,
EffectInstance instance,
EffectSettingsAccess access,
const EffectOutputs pOutputs 
)
overridevirtual

Add controls to effect panel; always succeeds.

Returns
if not null, then return it from PopulateUI instead of a DefaultEffectEditor; default implementation returns null

Reimplemented from StatefulEffectUIServices.

Definition at line 1137 of file Nyquist.cpp.

1140{
1141 mUIParent = S.GetParent();
1142 if (mIsPrompt)
1144 else
1146 return nullptr;
1147}
void BuildEffectWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2912
void BuildPromptWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2880

References BuildEffectWindow(), BuildPromptWindow(), mIsPrompt, mUIParent, and S.

Here is the call graph for this function:

◆ Process()

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

Implements StatefulEffectBase.

Definition at line 664 of file Nyquist.cpp.

665{
666 if (mIsPrompt && mControls.size() > 0 && !IsBatchProcessing()) {
667 auto &nyquistSettings = GetSettings(settings);
668 auto cleanup = finally([&]{
669 // Free up memory
670 nyquistSettings.proxySettings = {};
671 });
673 proxy.SetCommand(mInputCmd);
674 proxy.mDebug = nyquistSettings.proxyDebug;
675 proxy.mControls = move(nyquistSettings.controls);
676 auto result = Delegate(proxy, nyquistSettings.proxySettings);
677 if (result) {
678 mT0 = proxy.mT0;
679 mT1 = proxy.mT1;
680 }
681 return result;
682 }
683
684 // Check for reentrant Nyquist commands.
685 // I'm choosing to mark skipped Nyquist commands as successful even though
686 // they are skipped. The reason is that when Nyquist calls out to a chain,
687 // and that chain contains Nyquist, it will be clearer if the chain completes
688 // skipping Nyquist, rather than doing nothing at all.
689 if( mReentryCount > 0 )
690 return true;
691
692 // Restore the reentry counter (to zero) when we exit.
693 auto countRestorer = valueRestorer( mReentryCount);
696
697 bool success = true;
698 int nEffectsSoFar = nEffectsDone;
699 mProjectChanged = false;
701 em.SetSkipStateFlag(false);
702
703 // This code was added in a fix for bug 2392 (no preview for Nyquist)
704 // It was commented out in a fix for bug 2428 (no progress dialog from a macro)
705 //if (mExternal) {
706 // mProgress->Hide();
707 //}
708
709 mOutputTime = 0;
710 mCount = 0;
711 mProgressIn = 0;
712 mProgressOut = 0;
713 mProgressTot = 0;
714 mScale = (GetType() == EffectTypeProcess ? 0.5 : 1.0) / GetNumWaveGroups();
715
716 mStop = false;
717 mBreak = false;
718 mCont = false;
719
720 mTrackIndex = 0;
721
722 // If in tool mode, then we don't do anything with the track and selection.
723 const bool bOnePassTool = (GetType() == EffectTypeTool);
724
725 // We must copy all the tracks, because Paste needs label tracks to ensure
726 // correct sync-lock group behavior when the timeline is affected; then we just want
727 // to operate on the selected wave tracks
728 if ( !bOnePassTool )
729 CopyInputTracks(true);
730
731 mNumSelectedChannels = bOnePassTool
732 ? 0
733 : mOutputTracks->Selected< const WaveTrack >().size();
734
735 mDebugOutput = {};
736 if (!mHelpFile.empty() && !mHelpFileExists) {
738"error: File \"%s\" specified in header but not found in plug-in path.\n")
739 .Format( mHelpFile );
740 }
741
742 if (mVersion >= 4)
743 {
744 auto project = FindProject();
745
746 mProps = wxEmptyString;
747
748 mProps += wxString::Format(wxT("(putprop '*AUDACITY* (list %d %d %d) 'VERSION)\n"), AUDACITY_VERSION, AUDACITY_RELEASE, AUDACITY_REVISION);
749 wxString lang = gPrefs->Read(wxT("/Locale/Language"), wxT(""));
750 lang = (lang.empty())
752 : lang;
753 mProps += wxString::Format(wxT("(putprop '*AUDACITY* \"%s\" 'LANGUAGE)\n"), lang);
754
755 mProps += wxString::Format(wxT("(setf *DECIMAL-SEPARATOR* #\\%c)\n"), wxNumberFormatter::GetDecimalSeparator());
756
757 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'BASE)\n"), EscapeString(FileNames::BaseDir()));
758 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'DATA)\n"), EscapeString(FileNames::DataDir()));
759 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'HELP)\n"), EscapeString(FileNames::HtmlHelpDir().RemoveLast()));
760 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'TEMP)\n"), EscapeString(TempDirectory::TempDir()));
761 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'SYS-TEMP)\n"), EscapeString(wxStandardPaths::Get().GetTempDir()));
762 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'DOCUMENTS)\n"), EscapeString(wxStandardPaths::Get().GetDocumentsDir()));
763 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'HOME)\n"), EscapeString(wxGetHomeDir()));
764
766 wxString list;
767 for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
768 {
769 list += wxT("\"") + EscapeString(paths[i]) + wxT("\" ");
770 }
771 list = list.RemoveLast();
772
773 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* (list %s) 'PLUGIN)\n"), list);
774 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* (list %s) 'PLUG-IN)\n"), list);
775 mProps += wxString::Format(wxT("(putprop '*SYSTEM-DIR* \"%s\" 'USER-PLUG-IN)\n"),
777
778 // Date and time:
779 wxDateTime now = wxDateTime::Now();
780 int year = now.GetYear();
781 int doy = now.GetDayOfYear();
782 int dom = now.GetDay();
783 // enumerated constants
784 wxDateTime::Month month = now.GetMonth();
785 wxDateTime::WeekDay day = now.GetWeekDay();
786
787 // Date/time as a list: year, day of year, hour, minute, seconds
788 mProps += wxString::Format(wxT("(setf *SYSTEM-TIME* (list %d %d %d %d %d))\n"),
789 year, doy, now.GetHour(), now.GetMinute(), now.GetSecond());
790
791 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DATE)\n"), now.FormatDate());
792 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'TIME)\n"), now.FormatTime());
793 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'ISO-DATE)\n"), now.FormatISODate());
794 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'ISO-TIME)\n"), now.FormatISOTime());
795 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* %d 'YEAR)\n"), year);
796 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* %d 'DAY)\n"), dom); // day of month
797 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* %d 'MONTH)\n"), month);
798 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'MONTH-NAME)\n"), now.GetMonthName(month));
799 mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"), now.GetWeekDayName(day));
800
801 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"),
802 (int) AllProjects{}.size());
803 mProps += wxString::Format(wxT("(putprop '*PROJECT* \"%s\" 'NAME)\n"), EscapeString(project->GetProjectName()));
804
805 int numTracks = 0;
806 int numWave = 0;
807 int numLabel = 0;
808 int numMidi = 0;
809 int numTime = 0;
810 wxString waveTrackList; // track positions of selected audio tracks.
811
812 {
813 auto countRange = TrackList::Get( *project ).Leaders();
814 for (auto t : countRange) {
815 t->TypeSwitch( [&](const WaveTrack *) {
816 numWave++;
817 if (t->GetSelected())
818 waveTrackList += wxString::Format(wxT("%d "), 1 + numTracks);
819 });
820 numTracks++;
821 }
822 numLabel = countRange.Filter<const LabelTrack>().size();
823 #if defined(USE_MIDI)
824 numMidi = countRange.Filter<const NoteTrack>().size();
825 #endif
826 numTime = countRange.Filter<const TimeTrack>().size();
827 }
828
829 // We use Internat::ToString() rather than "%g" here because we
830 // always have to use the dot as decimal separator when giving
831 // numbers to Nyquist, whereas using "%g" will use the user's
832 // decimal separator which may be a comma in some countries.
833 mProps += wxString::Format(wxT("(putprop '*PROJECT* (float %s) 'RATE)\n"),
835 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'TRACKS)\n"), numTracks);
836 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'WAVETRACKS)\n"), numWave);
837 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'LABELTRACKS)\n"), numLabel);
838 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'MIDITRACKS)\n"), numMidi);
839 mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'TIMETRACKS)\n"), numTime);
840
841 double previewLen = 6.0;
842 gPrefs->Read(wxT("/AudioIO/EffectsPreviewLen"), &previewLen);
843 mProps += wxString::Format(wxT("(putprop '*PROJECT* (float %s) 'PREVIEW-DURATION)\n"),
844 Internat::ToString(previewLen));
845
846 // *PREVIEWP* is true when previewing (better than relying on track view).
847 wxString isPreviewing = (this->IsPreviewing())? wxT("T") : wxT("NIL");
848 mProps += wxString::Format(wxT("(setf *PREVIEWP* %s)\n"), isPreviewing);
849
850 mProps += wxString::Format(wxT("(putprop '*SELECTION* (float %s) 'START)\n"),
852 mProps += wxString::Format(wxT("(putprop '*SELECTION* (float %s) 'END)\n"),
854 mProps += wxString::Format(wxT("(putprop '*SELECTION* (list %s) 'TRACKS)\n"), waveTrackList);
855 mProps += wxString::Format(wxT("(putprop '*SELECTION* %d 'CHANNELS)\n"), mNumSelectedChannels);
856 }
857
858 // Nyquist Prompt does not require a selection, but effects do.
859 if (!bOnePassTool && (mNumSelectedChannels == 0)) {
860 auto message = XO("Audio selection required.");
862 message,
863 wxOK | wxCENTRE | wxICON_EXCLAMATION,
864 XO("Nyquist Error") );
865 }
866
867 std::optional<TrackIterRange<WaveTrack>> pRange;
868 if (!bOnePassTool)
869 pRange.emplace(mOutputTracks->Selected< WaveTrack >() + &Track::IsLeader);
870
871 // Keep track of whether the current track is first selected in its sync-lock group
872 // (we have no idea what the length of the returned audio will be, so we have
873 // to handle sync-lock group behavior the "old" way).
874 mFirstInGroup = true;
875 Track *gtLast = NULL;
876
877 for (;
878 bOnePassTool || pRange->first != pRange->second;
879 (void) (!pRange || (++pRange->first, true))
880 ) {
881 // Prepare to accumulate more debug output in OutputCallback
883 mDebugOutput = Verbatim( "%s" ).Format( std::cref( mDebugOutputStr ) );
884
885 mCurTrack[0] = pRange ? *pRange->first : nullptr;
886 mCurNumChannels = 1;
887 if ( (mT1 >= mT0) || bOnePassTool ) {
888 if (bOnePassTool) {
889 }
890 else {
891 auto channels = TrackList::Channels(mCurTrack[0]);
892 if (channels.size() > 1) {
893 // TODO: more-than-two-channels
894 // Pay attention to consistency of mNumSelectedChannels
895 // with the running tally made by this loop!
896 mCurNumChannels = 2;
897
898 mCurTrack[1] = * ++ channels.first;
899 if (mCurTrack[1]->GetRate() != mCurTrack[0]->GetRate()) {
901 XO(
902"Sorry, cannot apply effect on stereo tracks where the tracks don't match."),
903 wxOK | wxCENTRE );
904 success = false;
905 goto finish;
906 }
908 }
909
910 // Check whether we're in the same group as the last selected track
911 Track *gt = *SyncLock::Group(mCurTrack[0]).first;
912 mFirstInGroup = !gtLast || (gtLast != gt);
913 gtLast = gt;
914
917 mCurLen = end - mCurStart[0];
918
919 if (mCurLen > NYQ_MAX_LEN) {
920 float hours = (float)NYQ_MAX_LEN / (44100 * 60 * 60);
921 const auto message =
922 XO(
923"Selection too long for Nyquist code.\nMaximum allowed selection is %ld samples\n(about %.1f hours at 44100 Hz sample rate).")
924 .Format((long)NYQ_MAX_LEN, hours);
926 message,
927 wxOK | wxCENTRE,
928 XO("Nyquist Error") );
929 if (!mProjectChanged)
930 em.SetSkipStateFlag(true);
931 return false;
932 }
933
935 }
936
937 mProgressIn = 0.0;
938 mProgressOut = 0.0;
939
940 // libnyquist breaks except in LC_NUMERIC=="C".
941 //
942 // Note that we must set the locale to "C" even before calling
943 // nyx_init() because otherwise some effects will not work!
944 //
945 // MB: setlocale is not thread-safe. Should use uselocale()
946 // if available, or fix libnyquist to be locale-independent.
947 // See also http://bugzilla.audacityteam.org/show_bug.cgi?id=642#c9
948 // for further info about this thread safety question.
949 wxString prevlocale = wxSetlocale(LC_NUMERIC, NULL);
950 wxSetlocale(LC_NUMERIC, wxString(wxT("C")));
951
952 nyx_init();
953 nyx_set_os_callback(StaticOSCallback, (void *)this);
954 nyx_capture_output(StaticOutputCallback, (void *)this);
955
956 auto cleanup = finally( [&] {
957 nyx_capture_output(NULL, (void *)NULL);
958 nyx_set_os_callback(NULL, (void *)NULL);
959 nyx_cleanup();
960 } );
961
962
963 if (mVersion >= 4)
964 {
965 mPerTrackProps = wxEmptyString;
966 wxString lowHz = wxT("nil");
967 wxString highHz = wxT("nil");
968 wxString centerHz = wxT("nil");
969 wxString bandwidth = wxT("nil");
970
971#if defined(EXPERIMENTAL_SPECTRAL_EDITING)
972 if (mF0 >= 0.0) {
973 lowHz.Printf(wxT("(float %s)"), Internat::ToString(mF0));
974 }
975
976 if (mF1 >= 0.0) {
977 highHz.Printf(wxT("(float %s)"), Internat::ToString(mF1));
978 }
979
980 if ((mF0 >= 0.0) && (mF1 >= 0.0)) {
981 centerHz.Printf(wxT("(float %s)"), Internat::ToString(sqrt(mF0 * mF1)));
982 }
983
984 if ((mF0 > 0.0) && (mF1 >= mF0)) {
985 // with very small values, bandwidth calculation may be inf.
986 // (Observed on Linux)
987 double bw = log(mF1 / mF0) / log(2.0);
988 if (!std::isinf(bw)) {
989 bandwidth.Printf(wxT("(float %s)"), Internat::ToString(bw));
990 }
991 }
992
993#endif
994 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'LOW-HZ)\n"), lowHz);
995 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'CENTER-HZ)\n"), centerHz);
996 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'HIGH-HZ)\n"), highHz);
997 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'BANDWIDTH)\n"), bandwidth);
998 }
999
1000 success = ProcessOne();
1001
1002 // Reset previous locale
1003 wxSetlocale(LC_NUMERIC, prevlocale);
1004
1005 if (!success || bOnePassTool) {
1006 goto finish;
1007 }
1009 }
1010
1012 }
1013
1014 if (mOutputTime > 0.0) {
1015 mT1 = mT0 + mOutputTime;
1016 }
1017
1018finish:
1019
1020 // Show debug window if trace set in plug-in header and something to show.
1021 mDebug = (mTrace && !mDebugOutput.Translation().empty())? true : mDebug;
1022
1023 if (mDebug && !mRedirectOutput) {
1025 mName,
1026 XO("Debug Output: "),
1027 mDebugOutput);
1028 dlog.CentreOnParent();
1029 dlog.ShowModal();
1030 }
1031
1032 // Has rug been pulled from under us by some effect done within Nyquist??
1033 if( !bOnePassTool && ( nEffectsSoFar == nEffectsDone ))
1034 ReplaceProcessedTracks(success);
1035 else{
1036 ReplaceProcessedTracks(false); // Do not use the results.
1037 // Selection is to be set to whatever it is in the project.
1038 auto project = FindProject();
1039 if (project) {
1040 auto &selectedRegion = ViewInfo::Get( *project ).selectedRegion;
1041 mT0 = selectedRegion.t0();
1042 mT1 = selectedRegion.t1();
1043 }
1044 else {
1045 mT0 = 0;
1046 mT1 = -1;
1047 }
1048
1049 }
1050
1051 if (!mProjectChanged)
1052 em.SetSkipStateFlag(true);
1053
1054 return success;
1055}
int min(int a, int b)
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:251
#define NYQUIST_WORKER_ID
Definition: Nyquist.cpp:95
static void RegisterFunctions()
Definition: Nyquist.cpp:3579
FileConfig * gPrefs
Definition: Prefs.cpp:70
size_t size() const
Definition: Project.cpp:17
double mT1
Definition: EffectBase.h:113
std::shared_ptr< TrackList > mOutputTracks
Definition: EffectBase.h:111
bool IsPreviewing() const
Definition: EffectBase.h:89
double mT0
Definition: EffectBase.h:112
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: EffectBase.cpp:232
static int nEffectsDone
Definition: EffectBase.h:97
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:396
bool Delegate(Effect &delegate, EffectSettings &settings)
Re-invoke DoEffect on another Effect object that implements the work.
Definition: Effect.cpp:329
int GetNumWaveGroups() const
Definition: Effect.h:141
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:48
void SetSkipStateFlag(bool flag)
static EffectManager & Get()
static NyquistSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:177
static wxString ToString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, always uses the dot as decimal separator.
Definition: Internat.cpp:150
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:87
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:63
TranslatableString mDebugOutput
Definition: Nyquist.h:277
static void StaticOSCallback(void *userdata)
Definition: Nyquist.cpp:2626
static void StaticOutputCallback(int c, void *userdata)
Definition: Nyquist.cpp:2610
unsigned mCurNumChannels
Definition: Nyquist.h:282
EffectType GetType() const override
Type determines how it behaves.
Definition: Nyquist.cpp:276
wxString mPerTrackProps
Definition: Nyquist.h:307
static int mReentryCount
Definition: Nyquist.h:144
unsigned mNumSelectedChannels
Definition: Nyquist.h:291
bool ProcessOne()
Definition: Nyquist.cpp:1192
bool mProjectChanged
Definition: Nyquist.h:275
bool mFirstInGroup
Definition: Nyquist.h:288
wxString EscapeString(const wxString &inStr)
Definition: Nyquist.cpp:1743
wxString mProps
Definition: Nyquist.h:306
int mTrackIndex
Definition: Nyquist.h:287
double mOutputTime
Definition: Nyquist.h:289
unsigned mCount
Definition: Nyquist.h:290
Dialog used with NyquistEffect.
Definition: Nyquist.h:322
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: SampleTrack.cpp:43
static TrackIterRange< Track > Group(Track *pTrack)
Definition: SyncLock.cpp:161
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:25
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:226
bool IsLeader() const
Definition: Track.cpp:406
auto Leaders() -> TrackIterRange< TrackType >
Definition: Track.h:1474
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1544
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196
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
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
FILES_API wxString TempDir()

References FileNames::AudacityPathList(), FileNames::BaseDir(), TrackList::Channels(), Effect::CopyInputTracks(), FileNames::DataDir(), Effect::Delegate(), EffectUIServices::DoMessageBox(), EffectTypeProcess, EffectTypeTool, PackedArray::end(), EscapeString(), EffectBase::FindProject(), TranslatableString::Format(), BasicUI::Get(), EffectManager::Get(), ProjectRate::Get(), ViewInfo::Get(), TrackList::Get(), Effect::GetNumWaveGroups(), GetNyquistSearchPath(), anonymous_namespace{TimeTrack.cpp}::GetRate(), ProjectRate::GetRate(), EffectWithSettings< NyquistSettings, StatefulEffect >::GetSettings(), Languages::GetSystemLanguageCode(), GetType(), gPrefs, SyncLock::Group(), FileNames::HtmlHelpDir(), Effect::IsBatchProcessing(), Track::IsLeader(), EffectBase::IsPreviewing(), TrackList::Leaders(), mBreak, mCont, mControls, mCount, mCurLen, mCurNumChannels, mCurStart, mCurTrack, mDebug, mDebugOutput, mDebugOutputStr, mFirstInGroup, mHelpFile, mHelpFileExists, min(), mInputCmd, mIsPrompt, mMaxLen, mName, mNumSelectedChannels, mOutputTime, EffectBase::mOutputTracks, mPerTrackProps, mProgressIn, mProgressOut, mProgressTot, mProjectChanged, mProps, mRedirectOutput, mReentryCount, mScale, mStop, EffectBase::mT0, EffectBase::mT1, mTrace, mTrackIndex, mUIParent, mVersion, EffectBase::nEffectsDone, NYQ_MAX_LEN, NYQUIST_WORKER_ID, FileNames::PlugInDir(), ProcessOne(), RegisterFunctions(), EffectBase::ReplaceProcessedTracks(), ViewInfo::selectedRegion, EffectManager::SetSkipStateFlag(), settings(), size, AllProjects::size(), StaticOSCallback(), StaticOutputCallback(), TempDirectory::TempDir(), SampleTrack::TimeToLongSamples(), Internat::ToString(), TranslatableString::Translation(), valueRestorer(), Verbatim(), wxT(), and XO().

Here is the call graph for this function:

◆ ProcessOne()

bool NyquistEffect::ProcessOne ( )
private

Definition at line 1192 of file Nyquist.cpp.

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

References Effect::AddToOutputTracks(), sampleCount::as_long_long(), PackedArray::begin(), TrackList::Channels(), WaveTrack::ClearAndPaste(), EffectUIServices::DoMessageBox(), EffectTypeGenerate, EffectTypeProcess, EffectTypeTool, TranslatableString::empty(), WaveTrack::EmptyCopy(), EscapeString(), WaveTrackView::Find(), floatSample, format, SpectrogramSettings::Get(), LabelTrack::GetDefaultName(), Track::GetEndTime(), WaveTrack::GetEndTime(), WaveTrack::GetMinMax(), ComponentInterface::GetName(), anonymous_namespace{TimeTrack.cpp}::GetRate(), WaveTrack::GetRate(), WaveTrack::GetRMS(), Track::GetStartTime(), GetType(), SyncLock::Group(), EffectBase::inputTracks(), int16Sample, int24Sample, SyncLock::IsSyncLockSelected(), mCmd, mCompiler, mControls, mCount, mCurBuffer, mCurLen, mCurNumChannels, mCurTrack, mDebug, mDebugOutput, mExternal, mFirstInGroup, min(), mIsPrompt, mIsSal, mMergeClips, mName, mNumSelectedChannels, mOutputTime, mOutputTrack, EffectBase::mOutputTracks, mPerTrackProps, 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(), WaveTrack::SortedClipArray(), SpectrogramSettings::SpectralSelectionEnabled(), StaticGetCallback(), StaticPutCallback(), str, SampleTrack::TimeToLongSamples(), Internat::ToString(), Effect::TrackGroupProgress(), Effect::TrackProgress(), TranslatableString::Translation(), Track::TypeSwitch(), UTF8CTOWX, valueRestorer(), Verbatim(), wxT(), and XO().

Referenced by Process().

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

◆ PutCallback()

int NyquistEffect::PutCallback ( float *  buffer,
int  channel,
int64_t  start,
int64_t  len,
int64_t  totlen 
)
private

Definition at line 2587 of file Nyquist.cpp.

2589{
2590 // Don't let C++ exceptions propagate through the Nyquist library
2591 return GuardedCall<int>( [&] {
2592 if (channel == 0) {
2593 double progress = mScale*((float)(start+len)/totlen);
2594
2595 if (progress > mProgressOut) {
2596 mProgressOut = progress;
2597 }
2598
2600 return -1;
2601 }
2602 }
2603
2604 mOutputTrack[channel]->Append((samplePtr)buffer, floatSample, len);
2605
2606 return 0; // success
2607 }, MakeSimpleGuard( -1 ) ); // translate all exceptions into failure
2608}
SimpleGuard< R > MakeSimpleGuard(R value) noexcept(noexcept(SimpleGuard< R >{ value }))
Convert a value to a handler function returning that value, suitable for GuardedCall<R>
char * samplePtr
Definition: SampleFormat.h:55
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1, sampleFormat effectiveFormat=widestSampleFormat) override
Definition: WaveTrack.cpp:1570

References WaveTrack::Append(), floatSample, MakeSimpleGuard(), mOutputTrack, mProgressIn, mProgressOut, mProgressTot, mScale, and Effect::TotalProgress().

Referenced by StaticPutCallback().

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

◆ RedirectOutput()

void NyquistEffect::RedirectOutput ( )

Definition at line 1851 of file Nyquist.cpp.

1852{
1853 mRedirectOutput = true;
1854}

References mRedirectOutput.

Referenced by NyqBench::OnGo().

Here is the caller graph for this function:

◆ resolveFilePath()

void NyquistEffect::resolveFilePath ( wxString &  path,
FileExtension  extension = {} 
)
staticprivate

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 3312 of file Nyquist.cpp.

3314{
3315#if defined(__WXMSW__)
3316 path.Replace("/", wxFileName::GetPathSeparator());
3317#endif
3318
3319 path.Trim(true).Trim(false);
3320
3321 typedef std::unordered_map<wxString, FilePath> map;
3322 map pathKeys = {
3323 {"*home*", wxGetHomeDir()},
3324 {"~", wxGetHomeDir()},
3325 {"*default*", FileNames::DefaultToDocumentsFolder("").GetPath()},
3326 {"*export*", FileNames::FindDefaultPath(FileNames::Operation::Export)},
3327 {"*save*", FileNames::FindDefaultPath(FileNames::Operation::Save)},
3328 {"*config*", FileNames::DataDir()}
3329 };
3330
3331 int characters = path.Find(wxFileName::GetPathSeparator());
3332 if(characters == wxNOT_FOUND) // Just a path or just a file name
3333 {
3334 if (path.empty())
3335 path = "*default*";
3336
3337 if (pathKeys.find(path) != pathKeys.end())
3338 {
3339 // Keyword found, so assume this is the intended directory.
3340 path = pathKeys[path] + wxFileName::GetPathSeparator();
3341 }
3342 else // Just a file name
3343 {
3344 path = pathKeys["*default*"] + wxFileName::GetPathSeparator() + path;
3345 }
3346 }
3347 else // path + file name
3348 {
3349 wxString firstDir = path.Left(characters);
3350 wxString rest = path.Mid(characters);
3351
3352 if (pathKeys.find(firstDir) != pathKeys.end())
3353 {
3354 path = pathKeys[firstDir] + rest;
3355 }
3356 }
3357
3358 wxFileName fname = path;
3359
3360 // If the directory is invalid, better to leave it as is (invalid) so that
3361 // the user sees the error rather than an unexpected file path.
3362 if (fname.wxFileName::IsOk() && fname.GetFullName().empty())
3363 {
3364 path = fname.GetPathWithSep() + _("untitled");
3365 if (!extension.empty())
3366 path = path + '.' + extension;
3367 }
3368}
FILES_API wxFileNameWrapper DefaultToDocumentsFolder(const wxString &preference)
FILES_API FilePath FindDefaultPath(Operation op)

References _, FileNames::DataDir(), FileNames::DefaultToDocumentsFolder(), and FileNames::FindDefaultPath().

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

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

◆ SaveSettings()

bool NyquistEffect::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

Implements EffectSettingsManager.

Definition at line 372 of file Nyquist.cpp.

374{
375 if (mIsPrompt)
376 {
377 parms.Write(KEY_Command, mInputCmd);
378 parms.Write(KEY_Parameters, mParameters);
379
380 return true;
381 }
382
383 for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
384 {
385 const NyqControl & ctrl = mControls[c];
386 double d = ctrl.val;
387
388 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
389 {
390 d = GetCtrlValue(ctrl.valStr);
391 }
392
393 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
394 ctrl.type == NYQ_CTRL_TIME)
395 {
396 parms.Write(ctrl.var, d);
397 }
398 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
399 {
400 parms.Write(ctrl.var, (int) d);
401 }
402 else if (ctrl.type == NYQ_CTRL_CHOICE)
403 {
404 // untranslated
405 parms.WriteEnum(ctrl.var, (int) d,
406 ctrl.choices.data(), ctrl.choices.size());
407 }
408 else if (ctrl.type == NYQ_CTRL_STRING)
409 {
410 parms.Write(ctrl.var, ctrl.valStr);
411 }
412 else if (ctrl.type == NYQ_CTRL_FILE)
413 {
414 // Convert the given path string to platform-dependent equivalent
415 resolveFilePath(const_cast<wxString&>(ctrl.valStr));
416 parms.Write(ctrl.var, ctrl.valStr);
417 }
418 }
419
420 return true;
421}
#define UNINITIALIZED_CONTROL
Definition: Nyquist.cpp:115
bool WriteEnum(const wxString &key, int value, const EnumValueSymbol choices[], size_t nChoices)

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 ShowHostInterface(), and VisitSettings().

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

◆ SetCommand()

void NyquistEffect::SetCommand ( const wxString &  cmd)

Definition at line 1856 of file Nyquist.cpp.

1857{
1858 mExternal = true;
1859
1860 if (cmd.size()) {
1861 ParseCommand(cmd);
1862 }
1863}

References mExternal, and ParseCommand().

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

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

◆ SetLispVarsFromParameters()

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

Definition at line 496 of file Nyquist.cpp.

497{
498 int badCount = 0;
499 // First pass verifies values
500 for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
501 {
502 NyqControl & ctrl = mControls[c];
503 bool good = false;
504
505 // This GetCtrlValue code is preserved from former code,
506 // but probably is pointless. The value d isn't used later,
507 // and GetCtrlValue does not appear to have important needed
508 // side effects.
509 if (!bTestOnly) {
510 double d = ctrl.val;
511 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
512 {
513 d = GetCtrlValue(ctrl.valStr);
514 }
515 }
516
517 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
518 ctrl.type == NYQ_CTRL_TIME)
519 {
520 double val;
521 good = parms.Read(ctrl.var, &val) &&
522 val >= ctrl.low &&
523 val <= ctrl.high;
524 if (good && !bTestOnly)
525 ctrl.val = val;
526 }
527 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
528 {
529 int val;
530 good = parms.Read(ctrl.var, &val) &&
531 val >= ctrl.low &&
532 val <= ctrl.high;
533 if (good && !bTestOnly)
534 ctrl.val = (double)val;
535 }
536 else if (ctrl.type == NYQ_CTRL_CHOICE)
537 {
538 int val;
539 // untranslated
540 good = parms.ReadEnum(ctrl.var, &val,
541 ctrl.choices.data(), ctrl.choices.size()) &&
542 val != wxNOT_FOUND;
543 if (good && !bTestOnly)
544 ctrl.val = (double)val;
545 }
546 else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
547 {
548 wxString val;
549 good = parms.Read(ctrl.var, &val);
550 if (good && !bTestOnly)
551 ctrl.valStr = val;
552 }
553 else if (ctrl.type == NYQ_CTRL_TEXT)
554 {
555 // This "control" is just fixed text (nothing to save or restore),
556 // Does not count for good/bad counting.
557 good = true;
558 }
559 badCount += !good ? 1 : 0;
560 }
561 return badCount;
562}
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:

◆ ShowHostInterface()

int NyquistEffect::ShowHostInterface ( EffectPlugin plugin,
wxWindow &  parent,
const EffectDialogFactory factory,
std::shared_ptr< EffectInstance > &  pInstance,
EffectSettingsAccess access,
bool  forceModal = false 
)
overridevirtual

The only non-const member function, it usually applies factory to plugin and self and given access

But there are a few unusual overrides for historical reasons that may ignore the factory.

Parameters
pInstancemay be passed to factory, and is only guaranteed to have lifetime suitable for a modal dialog, unless the dialog stores a copy of pInstance
accessis only guaranteed to have lifetime suitable for a modal dialog, unless the dialog stores access.shared_from_this()
Returns
0 if destructive effect processing should not proceed (and there may be a non-modal dialog still opened); otherwise, modal dialog return code

Reimplemented from EffectUIServices.

Definition at line 1057 of file Nyquist.cpp.

1061{
1062 int res = wxID_APPLY;
1064 // Show the normal (prompt or effect) interface
1066 parent, factory, pInstance, access, forceModal);
1067 }
1068
1069
1070 // Remember if the user clicked debug
1071 mDebug = (res == eDebugID);
1072
1073 // We're done if the user clicked "Close", we are not the Nyquist Prompt,
1074 // or the program currently loaded into the prompt doesn't have a UI.
1075 if (!res || !mIsPrompt || mControls.size() == 0 || !pInstance)
1076 return res;
1077
1078 // Nyquist prompt was OK, but gave us some magic ;control comments to
1079 // reinterpret into a second dialog
1080
1082 effect.SetCommand(mInputCmd);
1083 Finally Do{[&]{
1084 // A second dialog will use effect as a pushed event handler.
1085 // wxWidgets delays window destruction until idle time.
1086 // Yield to destroy the dialog while effect is still in scope.
1088 }};
1089
1090 // Must give effect its own settings to interpret, not those in access
1091 // Let's also give it its own instance
1092 auto newSettings = effect.MakeSettings();
1093 auto pNewInstance = effect.MakeInstance();
1094 auto newAccess = std::make_shared<SimpleEffectSettingsAccess>(newSettings);
1095
1096 if (IsBatchProcessing()) {
1097 effect.SetBatchProcessing();
1098
1101 effect.LoadSettings(cp, newSettings);
1102
1103 // Show the normal (prompt or effect) interface
1104 // Don't pass this as first argument, pass the worker to itself
1105 res = effect.ShowHostInterface(effect,
1106 parent, factory, pNewInstance, *newAccess, forceModal);
1107 if (res) {
1109 effect.SaveSettings(newSettings, cp);
1111 }
1112 }
1113 else {
1114 if (!factory)
1115 return 0;
1116 // Don't pass this as first argument, pass the worker to itself
1117 res = effect.ShowHostInterface(effect,
1118 parent, factory, pNewInstance, *newAccess, false );
1119 if (!res)
1120 return 0;
1121
1122 // Wrap the new settings in the old settings
1124 auto &nyquistSettings = GetSettings(settings);
1125 nyquistSettings.proxySettings = std::move(newSettings);
1126 nyquistSettings.proxyDebug = this->mDebug;
1127 nyquistSettings.controls = move(effect.mControls);
1128 return nullptr;
1129 });
1130 }
1131 if (!pNewInstance)
1132 // Propagate the failure from nested ShowHostInterface
1133 pInstance.reset();
1134 return res;
1135}
@ eDebugID
Definition: ShuttleGui.h:613
bool GetParameters(wxString &parms)
unsigned TestUIFlags(unsigned mask)
Definition: Effect.cpp:298
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
virtual int ShowHostInterface(EffectPlugin &plugin, wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false)
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.
Definition: BasicUI.cpp:219
static RegisteredToolbarFactory factory
Externalized state of a plug-in.
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
Definition: MemoryX.h:173

References eDebugID, cloud::factory, CommandParameters::GetParameters(), EffectWithSettings< NyquistSettings, StatefulEffect >::GetSettings(), Effect::IsBatchProcessing(), EffectManager::kRepeatNyquistPrompt, LoadSettings(), StatefulEffect::MakeInstance(), EffectWithSettings< Settings, Base >::MakeSettings(), mControls, mDebug, mInputCmd, mIsPrompt, EffectSettingsAccess::ModifySettings(), mParameters, NYQUIST_WORKER_ID, SaveSettings(), Effect::SetBatchProcessing(), SetCommand(), CommandParameters::SetParameters(), settings(), EffectUIServices::ShowHostInterface(), ShowHostInterface(), Effect::TestUIFlags(), and BasicUI::Yield().

Referenced by ShowHostInterface().

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

◆ StaticGetCallback()

int NyquistEffect::StaticGetCallback ( float *  buffer,
int  channel,
int64_t  start,
int64_t  len,
int64_t  totlen,
void *  userdata 
)
staticprivate

Definition at line 2512 of file Nyquist.cpp.

2515{
2516 NyquistEffect *This = (NyquistEffect *)userdata;
2517 return This->GetCallback(buffer, channel, start, len, totlen);
2518}
int GetCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
Definition: Nyquist.cpp:2520

References GetCallback().

Referenced by ProcessOne().

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

◆ StaticOSCallback()

void NyquistEffect::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2626 of file Nyquist.cpp.

2627{
2628 ((NyquistEffect *)This)->OSCallback();
2629}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2610 of file Nyquist.cpp.

2611{
2612 ((NyquistEffect *)This)->OutputCallback(c);
2613}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticPutCallback()

int NyquistEffect::StaticPutCallback ( float *  buffer,
int  channel,
int64_t  start,
int64_t  len,
int64_t  totlen,
void *  userdata 
)
staticprivate

Definition at line 2579 of file Nyquist.cpp.

2582{
2583 NyquistEffect *This = (NyquistEffect *)userdata;
2584 return This->PutCallback(buffer, channel, start, len, totlen);
2585}
int PutCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
Definition: Nyquist.cpp:2587

References PutCallback().

Referenced by ProcessOne().

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

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1875 of file Nyquist.cpp.

1876{
1877 mStop = true;
1878}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3382 of file Nyquist.cpp.

3383{
3384 int seconds = static_cast<int>(t);
3385 int hh = seconds / 3600;
3386 int mm = seconds % 3600;
3387 mm = mm / 60;
3388 return wxString::Format("%d:%d:%.3f", hh, mm, t - (hh * 3600 + mm * 60));
3389}

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2740 of file Nyquist.cpp.

2741{
2742 if (mControls.size() == 0)
2743 {
2744 return true;
2745 }
2746
2747 for (unsigned int i = 0; i < mControls.size(); i++)
2748 {
2749 NyqControl *ctrl = &mControls[i];
2750
2751 if (ctrl->type == NYQ_CTRL_STRING || ctrl->type == NYQ_CTRL_TEXT)
2752 {
2753 continue;
2754 }
2755
2756 if (ctrl->val == UNINITIALIZED_CONTROL)
2757 {
2758 ctrl->val = GetCtrlValue(ctrl->valStr);
2759 }
2760
2761 if (ctrl->type == NYQ_CTRL_CHOICE)
2762 {
2763 continue;
2764 }
2765
2766 if (ctrl->type == NYQ_CTRL_FILE)
2767 {
2768 resolveFilePath(ctrl->valStr);
2769
2770 wxString path;
2771 if (ctrl->valStr.StartsWith("\"", &path))
2772 {
2773 // Validate if a list of quoted paths.
2774 if (path.EndsWith("\"", &path))
2775 {
2776 path.Replace("\"\"", "\"");
2777 wxStringTokenizer tokenizer(path, "\"");
2778 while (tokenizer.HasMoreTokens())
2779 {
2780 wxString token = tokenizer.GetNextToken();
2781 if(!validatePath(token))
2782 {
2783 const auto message =
2784 XO("\"%s\" is not a valid file path.").Format( token );
2786 message,
2787 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2788 XO("Error") );
2789 return false;
2790 }
2791 }
2792 continue;
2793 }
2794 else
2795 {
2796 const auto message =
2797 /* i18n-hint: Warning that there is one quotation mark rather than a pair.*/
2798 XO("Mismatched quotes in\n%s").Format( ctrl->valStr );
2800 message,
2801 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2802 XO("Error") );
2803 return false;
2804 }
2805 }
2806 // Validate a single path.
2807 else if (validatePath(ctrl->valStr))
2808 {
2809 continue;
2810 }
2811
2812 // Validation failed
2813 const auto message =
2814 XO("\"%s\" is not a valid file path.").Format( ctrl->valStr );
2816 message,
2817 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2818 XO("Error") );
2819 return false;
2820 }
2821
2822 if (ctrl->type == NYQ_CTRL_TIME)
2823 {
2824 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
2825 ctrl->val = n->GetValue();
2826 }
2827
2828 if (ctrl->type == NYQ_CTRL_INT_TEXT && ctrl->lowStr.IsSameAs(wxT("nil"), false)) {
2829 ctrl->low = INT_MIN;
2830 }
2831 else if ((ctrl->type == NYQ_CTRL_FLOAT_TEXT || ctrl->type == NYQ_CTRL_TIME) &&
2832 ctrl->lowStr.IsSameAs(wxT("nil"), false))
2833 {
2834 ctrl->low = -(FLT_MAX);
2835 }
2836 else
2837 {
2838 ctrl->low = GetCtrlValue(ctrl->lowStr);
2839 }
2840
2841 if (ctrl->type == NYQ_CTRL_INT_TEXT && ctrl->highStr.IsSameAs(wxT("nil"), false)) {
2842 ctrl->high = INT_MAX;
2843 }
2844 else if ((ctrl->type == NYQ_CTRL_FLOAT_TEXT || ctrl->type == NYQ_CTRL_TIME) &&
2845 ctrl->highStr.IsSameAs(wxT("nil"), false))
2846 {
2847 ctrl->high = FLT_MAX;
2848 }
2849 else
2850 {
2851 ctrl->high = GetCtrlValue(ctrl->highStr);
2852 }
2853
2854 if (ctrl->high < ctrl->low)
2855 {
2856 ctrl->high = ctrl->low + 1;
2857 }
2858
2859 if (ctrl->val < ctrl->low)
2860 {
2861 ctrl->val = ctrl->low;
2862 }
2863
2864 if (ctrl->val > ctrl->high)
2865 {
2866 ctrl->val = ctrl->high;
2867 }
2868
2869 ctrl->ticks = 1000;
2870 if (ctrl->type == NYQ_CTRL_INT &&
2871 (ctrl->high - ctrl->low < ctrl->ticks))
2872 {
2873 ctrl->ticks = (int)(ctrl->high - ctrl->low);
2874 }
2875 }
2876
2877 return true;
2878}
bool validatePath(wxString path)
Definition: Nyquist.cpp:3371

References EffectUIServices::DoMessageBox(), GetCtrlValue(), NumericConverter::GetValue(), NyqControl::high, NyqControl::highStr, ID_Time, NyqControl::low, NyqControl::lowStr, mControls, mUIParent, NYQ_CTRL_CHOICE, NYQ_CTRL_FILE, NYQ_CTRL_FLOAT_TEXT, NYQ_CTRL_INT, NYQ_CTRL_INT_TEXT, NYQ_CTRL_STRING, NYQ_CTRL_TEXT, NYQ_CTRL_TIME, resolveFilePath(), NyqControl::ticks, NyqControl::type, UNINITIALIZED_CONTROL, NyqControl::val, validatePath(), NyqControl::valStr, wxT(), and XO().

Referenced by TransferDataFromWindow().

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

◆ TransferDataFromPromptWindow()

bool NyquistEffect::TransferDataFromPromptWindow ( )
private

Definition at line 2722 of file Nyquist.cpp.

2723{
2724 mInputCmd = mCommandText->GetValue();
2725
2726 // Un-correct smart quoting, bothersomely applied in wxTextCtrl by
2727 // the native widget of MacOS 10.9 SDK
2728 const wxString left = wxT("\u201c"), right = wxT("\u201d"), dumb = '"';
2729 mInputCmd.Replace(left, dumb, true);
2730 mInputCmd.Replace(right, dumb, true);
2731
2732 const wxString leftSingle = wxT("\u2018"), rightSingle = wxT("\u2019"),
2733 dumbSingle = '\'';
2734 mInputCmd.Replace(leftSingle, dumbSingle, true);
2735 mInputCmd.Replace(rightSingle, dumbSingle, true);
2736
2737 return ParseCommand(mInputCmd);
2738}

References mCommandText, mInputCmd, ParseCommand(), and wxT().

Referenced by TransferDataFromWindow().

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

◆ TransferDataFromWindow()

bool NyquistEffect::TransferDataFromWindow ( EffectSettings settings)
overridevirtual

Update the given settings from controls; default does nothing, returns true

Reimplemented from StatefulEffectUIServices.

Definition at line 1176 of file Nyquist.cpp.

1177{
1178 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
1179 {
1180 return false;
1181 }
1182
1183 if (mIsPrompt)
1184 {
1186 }
1188}
bool TransferDataFromPromptWindow()
Definition: Nyquist.cpp:2722
bool TransferDataFromEffectWindow()
Definition: Nyquist.cpp:2740

References mIsPrompt, mUIParent, TransferDataFromEffectWindow(), and TransferDataFromPromptWindow().

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2685 of file Nyquist.cpp.

2686{
2687 for (size_t i = 0, cnt = mControls.size(); i < cnt; i++)
2688 {
2689 NyqControl & ctrl = mControls[i];
2690
2691 if (ctrl.type == NYQ_CTRL_CHOICE)
2692 {
2693 const auto count = ctrl.choices.size();
2694
2695 int val = (int)ctrl.val;
2696 if (val < 0 || val >= (int)count)
2697 {
2698 val = 0;
2699 }
2700
2701 wxChoice *c = (wxChoice *) mUIParent->FindWindow(ID_Choice + i);
2702 c->SetSelection(val);
2703 }
2704 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_FLOAT)
2705 {
2706 // wxTextCtrls are handled by the validators
2707 double range = ctrl.high - ctrl.low;
2708 int val = (int)(0.5 + ctrl.ticks * (ctrl.val - ctrl.low) / range);
2709 wxSlider *s = (wxSlider *) mUIParent->FindWindow(ID_Slider + i);
2710 s->SetValue(val);
2711 }
2712 else if (ctrl.type == NYQ_CTRL_TIME)
2713 {
2714 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
2715 n->SetValue(ctrl.val);
2716 }
2717 }
2718
2719 return true;
2720}

References NyqControl::choices, NyqControl::high, ID_Choice, ID_Slider, ID_Time, NyqControl::low, mControls, mUIParent, NYQ_CTRL_CHOICE, NYQ_CTRL_FLOAT, NYQ_CTRL_INT, NYQ_CTRL_TIME, NumericTextCtrl::SetValue(), NyqControl::ticks, NyqControl::type, and NyqControl::val.

Referenced by TransferDataToWindow().

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

◆ TransferDataToPromptWindow()

bool NyquistEffect::TransferDataToPromptWindow ( )
private

Definition at line 2678 of file Nyquist.cpp.

2679{
2680 mCommandText->ChangeValue(mInputCmd);
2681
2682 return true;
2683}

References mCommandText, and mInputCmd.

Referenced by TransferDataToWindow().

Here is the caller graph for this function:

◆ TransferDataToWindow()

bool NyquistEffect::TransferDataToWindow ( const EffectSettings settings)
overridevirtual

Update controls for the settings; default does nothing, returns true

Reimplemented from StatefulEffectUIServices.

Definition at line 1154 of file Nyquist.cpp.

1155{
1156 mUIParent->TransferDataToWindow();
1157
1158 bool success;
1159 if (mIsPrompt)
1160 {
1161 success = TransferDataToPromptWindow();
1162 }
1163 else
1164 {
1165 success = TransferDataToEffectWindow();
1166 }
1167
1168 if (success)
1169 {
1171 }
1172
1173 return success;
1174}
static bool EnablePreview(wxWindow *parent, bool enable=true)
bool TransferDataToPromptWindow()
Definition: Nyquist.cpp:2678
bool TransferDataToEffectWindow()
Definition: Nyquist.cpp:2685

References EffectEditor::EnablePreview(), mEnablePreview, mIsPrompt, mUIParent, TransferDataToEffectWindow(), and TransferDataToPromptWindow().

Here is the call graph for this function:

◆ UnQuote()

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

Definition at line 1921 of file Nyquist.cpp.

1923{
1924 return UnQuoteMsgid( s, allowParens, pExtraString ).Translation();
1925}

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 NyquistEffect::UnQuoteMsgid ( const wxString &  s,
bool  allowParens = true,
wxString *  pExtraString = nullptr 
)
staticprivate

Definition at line 1880 of file Nyquist.cpp.

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

References NyquistEffect::Tokenizer::Tokenize(), NyquistEffect::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 NyquistEffect::validatePath ( wxString  path)
private

Definition at line 3371 of file Nyquist.cpp.

3372{
3373 wxFileName fname = path;
3374 wxString dir = fname.GetPath();
3375
3376 return (fname.wxFileName::IsOk() &&
3377 wxFileName::DirExists(dir) &&
3378 !fname.GetFullName().empty());
3379}

Referenced by TransferDataFromEffectWindow().

Here is the caller graph for this function:

◆ VisitSettings() [1/2]

bool NyquistEffect::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 EffectSettingsManager.

Definition at line 316 of file Nyquist.cpp.

318{
319 // For now we assume Nyquist can do get and set better than VisitSettings can,
320 // And so we ONLY use it for getting the signature.
321 if (auto pGa = dynamic_cast<ShuttleGetAutomation*>(&visitor)) {
322 SaveSettings(settings, *pGa->mpEap);
323 return true;
324 }
325 else if (auto pSd = dynamic_cast<ShuttleGetDefinition*>(&visitor);
326 !pSd)
327 // must be the NullShuttle
328 return true;
329
330 // Get the "definition," only for the help or info commands
331 if (mExternal)
332 return true;
333
334 if (mIsPrompt) {
335 visitor.Define( mInputCmd, KEY_Command, wxString{} );
336 visitor.Define( mParameters, KEY_Parameters, wxString{} );
337 return true;
338 }
339
340 for (const auto &ctrl : mControls) {
341 double d = ctrl.val;
342
343 if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
344 d = GetCtrlValue(ctrl.valStr);
345
346 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
347 ctrl.type == NYQ_CTRL_TIME)
348 visitor.Define( d, static_cast<const wxChar*>( ctrl.var.c_str() ),
349 (double)0.0, ctrl.low, ctrl.high, 1.0);
350 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT) {
351 int x = d;
352 visitor.Define( x, static_cast<const wxChar*>( ctrl.var.c_str() ), 0,
353 static_cast<int>(ctrl.low), static_cast<int>(ctrl.high), 1);
354 //parms.Write(ctrl.var, (int) d);
355 }
356 else if (ctrl.type == NYQ_CTRL_CHOICE) {
357 // untranslated
358 int x = d;
359 //parms.WriteEnum(ctrl.var, (int) d, choices);
360 visitor.DefineEnum( x, static_cast<const wxChar*>( ctrl.var.c_str() ),
361 0, ctrl.choices.data(), ctrl.choices.size() );
362 }
363 else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE) {
364 visitor.Define( ctrl.valStr, ctrl.var,
365 wxString{}, ctrl.lowStr, ctrl.highStr );
366 //parms.Write(ctrl.var, ctrl.valStr);
367 }
368 }
369 return true;
370}
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
Definition: Nyquist.cpp:372
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.
SettingsVisitor that retrieves a JSON format definition of a command's parameters.

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 NyquistEffect::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 EffectSettingsManager.

Definition at line 308 of file Nyquist.cpp.

310{
311 if (auto pSa = dynamic_cast<ShuttleSetAutomation*>(&visitor))
312 LoadSettings(*pSa->mpEap, settings);
313 return true;
314}
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
Definition: Nyquist.cpp:423
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 318 of file Nyquist.h.

Member Data Documentation

◆ mAction

TranslatableString NyquistEffect::mAction
private

Definition at line 255 of file Nyquist.h.

Referenced by Parse().

◆ mAuthor

TranslatableString NyquistEffect::mAuthor
private

Definition at line 257 of file Nyquist.h.

Referenced by GetVendor(), and Parse().

◆ mBreak

bool NyquistEffect::mBreak
private

Definition at line 233 of file Nyquist.h.

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

◆ mCategories

wxArrayString NyquistEffect::mCategories
private

Definition at line 304 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mCmd

wxString NyquistEffect::mCmd
private

Definition at line 252 of file Nyquist.h.

Referenced by ParseProgram(), and ProcessOne().

◆ mCommandText

wxTextCtrl* NyquistEffect::mCommandText
private

◆ mCompiler

bool NyquistEffect::mCompiler
private

Definition at line 237 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mCont

bool NyquistEffect::mCont
private

Definition at line 234 of file Nyquist.h.

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

◆ mControls

std::vector<NyqControl> NyquistEffect::mControls
private

◆ mCopyright

TranslatableString NyquistEffect::mCopyright
private

Definition at line 262 of file Nyquist.h.

Referenced by GetDescription(), and Parse().

◆ mCount

unsigned NyquistEffect::mCount
private

Definition at line 290 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mCurBuffer

Buffer NyquistEffect::mCurBuffer[2]
private

Definition at line 298 of file Nyquist.h.

Referenced by GetCallback(), and ProcessOne().

◆ mCurBufferLen

size_t NyquistEffect::mCurBufferLen[2]
private

Definition at line 300 of file Nyquist.h.

Referenced by GetCallback().

◆ mCurBufferStart

sampleCount NyquistEffect::mCurBufferStart[2]
private

Definition at line 299 of file Nyquist.h.

Referenced by GetCallback().

◆ mCurLen

sampleCount NyquistEffect::mCurLen
private

Definition at line 285 of file Nyquist.h.

Referenced by GetCallback(), Process(), and ProcessOne().

◆ mCurNumChannels

unsigned NyquistEffect::mCurNumChannels
private

Definition at line 282 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mCurStart

sampleCount NyquistEffect::mCurStart[2]
private

Definition at line 284 of file Nyquist.h.

Referenced by GetCallback(), and Process().

◆ mCurTrack

WaveTrack* NyquistEffect::mCurTrack[2]
private

Definition at line 283 of file Nyquist.h.

Referenced by GetCallback(), Process(), and ProcessOne().

◆ mDebug

bool NyquistEffect::mDebug
private

Definition at line 273 of file Nyquist.h.

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

◆ mDebugButton

bool NyquistEffect::mDebugButton
private

Definition at line 271 of file Nyquist.h.

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

◆ mDebugOutput

TranslatableString NyquistEffect::mDebugOutput
private

Definition at line 277 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mDebugOutputStr

wxString NyquistEffect::mDebugOutputStr
private

Definition at line 276 of file Nyquist.h.

Referenced by OutputCallback(), and Process().

◆ mEnablePreview

bool NyquistEffect::mEnablePreview
private

Definition at line 270 of file Nyquist.h.

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

◆ mExternal

bool NyquistEffect::mExternal
private

Definition at line 240 of file Nyquist.h.

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

◆ mFileModified

wxDateTime NyquistEffect::mFileModified
private

When the script was last modified on disk.

Definition at line 230 of file Nyquist.h.

◆ mFileName

wxFileName NyquistEffect::mFileName
private

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

Definition at line 229 of file Nyquist.h.

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

◆ mFirstInGroup

bool NyquistEffect::mFirstInGroup
private

Definition at line 288 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mFoundType

bool NyquistEffect::mFoundType
private

Definition at line 236 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mHelpFile

wxString NyquistEffect::mHelpFile
private

Definition at line 264 of file Nyquist.h.

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

◆ mHelpFileExists

bool NyquistEffect::mHelpFileExists
private

Definition at line 265 of file Nyquist.h.

Referenced by ParseProgram(), and Process().

◆ mHelpPage

FilePath NyquistEffect::mHelpPage
private

Definition at line 266 of file Nyquist.h.

Referenced by HelpPage(), and ParseProgram().

◆ mInfo

TranslatableString NyquistEffect::mInfo
private

Definition at line 256 of file Nyquist.h.

Referenced by Parse().

◆ mInitError

TranslatableString NyquistEffect::mInitError
private

Definition at line 249 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mInputCmd

wxString NyquistEffect::mInputCmd
private

◆ mIsPrompt

const bool NyquistEffect::mIsPrompt
private

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 247 of file Nyquist.h.

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

◆ mIsSal

bool NyquistEffect::mIsSal
private

Definition at line 239 of file Nyquist.h.

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

◆ mIsSpectral

bool NyquistEffect::mIsSpectral
private

Definition at line 241 of file Nyquist.h.

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

◆ mIsTool

bool NyquistEffect::mIsTool
private

Definition at line 242 of file Nyquist.h.

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

◆ mManPage

wxString NyquistEffect::mManPage
private

Definition at line 263 of file Nyquist.h.

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

◆ mMaxLen

sampleCount NyquistEffect::mMaxLen
private

Definition at line 286 of file Nyquist.h.

Referenced by Parse(), and Process().

◆ mMergeClips

int NyquistEffect::mMergeClips
private

Definition at line 310 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mName

TranslatableString NyquistEffect::mName
private

Name of the Effect (untranslated)

Definition at line 253 of file Nyquist.h.

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

◆ mNumSelectedChannels

unsigned NyquistEffect::mNumSelectedChannels
private

Definition at line 291 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mOK

bool NyquistEffect::mOK
private

Definition at line 248 of file Nyquist.h.

Referenced by IsOk(), and Parse().

◆ mOutputTime

double NyquistEffect::mOutputTime
private

Definition at line 289 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mOutputTrack

WaveTrack* NyquistEffect::mOutputTrack[2]
private

Definition at line 302 of file Nyquist.h.

Referenced by ProcessOne(), and PutCallback().

◆ mParameters

wxString NyquistEffect::mParameters
private

Definition at line 251 of file Nyquist.h.

Referenced by DoLoadSettings(),