Audacity 3.2.0
Classes | Public Member Functions | 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  NyxContext
 
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 (EffectBase &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
 
EffectFamilySymbol GetFamily () const override
 Report identifier and user-visible name of the effect protocol. More...
 
bool IsInteractive () const override
 Whether the effect needs a dialog for entry of settings. More...
 
bool IsDefault () const override
 Whether the effect sorts "above the line" in the menus. More...
 
RealtimeSince RealtimeSupport () const override
 Since which version of Audacity has the effect supported realtime? More...
 
bool SupportsAutomation () const override
 Whether the effect has any automatable controls. More...
 
bool SaveSettings (const EffectSettings &settings, CommandParameters &parms) const override
 Store settings as keys and values. More...
 
bool LoadSettings (const CommandParameters &parms, EffectSettings &settings) const override
 Restore settings from keys and values. More...
 
OptionalMessage LoadUserPreset (const RegistryPath &name, EffectSettings &settings) const override
 
bool SaveUserPreset (const RegistryPath &name, const EffectSettings &settings) const override
 Save settings in the configuration file as a user-named preset. More...
 
RegistryPaths GetFactoryPresets () const override
 Report names of factory presets. More...
 
OptionalMessage LoadFactoryPreset (int id, EffectSettings &settings) const override
 
OptionalMessage LoadFactoryDefaults (EffectSettings &settings) const override
 
virtual const EffectParameterMethodsParameters () const
 
bool CanExportPresets () const override
 Whether the effect supports export of presets to files, and importing too. More...
 
bool HasOptions () const override
 
const EffectSettingsManagerGetDefinition () const override
 
virtual NumericFormatID GetSelectionFormat ()
 
bool SaveSettingsAsString (const EffectSettings &settings, wxString &parms) const override
 
OptionalMessage LoadSettingsFromString (const wxString &parms, EffectSettings &settings) const override
 
bool IsBatchProcessing () const override
 
void SetBatchProcessing () override
 
void UnsetBatchProcessing () override
 
unsigned TestUIFlags (unsigned mask)
 
bool Delegate (Effect &delegate, EffectSettings &settings, InstanceFinder finder={})
 Re-invoke DoEffect on another Effect object that implements the work. More...
 
- Public Member Functions inherited from EffectBase
 EffectBase ()
 
 ~EffectBase () override
 
bool IsLinearEffect () const
 
bool PreviewsFullSelection () const
 
void SetTracks (TrackList *pTracks)
 
double GetDefaultDuration ()
 
virtual std::any BeginPreview (const EffectSettings &settings)
 Called when Preview() starts, to allow temporary effect state changes. More...
 
bool DoEffect (EffectSettings &settings, const InstanceFinder &finder, double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, const EffectSettingsAccessPtr &pAccess) override
 
virtual double CalcPreviewInputLength (const EffectSettings &settings, double previewLength) const =0
 
void CountWaveTracks ()
 
- Public Member Functions inherited from EffectPlugin
EffectPluginoperator= (EffectPlugin &)=delete
 
virtual ~EffectPlugin ()
 
virtual bool HasOptions () const =0
 
virtual bool CanExportPresets () const =0
 Whether the effect supports export of presets to files, and importing too. More...
 
virtual const EffectSettingsManagerGetDefinition () const =0
 
virtual bool SaveSettingsAsString (const EffectSettings &settings, wxString &parms) const =0
 
virtual OptionalMessage LoadSettingsFromString (const wxString &parms, EffectSettings &settings) const =0
 
virtual bool IsBatchProcessing () const =0
 
virtual void SetBatchProcessing ()=0
 
virtual void UnsetBatchProcessing ()=0
 
virtual bool DoEffect (EffectSettings &settings, const InstanceFinder &finder, double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, unsigned flags, const EffectSettingsAccessPtr &pAccess=nullptr)=0
 
- Public Member Functions inherited from EffectInstanceFactory
virtual ~EffectInstanceFactory ()
 
virtual std::shared_ptr< EffectInstanceMakeInstance () const =0
 Make an object maintaining short-term state of an Effect. More...
 
- Public Member Functions inherited from EffectSettingsManager
virtual ~EffectSettingsManager ()
 
virtual bool VisitSettings (SettingsVisitor &visitor, EffectSettings &settings)
 
virtual bool VisitSettings (ConstSettingsVisitor &visitor, const EffectSettings &settings) const
 
virtual std::unique_ptr< EffectOutputsMakeOutputs () const
 Produce an object to hold values to send to effect output meters. More...
 
- Public Member Functions inherited from EffectDefinitionInterface
virtual ~EffectDefinitionInterface ()
 
virtual EffectType GetType () const =0
 Type determines how it behaves. More...
 
virtual EffectType GetClassification () const
 Determines which menu it appears in; default same as GetType(). More...
 
virtual EffectFamilySymbol GetFamily () const =0
 Report identifier and user-visible name of the effect protocol. More...
 
virtual bool IsInteractive () const =0
 Whether the effect needs a dialog for entry of settings. More...
 
virtual bool IsDefault () const =0
 Whether the effect sorts "above the line" in the menus. More...
 
virtual RealtimeSince RealtimeSupport () const =0
 Since which version of Audacity has the effect supported realtime? More...
 
bool SupportsRealtime () const
 
virtual bool SupportsAutomation () const =0
 Whether the effect has any automatable controls. More...
 
virtual bool EnablesDebug () const
 Whether the effect dialog should have a Debug button; default, always false. More...
 
virtual ManualPageID ManualPage () const
 Name of a page in the Audacity alpha manual, default is empty. More...
 
virtual FilePath HelpPage () const
 Fully qualified local help file name, default is empty. More...
 
virtual bool IsHiddenFromMenus () const
 Default is false. More...
 
- Public Member Functions inherited from ComponentInterface
virtual ~ComponentInterface ()
 
virtual PluginPath GetPath () const =0
 
virtual ComponentInterfaceSymbol GetSymbol () const =0
 
virtual VendorSymbol GetVendor () const =0
 
virtual wxString GetVersion () const =0
 
virtual TranslatableString GetDescription () const =0
 
TranslatableString GetName () const
 
- Public 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 (EffectBase &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 Member Functions

bool ProcessOne (NyxContext &nyxContext, EffectOutputTracks *pOutputs)
 
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)
 
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 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
 
sampleCount mMaxLen
 
int mTrackIndex
 
bool mFirstInGroup
 
double mOutputTime
 
unsigned mCount
 
unsigned mNumSelectedChannels
 
wxArrayString mCategories
 
wxString mProps
 
wxString mPerTrackProps
 
bool mRestoreSplits
 
int mMergeClips
 
wxTextCtrl * mCommandText
 

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 Public Member Functions inherited from EffectBase
static std::optional< InstancePointerFindInstance (EffectPlugin &plugin)
 
static InstanceFinder DefaultInstanceFinder (EffectPlugin &plugin)
 
- Static Public Member Functions inherited from EffectDefinitionInterface
static Identifier GetSquashedName (const Identifier &ident)
 A utility that strips spaces and CamelCases a name. More...
 
- Static Public 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
std::shared_ptr< TrackListmTracks {}
 
int mNumTracks {}
 
BasicUI::ProgressDialogmProgress {}
 
double mProjectRate {}
 
WaveTrackFactorymFactory {}
 
double mT0 {}
 
double mT1 {}
 
bool mIsPreview { false }
 
- 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, sampleCount *start, sampleCount *len)
 
- Protected Member Functions inherited from EffectBase
virtual bool CheckWhetherSkipEffect (const EffectSettings &settings) const =0
 After Init(), tell whether Process() should be skipped. More...
 
void SetLinearEffectFlag (bool linearEffectFlag)
 
void SetPreviewFullSelectionFlag (bool previewDurationFlag)
 
bool IsPreviewing () const
 
const TrackListinputTracks () const
 
const AudacityProjectFindProject () const
 
- Protected Attributes inherited from EffectBase
double mF0 {}
 
double mF1 {}
 
wxArrayString mPresetNames
 
unsigned mUIFlags { 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 77 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 202 of file Nyquist.cpp.

203{
204}

Member Function Documentation

◆ Break()

void NyquistEffect::Break ( )

Definition at line 1918 of file Nyquist.cpp.

1919{
1920 mBreak = true;
1921}
bool mBreak
Definition: Nyquist.h:228

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2953 of file Nyquist.cpp.

2954{
2955 wxScrolledWindow *scroller = S.Style(wxVSCROLL | wxTAB_TRAVERSAL)
2956 .StartScroller(2);
2957 {
2958 S.StartMultiColumn(4);
2959 {
2960 for (size_t i = 0; i < mControls.size(); i++)
2961 {
2962 NyqControl & ctrl = mControls[i];
2963
2964 if (ctrl.type == NYQ_CTRL_TEXT)
2965 {
2966 S.EndMultiColumn();
2967 S.StartHorizontalLay(wxALIGN_LEFT, 0);
2968 {
2969 S.AddSpace(0, 10);
2970 S.AddFixedText( Verbatim( ctrl.label ), false );
2971 }
2972 S.EndHorizontalLay();
2973 S.StartMultiColumn(4);
2974 }
2975 else
2976 {
2977 auto prompt = XXO("%s:").Format( ctrl.name );
2978 S.AddPrompt( prompt );
2979
2980 if (ctrl.type == NYQ_CTRL_STRING)
2981 {
2982 S.AddSpace(10, 10);
2983
2984 auto item = S.Id(ID_Text + i)
2985 .Validator<wxGenericValidator>(&ctrl.valStr)
2986 .Name( prompt )
2987 .AddTextBox( {}, wxT(""), 50);
2988 }
2989 else if (ctrl.type == NYQ_CTRL_CHOICE)
2990 {
2991 S.AddSpace(10, 10);
2992
2993 S.Id(ID_Choice + i).AddChoice( {},
2994 Msgids( ctrl.choices.data(), ctrl.choices.size() ) );
2995 }
2996 else if (ctrl.type == NYQ_CTRL_TIME)
2997 {
2998 S.AddSpace(10, 10);
2999
3000 const auto options = NumericTextCtrl::Options{}
3001 .AutoPos(true)
3002 .MenuEnabled(true)
3003 .ReadOnly(false);
3004
3005 NumericTextCtrl *time = safenew
3007 S.GetParent(), (ID_Time + i),
3010 ctrl.val,
3011 options);
3012 S
3013 .Name( prompt )
3014 .Position(wxALIGN_LEFT | wxALL)
3015 .AddWindow(time);
3016 }
3017 else if (ctrl.type == NYQ_CTRL_FILE)
3018 {
3019 S.AddSpace(10, 10);
3020
3021 // Get default file extension if specified in wildcards
3022 FileExtension defaultExtension;
3023 if (!ctrl.fileTypes.empty()) {
3024 const auto &type = ctrl.fileTypes[0];
3025 if ( !type.extensions.empty() )
3026 defaultExtension = type.extensions[0];
3027 }
3028 resolveFilePath(ctrl.valStr, defaultExtension);
3029
3030 wxTextCtrl *item = S.Id(ID_Text+i)
3031 .Name( prompt )
3032 .AddTextBox( {}, wxT(""), 40);
3033 item->SetValidator(wxGenericValidator(&ctrl.valStr));
3034
3035 if (ctrl.label.empty())
3036 // We'd expect wxFileSelectorPromptStr to already be translated, but apparently not.
3037 ctrl.label = wxGetTranslation( wxFileSelectorPromptStr );
3038 S.Id(ID_FILE + i).AddButton(
3039 Verbatim(ctrl.label), wxALIGN_LEFT);
3040 }
3041 else
3042 {
3043 // Integer or Real
3044 if (ctrl.type == NYQ_CTRL_INT_TEXT || ctrl.type == NYQ_CTRL_FLOAT_TEXT)
3045 {
3046 S.AddSpace(10, 10);
3047 }
3048
3049 S.Id(ID_Text+i);
3050 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT)
3051 {
3052 double range = ctrl.high - ctrl.low;
3053 S.Validator<FloatingPointValidator<double>>(
3054 // > 12 decimal places can cause rounding errors in display.
3055 12, &ctrl.val,
3056 // Set number of decimal places
3057 (range < 10
3058 ? NumValidatorStyle::THREE_TRAILING_ZEROES
3059 : range < 100
3060 ? NumValidatorStyle::TWO_TRAILING_ZEROES
3061 : NumValidatorStyle::ONE_TRAILING_ZERO),
3062 ctrl.low, ctrl.high
3063 );
3064 }
3065 else
3066 {
3067 S.Validator<IntegerValidator<double>>(
3068 &ctrl.val, NumValidatorStyle::DEFAULT,
3069 (int) ctrl.low, (int) ctrl.high);
3070 }
3071 wxTextCtrl *item = S
3072 .Name( prompt )
3073 .AddTextBox( {}, wxT(""),
3074 (ctrl.type == NYQ_CTRL_INT_TEXT ||
3075 ctrl.type == NYQ_CTRL_FLOAT_TEXT) ? 25 : 12);
3076
3077 if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_FLOAT)
3078 {
3079 S.Id(ID_Slider + i)
3080 .Style(wxSL_HORIZONTAL)
3081 .MinSize( { 150, -1 } )
3082 .AddSlider( {}, 0, ctrl.ticks, 0);
3083 }
3084 }
3085
3086 if (ctrl.type != NYQ_CTRL_FILE)
3087 {
3088 if (ctrl.type == NYQ_CTRL_CHOICE || ctrl.label.empty())
3089 {
3090 S.AddSpace(10, 10);
3091 }
3092 else
3093 {
3094 S.AddUnits( Verbatim( ctrl.label ) );
3095 }
3096 }
3097 }
3098 }
3099 }
3100 S.EndMultiColumn();
3101 }
3102 S.EndScroller();
3103
3104 scroller->SetScrollRate(0, 20);
3105
3106 // This fools NVDA into not saying "Panel" when the dialog gets focus
3107 scroller->SetName(wxT("\a"));
3108 scroller->SetLabel(wxT("\a"));
3109}
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
const NumericConverterType & NumericConverterType_TIME()
@ ID_FILE
Definition: Nyquist.cpp:112
@ ID_Choice
Definition: Nyquist.cpp:110
@ ID_Slider
Definition: Nyquist.cpp:108
ID_Text
Definition: Nyquist.cpp:135
NyquistEffect::OnText ID_Time
Definition: Nyquist.cpp:139
@ NYQ_CTRL_STRING
Definition: Nyquist.h:35
@ NYQ_CTRL_TEXT
Definition: Nyquist.h:39
@ NYQ_CTRL_TIME
Definition: Nyquist.h:40
@ NYQ_CTRL_INT_TEXT
Definition: Nyquist.h:37
@ NYQ_CTRL_INT
Definition: Nyquist.h:33
@ NYQ_CTRL_CHOICE
Definition: Nyquist.h:36
@ NYQ_CTRL_FLOAT_TEXT
Definition: Nyquist.h:38
@ NYQ_CTRL_FILE
Definition: Nyquist.h:41
@ NYQ_CTRL_FLOAT
Definition: Nyquist.h:34
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:119
virtual NumericFormatID GetSelectionFormat()
Definition: Effect.cpp:187
static FormatterContext SampleRateContext(double sampleRate)
A control on a NyquistDialog.
Definition: Nyquist.h:45
double high
Definition: Nyquist.h:64
wxString label
Definition: Nyquist.h:56
wxString name
Definition: Nyquist.h:55
int ticks
Definition: Nyquist.h:65
std::vector< EnumValueSymbol > choices
Definition: Nyquist.h:57
int type
Definition: Nyquist.h:53
wxString valStr
Definition: Nyquist.h:59
double low
Definition: Nyquist.h:63
double val
Definition: Nyquist.h:62
FileNames::FileTypes fileTypes
Definition: Nyquist.h:58
std::vector< NyqControl > mControls
Definition: Nyquist.h:275
static void resolveFilePath(wxString &path, FileExtension extension={})
Definition: Nyquist.cpp:3353
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, NumericConverterType_TIME(), 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, FormatterContext::SampleRateContext(), NyqControl::ticks, 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 2921 of file Nyquist.cpp.

2922{
2923 S.StartVerticalLay();
2924 {
2925 S.StartMultiColumn(3, wxEXPAND);
2926 {
2927 S.SetStretchyCol(1);
2928
2929 S.AddVariableText(XO("Enter Nyquist Command: "));
2930
2931 S.AddSpace(1, 1);
2932 }
2933 S.EndMultiColumn();
2934
2935 S.StartHorizontalLay(wxEXPAND, 1);
2936 {
2937 mCommandText = S.Focus()
2938 .MinSize( { 500, 200 } )
2939 .AddTextWindow(wxT(""));
2940 }
2941 S.EndHorizontalLay();
2942
2943 S.StartHorizontalLay(wxALIGN_CENTER, 0);
2944 {
2945 S.Id(ID_Load).AddButton(XXO("&Load"));
2946 S.Id(ID_Save).AddButton(XXO("&Save"));
2947 }
2948 S.EndHorizontalLay();
2949 }
2950 S.EndVerticalLay();
2951}
XO("Cut/Copy/Paste")
@ ID_Load
Definition: Nyquist.cpp:105
@ ID_Save
Definition: Nyquist.cpp:106
wxTextCtrl * mCommandText
Definition: Nyquist.h:292

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

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

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

1924{
1925 mCont = true;
1926}
bool mCont
Definition: Nyquist.h:229

References mCont.

◆ DoLoadSettings()

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

Definition at line 431 of file Nyquist.cpp.

433{
434 // Due to a constness problem that happens when using the prompt, we need
435 // to be ready to switch the params to a local instance.
436 const CommandParameters* pParms = &parms;
437 CommandParameters localParms;
438
439 if (mIsPrompt)
440 {
441 parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
442 parms.Read(KEY_Parameters, &mParameters, wxEmptyString);
443
444 if (!mInputCmd.empty())
445 {
447 }
448
449 if (!mParameters.empty())
450 {
451 pParms = &localParms;
452 localParms.SetParameters(mParameters);
453 }
454
455 if (!IsBatchProcessing())
456 {
458 }
459
462 mExternal = true;
463
464 if (!IsBatchProcessing())
465 {
466 return true;
467 }
468 }
469
470 // Constants to document what the true/false values mean.
471 const auto kTestOnly = true;
472 const auto kTestAndSet = false;
473
474 // badCount will encompass both actual bad values and missing values.
475 // We probably never actually have bad values when using the dialogs
476 // since the dialog validation will catch them.
477 int badCount;
478 // When batch processing, we just ignore missing/bad parameters.
479 // We'll end up using defaults in those cases.
480 if (!IsBatchProcessing()) {
481 badCount = SetLispVarsFromParameters(*pParms, kTestOnly);
482 if (badCount > 0)
483 return false;
484 }
485
486 badCount = SetLispVarsFromParameters(*pParms, kTestAndSet);
487 // We never do anything with badCount here.
488 // It might be non zero, for missing parameters, and we allow that,
489 // and don't distinguish that from an out-of-range value.
490 return true;
491}
@ EffectTypeTool
static const wxChar * KEY_Command
Definition: Nyquist.cpp:120
static const wxChar * KEY_Parameters
Definition: Nyquist.cpp:121
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool SetParameters(const wxString &parms)
bool IsBatchProcessing() const override
Definition: Effect.cpp:295
EffectType mType
Definition: Nyquist.h:262
bool ParseCommand(const wxString &cmd)
Definition: Nyquist.cpp:2556
int SetLispVarsFromParameters(const CommandParameters &parms, bool bTestOnly)
Definition: Nyquist.cpp:497
const bool mIsPrompt
Definition: Nyquist.h:242
wxString mInputCmd
Definition: Nyquist.h:245
bool mExternal
Definition: Nyquist.h:235
bool mIsTool
Definition: Nyquist.h:237
wxString mParameters
Definition: Nyquist.h:246
EffectType mPromptType
Definition: Nyquist.h:263

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

1195{
1196 return mDebugButton;
1197}
bool mDebugButton
Definition: Nyquist.h:266

References mDebugButton.

◆ EscapeString()

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

Definition at line 1796 of file Nyquist.cpp.

1797{
1798 wxString str = inStr;
1799
1800 str.Replace(wxT("\\"), wxT("\\\\"));
1801 str.Replace(wxT("\""), wxT("\\\""));
1802
1803 return str;
1804}
#define str(a)

References str, and wxT().

Referenced by Process(), and ProcessOne().

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

◆ GetClassification()

EffectType NyquistEffect::GetClassification ( ) const
overridevirtual

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

Reimplemented from EffectDefinitionInterface.

Definition at line 282 of file Nyquist.cpp.

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

References EffectTypeTool, mIsTool, and mType.

◆ GetCtrlValue()

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

Definition at line 1980 of file Nyquist.cpp.

1981{
1982 /* For this to work correctly requires that the plug-in header is
1983 * parsed on each run so that the correct value for "half-srate" may
1984 * be determined.
1985 *
1986 auto project = FindProject();
1987 if (project && s.IsSameAs(wxT("half-srate"), false)) {
1988 auto rate =
1989 TrackList::Get( *project ).Selected< const WaveTrack >()
1990 .min( &WaveTrack::GetRate );
1991 return (rate / 2.0);
1992 }
1993 */
1994
1996}
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:109

References Internat::CompatibleToDouble().

Referenced by Parse(), SaveSettings(), SetLispVarsFromParameters(), 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 241 of file Nyquist.cpp.

242{
243 return mCopyright;
244}
TranslatableString mCopyright
Definition: Nyquist.h:257

References mCopyright.

◆ GetFamily()

EffectFamilySymbol NyquistEffect::GetFamily ( ) const
overridevirtual

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

Implements EffectDefinitionInterface.

Definition at line 289 of file Nyquist.cpp.

290{
292}
#define NYQUISTEFFECTS_FAMILY
Definition: EffectBase.h:141

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistEffect::GetNyquistSearchPath ( )
staticprivate

Definition at line 2702 of file Nyquist.cpp.

2703{
2704 const auto &audacityPathList = FileNames::AudacityPathList();
2705 FilePaths pathList;
2706
2707 for (size_t i = 0; i < audacityPathList.size(); i++)
2708 {
2709 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2710 FileNames::AddUniquePathToPathList(prefix + wxT("nyquist"), pathList);
2711 FileNames::AddUniquePathToPathList(prefix + wxT("plugins"), pathList);
2712 FileNames::AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList);
2713 }
2714 pathList.push_back(FileNames::PlugInDir());
2715
2716 return pathList;
2717}
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 208 of file Nyquist.cpp.

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

References mFileName, mIsPrompt, and NYQUIST_PROMPT_ID.

◆ GetSymbol()

ComponentInterfaceSymbol NyquistEffect::GetSymbol ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 216 of file Nyquist.cpp.

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

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

278{
279 return mType;
280}

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

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

References mAuthor, mIsPrompt, and XO().

Here is the call graph for this function:

◆ GetVersion()

wxString NyquistEffect::GetVersion ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 234 of file Nyquist.cpp.

235{
236 // Are Nyquist version strings really supposed to be translatable?
237 // See commit a06e561 which used XO for at least one of them
239}
TranslatableString mReleaseVersion
Definition: Nyquist.h:256
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 270 of file Nyquist.cpp.

271{
272 return mHelpPage;
273}
FilePath mHelpPage
Definition: Nyquist.h:261

References mHelpPage.

◆ Init()

bool NyquistEffect::Init ( )
overridevirtual

Default implementation does nothing, returns true

Reimplemented from StatefulEffectBase.

Definition at line 566 of file Nyquist.cpp.

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

References EffectUIServices::DoMessageBox(), WaveChannelView::FindFirst(), EffectBase::FindProject(), TrackList::Get(), SpectrogramSettings::Get(), mDebugButton, mEnablePreview, EffectBase::mF0, EffectBase::mF1, mIsPrompt, mIsSpectral, mName, mPromptName, mPromptType, mType, mVersion, project, TrackList::Selected(), SpectrogramSettings::SpectralSelectionEnabled(), and XO().

Here is the call graph for this function:

◆ InitializationError()

const TranslatableString & NyquistEffect::InitializationError ( ) const
inlineprivate

Definition at line 164 of file Nyquist.h.

164{ return mInitError; }
TranslatableString mInitError
Definition: Nyquist.h:244

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

305{
306 return mIsPrompt;
307}

References mIsPrompt.

◆ IsInteractive()

bool NyquistEffect::IsInteractive ( ) const
overridevirtual

Whether the effect needs a dialog for entry of settings.

Implements EffectDefinitionInterface.

Definition at line 294 of file Nyquist.cpp.

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

References mControls, and mIsPrompt.

◆ IsOk()

bool NyquistEffect::IsOk ( )
private

Definition at line 3113 of file Nyquist.cpp.

3114{
3115 return mOK;
3116}

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

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

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

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

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

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

Definition at line 1783 of file Nyquist.cpp.

1784{
1785 wxString str(nyqString, wxConvUTF8);
1786 if (nyqString != NULL && nyqString[0] && str.empty()) {
1787 // invalid UTF-8 string, convert as Latin-1
1788 str = _("[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1789 // TODO: internationalization of strings from Nyquist effects, at least
1790 // from those shipped with Audacity
1791 str += LAT1CTOWX(nyqString);
1792 }
1793 return str;
1794}
#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 3222 of file Nyquist.cpp.

3223{
3224 mControls[evt.GetId() - ID_Choice].val = (double) evt.GetInt();
3225}

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3258 of file Nyquist.cpp.

3259{
3260 int i = evt.GetId() - ID_FILE;
3261 NyqControl & ctrl = mControls[i];
3262
3263 // Get style flags:
3264 // Ensure legal combinations so that wxWidgets does not throw an assert error.
3265 unsigned int flags = 0;
3266 if (!ctrl.highStr.empty())
3267 {
3268 wxStringTokenizer tokenizer(ctrl.highStr, ",");
3269 while ( tokenizer.HasMoreTokens() )
3270 {
3271 wxString token = tokenizer.GetNextToken().Trim(true).Trim(false);
3272 if (token.IsSameAs("open", false))
3273 {
3274 flags |= wxFD_OPEN;
3275 flags &= ~wxFD_SAVE;
3276 flags &= ~wxFD_OVERWRITE_PROMPT;
3277 }
3278 else if (token.IsSameAs("save", false))
3279 {
3280 flags |= wxFD_SAVE;
3281 flags &= ~wxFD_OPEN;
3282 flags &= ~wxFD_MULTIPLE;
3283 flags &= ~wxFD_FILE_MUST_EXIST;
3284 }
3285 else if (token.IsSameAs("overwrite", false) && !(flags & wxFD_OPEN))
3286 {
3287 flags |= wxFD_OVERWRITE_PROMPT;
3288 }
3289 else if (token.IsSameAs("exists", false) && !(flags & wxFD_SAVE))
3290 {
3291 flags |= wxFD_FILE_MUST_EXIST;
3292 }
3293 else if (token.IsSameAs("multiple", false) && !(flags & wxFD_SAVE))
3294 {
3295 flags |= wxFD_MULTIPLE;
3296 }
3297 }
3298 }
3299
3300 resolveFilePath(ctrl.valStr);
3301
3302 wxFileName fname = ctrl.valStr;
3303 wxString defaultDir = fname.GetPath();
3304 wxString defaultFile = fname.GetName();
3305 auto message = XO("Select a file");
3306
3307 if (flags & wxFD_MULTIPLE)
3308 message = XO("Select one or more files");
3309 else if (flags & wxFD_SAVE)
3310 message = XO("Save file as");
3311
3312 FileDialogWrapper openFileDialog(mUIParent->FindWindow(ID_FILE + i),
3313 message,
3314 defaultDir,
3315 defaultFile,
3316 ctrl.fileTypes,
3317 flags); // styles
3318
3319 if (openFileDialog.ShowModal() == wxID_CANCEL)
3320 {
3321 return;
3322 }
3323
3324 wxString path;
3325 // When multiple files selected, return file paths as a list of quoted strings.
3326 if (flags & wxFD_MULTIPLE)
3327 {
3328 wxArrayString selectedFiles;
3329 openFileDialog.GetPaths(selectedFiles);
3330
3331 for (size_t sf = 0; sf < selectedFiles.size(); sf++) {
3332 path += "\"";
3333 path += selectedFiles[sf];
3334 path += "\"";
3335 }
3336 ctrl.valStr = path;
3337 }
3338 else
3339 {
3340 ctrl.valStr = openFileDialog.GetPath();
3341 }
3342
3343 mUIParent->FindWindow(ID_Text + i)->GetValidator()->TransferToWindow();
3344}
wxString highStr
Definition: Nyquist.h:61
wxWeakRef< wxWindow > mUIParent
Definition: Nyquist.h:146

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

3126{
3127 if (mCommandText->IsModified())
3128 {
3129 if (wxNO == EffectUIServices::DoMessageBox(*this,
3130 XO("Current program has been modified.\nDiscard changes?"),
3131 wxYES_NO ) )
3132 {
3133 return;
3134 }
3135 }
3136
3137 FileDialogWrapper dlog(
3138 mUIParent,
3139 XO("Load Nyquist script"),
3140 mFileName.GetPath(),
3141 wxEmptyString,
3142 {
3143 NyquistScripts,
3144 LispScripts,
3145 FileNames::TextFiles,
3146 FileNames::AllFiles
3147 },
3148 wxFD_OPEN | wxRESIZE_BORDER);
3149
3150 if (dlog.ShowModal() != wxID_OK)
3151 {
3152 return;
3153 }
3154
3155 mFileName = dlog.GetPath();
3156
3157 if (!mCommandText->LoadFile(mFileName.GetFullPath()))
3158 {
3159 EffectUIServices::DoMessageBox(*this, XO("File could not be loaded"));
3160 }
3161}

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

3164{
3165 FileDialogWrapper dlog(
3166 mUIParent,
3167 XO("Save Nyquist script"),
3168 mFileName.GetPath(),
3169 mFileName.GetFullName(),
3170 {
3171 NyquistScripts,
3172 LispScripts,
3173 FileNames::AllFiles
3174 },
3175 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
3176
3177 if (dlog.ShowModal() != wxID_OK)
3178 {
3179 return;
3180 }
3181
3182 mFileName = dlog.GetPath();
3183
3184 if (!mCommandText->SaveFile(mFileName.GetFullPath()))
3185 {
3186 EffectUIServices::DoMessageBox(*this, XO("File could not be saved"));
3187 }
3188}

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

3191{
3192 int i = evt.GetId() - ID_Slider;
3193 NyqControl & ctrl = mControls[i];
3194
3195 int val = evt.GetInt();
3196 double range = ctrl.high - ctrl.low;
3197 double newVal = (val / (double)ctrl.ticks) * range + ctrl.low;
3198
3199 // Determine precision for displayed number
3200 int precision = range < 1.0 ? 3 :
3201 range < 10.0 ? 2 :
3202 range < 100.0 ? 1 :
3203 0;
3204
3205 // If the value is at least one tick different from the current value
3206 // change it (this prevents changes from manually entered values unless
3207 // the slider actually moved)
3208 if (fabs(newVal - ctrl.val) >= (1 / (double)ctrl.ticks) * range &&
3209 fabs(newVal - ctrl.val) >= pow(0.1, precision) / 2)
3210 {
3211 // First round to the appropriate precision
3212 newVal *= pow(10.0, precision);
3213 newVal = floor(newVal + 0.5);
3214 newVal /= pow(10.0, precision);
3215
3216 ctrl.val = newVal;
3217
3218 mUIParent->FindWindow(ID_Text + i)->GetValidator()->TransferToWindow();
3219 }
3220}

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

3434{
3435 int i = evt.GetId() - ID_Text;
3436
3437 NyqControl & ctrl = mControls[i];
3438
3439 if (wxDynamicCast(evt.GetEventObject(), wxWindow)->GetValidator()->TransferFromWindow())
3440 {
3441 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_INT)
3442 {
3443 int pos = (int)floor((ctrl.val - ctrl.low) /
3444 (ctrl.high - ctrl.low) * ctrl.ticks + 0.5);
3445
3446 wxSlider *slider = (wxSlider *)mUIParent->FindWindow(ID_Slider + i);
3447 slider->SetValue(pos);
3448 }
3449 }
3450}

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

3228{
3229 int i = evt.GetId() - ID_Time;
3230 static double value = 0.0;
3231 NyqControl & ctrl = mControls[i];
3232
3233 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
3234 double val = n->GetValue();
3235
3236 // Observed that two events transmitted on each control change (Linux)
3237 // so skip if value has not changed.
3238 if (val != value) {
3239 if (val < ctrl.low || val > ctrl.high) {
3240 const auto message = XO("Value range:\n%s to %s")
3241 .Format( ToTimeFormat(ctrl.low), ToTimeFormat(ctrl.high) );
3243 message,
3244 wxOK | wxCENTRE,
3245 XO("Value Error") );
3246 }
3247
3248 if (val < ctrl.low)
3249 val = ctrl.low;
3250 else if (val > ctrl.high)
3251 val = ctrl.high;
3252
3253 n->SetValue(val);
3254 value = val;
3255 }
3256}
void SetValue(double newValue)
wxString ToTimeFormat(double t)
Definition: Nyquist.cpp:3423

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

2673{
2674 if (mStop) {
2675 mStop = false;
2676 nyx_stop();
2677 }
2678 else if (mBreak) {
2679 mBreak = false;
2680 nyx_break();
2681 }
2682 else if (mCont) {
2683 mCont = false;
2684 nyx_continue();
2685 }
2686
2687 // LLL: STF figured out that yielding while the effect is being applied
2688 // produces an EXTREME slowdown. It appears that yielding is not
2689 // really necessary on Linux and Windows.
2690 //
2691 // However, on the Mac, the spinning cursor appears during longer
2692 // Nyquist processing and that may cause the user to think Audacity
2693 // has crashed or hung. In addition, yielding or not on the Mac
2694 // doesn't seem to make much of a difference in execution time.
2695 //
2696 // So, yielding on the Mac only...
2697#if defined(__WXMAC__)
2698 wxYieldIfNeeded();
2699#endif
2700}
bool mStop
Definition: Nyquist.h:227

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2656 of file Nyquist.cpp.

2657{
2658 // Always collect Nyquist error messages for normal plug-ins
2659 if (!mRedirectOutput) {
2660 mDebugOutputStr += (wxChar)c;
2661 return;
2662 }
2663
2664 std::cout << (char)c;
2665}
bool mRedirectOutput
Definition: Nyquist.h:269
wxString mDebugOutputStr
Definition: Nyquist.h:271

References mDebugOutputStr, and mRedirectOutput.

◆ Parse()

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

Definition at line 2097 of file Nyquist.cpp.

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

1807{
1808 std::vector<EnumValueSymbol> results;
1809 if (text[0] == wxT('(')) {
1810 // New style: expecting a Lisp-like list of strings
1811 Tokenizer tzer;
1812 tzer.Tokenize(text, true, 1, 1);
1813 auto &choices = tzer.tokens;
1814 wxString extra;
1815 for (auto &choice : choices) {
1816 auto label = UnQuote(choice, true, &extra);
1817 if (extra.empty())
1818 results.push_back( TranslatableString{ label, {} } );
1819 else
1820 results.push_back(
1821 { extra, TranslatableString{ label, {} } } );
1822 }
1823 }
1824 else {
1825 // Old style: expecting a comma-separated list of
1826 // un-internationalized names, ignoring leading and trailing spaces
1827 // on each; and the whole may be quoted
1828 auto choices = wxStringTokenize(
1829 text[0] == wxT('"') ? text.Mid(1, text.length() - 2) : text,
1830 wxT(",")
1831 );
1832 for (auto &choice : choices)
1833 results.push_back( { choice.Trim(true).Trim(false) } );
1834 }
1835 return results;
1836}
TranslatableString label
Definition: TagsEditor.cpp:165

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

2557{
2558 wxStringInputStream stream(cmd + wxT(" "));
2559
2560 return ParseProgram(stream);
2561}
bool ParseProgram(wxInputStream &stream)
Definition: Nyquist.cpp:2450

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

2549{
2550 wxFileInputStream rawStream(mFileName.GetFullPath());
2551 wxBufferedInputStream stream(rawStream, 10000);
2552
2553 ParseProgram(stream);
2554}

References mFileName, and ParseProgram().

Here is the call graph for this function:

◆ ParseFileExtensions()

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

Definition at line 1838 of file Nyquist.cpp.

1839{
1840 // todo: error handling
1841 FileExtensions results;
1842 if (text[0] == wxT('(')) {
1843 Tokenizer tzer;
1844 tzer.Tokenize(text, true, 1, 1);
1845 for (const auto &token : tzer.tokens)
1846 results.push_back( UnQuote( token ) );
1847 }
1848 return results;
1849}

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

1852{
1853 // todo: error handling
1854 FileNames::FileType result;
1855 if (text[0] == wxT('(')) {
1856 Tokenizer tzer;
1857 tzer.Tokenize(text, true, 1, 1);
1858 auto &tokens = tzer.tokens;
1859 if ( tokens.size() == 2 )
1860 result =
1861 { UnQuoteMsgid( tokens[0] ), ParseFileExtensions( tokens[1] ) };
1862 }
1863 return result;
1864}
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1933
FileExtensions ParseFileExtensions(const wxString &text)
Definition: Nyquist.cpp:1838

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

1867{
1868 // todo: error handling
1869 FileNames::FileTypes results;
1870 if (text[0] == wxT('(')) {
1871 Tokenizer tzer;
1872 tzer.Tokenize(text, true, 1, 1);
1873 auto &types = tzer.tokens;
1874 if ( !types.empty() && types[0][0] == wxT('(') )
1875 for (auto &type : types)
1876 results.push_back( ParseFileType( type ) );
1877 }
1878 if ( results.empty() ) {
1879 // Old-style is a specially formatted string, maybe translated
1880 // Parse it for compatibility
1881 auto str = UnQuote( text );
1882 auto pieces = wxSplit( str, '|' );
1883 // Should have an even number
1884 auto size = pieces.size();
1885 if ( size % 2 == 1 )
1886 --size, pieces.pop_back();
1887 for ( size_t ii = 0; ii < size; ii += 2 ) {
1888 FileExtensions extensions;
1889 auto extensionStrings = wxSplit( pieces[ii + 1], ';' );
1890 for ( const auto &extensionString : extensionStrings )
1891 if ( extensionString.StartsWith( wxT("*.") ) ) {
1892 auto ext = extensionString.substr( 2 );
1893 if (ext == wxT("*"))
1894 // "*.*" to match all
1895 ext.clear();
1896 extensions.push_back( ext );
1897 }
1898 results.push_back( { Verbatim( pieces[ii] ), extensions } );
1899 }
1900 }
1901 return results;
1902}
std::vector< FileType > FileTypes
Definition: FileNames.h:75
FileNames::FileType ParseFileType(const wxString &text)
Definition: Nyquist.cpp:1851

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

2451{
2452 if (!stream.IsOk())
2453 {
2454 mInitError = XO("Could not open file");
2455 return false;
2456 }
2457
2458 wxTextInputStream pgm(stream, wxT(" \t"), wxConvAuto());
2459
2460 mCmd = wxT("");
2461 mCmd.Alloc(10000);
2462 mIsSal = false;
2463 mControls.clear();
2464 mCategories.clear();
2465 mIsSpectral = false;
2466 mManPage = wxEmptyString; // If not wxEmptyString, must be a page in the Audacity manual.
2467 mHelpFile = wxEmptyString; // If not wxEmptyString, must be a valid HTML help file.
2468 mHelpFileExists = false;
2469 mDebug = false;
2470 mTrace = false;
2471 mDebugButton = true; // Debug button enabled by default.
2472 mEnablePreview = true; // Preview button enabled by default.
2473
2474 // Bug 1934.
2475 // All Nyquist plug-ins should have a ';type' field, but if they don't we default to
2476 // being an Effect.
2478
2479 mFoundType = false;
2480 while (!stream.Eof() && stream.IsOk())
2481 {
2482 wxString line = pgm.ReadLine();
2483 if (line.length() > 1 &&
2484 // New in 2.3.0: allow magic comment lines to start with $
2485 // The trick is that xgettext will not consider such lines comments
2486 // and will extract the strings they contain
2487 (line[0] == wxT(';') || line[0] == wxT('$')) )
2488 {
2489 Tokenizer tzer;
2490 unsigned nLines = 1;
2491 bool done;
2492 // Allow continuations within control lines.
2493 bool control =
2494 line[0] == wxT('$') || line.StartsWith( wxT(";control") );
2495 do
2496 done = Parse(tzer, line, !control || stream.Eof(), nLines == 1);
2497 while(!done &&
2498 (line = pgm.ReadLine(), ++nLines, true));
2499
2500 // Don't pass these lines to the interpreter, so it doesn't get confused
2501 // by $, but pass blanks,
2502 // so that SAL effects compile with proper line numbers
2503 while (nLines --)
2504 mCmd += wxT('\n');
2505 }
2506 else
2507 {
2508 if(!mFoundType && line.length() > 0) {
2509 if (line[0] == wxT('(') ||
2510 (line[0] == wxT('#') && line.length() > 1 && line[1] == wxT('|')))
2511 {
2512 mIsSal = false;
2513 mFoundType = true;
2514 }
2515 else if (line.Upper().Find(wxT("RETURN")) != wxNOT_FOUND)
2516 {
2517 mIsSal = true;
2518 mFoundType = true;
2519 }
2520 }
2521 mCmd += line + wxT("\n");
2522 }
2523 }
2524 if (!mFoundType && mIsPrompt)
2525 {
2526 /* i1n-hint: SAL and LISP are names for variant syntaxes for the
2527 Nyquist programming language. Leave them, and 'return', untranslated. */
2529 XO(
2530"Your code looks like SAL syntax, but there is no \'return\' statement.\n\
2531For SAL, use a return statement such as:\n\treturn *track* * 0.1\n\
2532or for LISP, begin with an open parenthesis such as:\n\t(mult *track* 0.1)\n ."),
2534 XO("Error in Nyquist code") );
2535 /* i18n-hint: refers to programming "languages" */
2536 mInitError = XO("Could not determine language");
2537 return false;
2538 // Else just throw it at Nyquist to see what happens
2539 }
2540
2541 const auto helpStuff = CheckHelpPage();
2542 mHelpFileExists = helpStuff.first;
2543 mHelpPage = helpStuff.second;
2544
2545 return true;
2546}
std::pair< bool, FilePath > CheckHelpPage() const
Definition: Nyquist.cpp:254
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
Definition: Nyquist.cpp:2097
bool mHelpFileExists
Definition: Nyquist.h:260
bool mDebug
Definition: Nyquist.h:268
wxString mCmd
Definition: Nyquist.h:247

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

1185{
1186 mUIParent = S.GetParent();
1187 if (mIsPrompt)
1189 else
1191 return nullptr;
1192}
void BuildEffectWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2953
void BuildPromptWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2921

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

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

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

Here is the call graph for this function:

◆ ProcessOne()

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

Definition at line 1273 of file Nyquist.cpp.

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

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

Referenced by Process().

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

◆ RedirectOutput()

void NyquistEffect::RedirectOutput ( )

Definition at line 1904 of file Nyquist.cpp.

1905{
1906 mRedirectOutput = true;
1907}

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

3355{
3356#if defined(__WXMSW__)
3357 path.Replace("/", wxFileName::GetPathSeparator());
3358#endif
3359
3360 path.Trim(true).Trim(false);
3361
3362 typedef std::unordered_map<wxString, FilePath> map;
3363 map pathKeys = {
3364 {"*home*", wxGetHomeDir()},
3365 {"~", wxGetHomeDir()},
3366 {"*default*", FileNames::DefaultToDocumentsFolder("").GetPath()},
3367 {"*export*", FileNames::FindDefaultPath(FileNames::Operation::Export)},
3368 {"*save*", FileNames::FindDefaultPath(FileNames::Operation::Save)},
3369 {"*config*", FileNames::DataDir()}
3370 };
3371
3372 int characters = path.Find(wxFileName::GetPathSeparator());
3373 if(characters == wxNOT_FOUND) // Just a path or just a file name
3374 {
3375 if (path.empty())
3376 path = "*default*";
3377
3378 if (pathKeys.find(path) != pathKeys.end())
3379 {
3380 // Keyword found, so assume this is the intended directory.
3381 path = pathKeys[path] + wxFileName::GetPathSeparator();
3382 }
3383 else // Just a file name
3384 {
3385 path = pathKeys["*default*"] + wxFileName::GetPathSeparator() + path;
3386 }
3387 }
3388 else // path + file name
3389 {
3390 wxString firstDir = path.Left(characters);
3391 wxString rest = path.Mid(characters);
3392
3393 if (pathKeys.find(firstDir) != pathKeys.end())
3394 {
3395 path = pathKeys[firstDir] + rest;
3396 }
3397 }
3398
3399 wxFileName fname = path;
3400
3401 // If the directory is invalid, better to leave it as is (invalid) so that
3402 // the user sees the error rather than an unexpected file path.
3403 if (fname.wxFileName::IsOk() && fname.GetFullName().empty())
3404 {
3405 path = fname.GetPathWithSep() + _("untitled");
3406 if (!extension.empty())
3407 path = path + '.' + extension;
3408 }
3409}
FILES_API wxFileNameWrapper DefaultToDocumentsFolder(const wxString &preference)
FILES_API FilePath FindDefaultPath(Operation op)

References _, FileNames::DataDir(), FileNames::DefaultToDocumentsFolder(), anonymous_namespace{CloudProjectFileIOExtensions.cpp}::extension, 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 373 of file Nyquist.cpp.

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

1910{
1911 mExternal = true;
1912
1913 if (cmd.size()) {
1914 ParseCommand(cmd);
1915 }
1916}

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

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

1106{
1107 int res = wxID_APPLY;
1109 // Show the normal (prompt or effect) interface
1111 parent, factory, pInstance, access, forceModal);
1112 }
1113
1114
1115 // Remember if the user clicked debug
1116 mDebug = (res == eDebugID);
1117
1118 // We're done if the user clicked "Close", we are not the Nyquist Prompt,
1119 // or the program currently loaded into the prompt doesn't have a UI.
1120 if (!res || !mIsPrompt || mControls.size() == 0 || !pInstance)
1121 return res;
1122
1123 // Nyquist prompt was OK, but gave us some magic ;control comments to
1124 // reinterpret into a second dialog
1125
1127 effect.SetCommand(mInputCmd);
1128 Finally Do{[&]{
1129 // A second dialog will use effect as a pushed event handler.
1130 // wxWidgets delays window destruction until idle time.
1131 // Yield to destroy the dialog while effect is still in scope.
1133 }};
1134
1135 // Must give effect its own settings to interpret, not those in access
1136 // Let's also give it its own instance
1137 auto newSettings = effect.MakeSettings();
1138 auto pNewInstance = effect.MakeInstance();
1139 auto newAccess = std::make_shared<SimpleEffectSettingsAccess>(newSettings);
1140
1141 if (IsBatchProcessing()) {
1142 effect.SetBatchProcessing();
1143
1146 effect.LoadSettings(cp, newSettings);
1147
1148 // Show the normal (prompt or effect) interface
1149 // Don't pass this as first argument, pass the worker to itself
1150 res = effect.ShowHostInterface(effect,
1151 parent, factory, pNewInstance, *newAccess, forceModal);
1152 if (res) {
1154 effect.SaveSettings(newSettings, cp);
1156 }
1157 }
1158 else {
1159 if (!factory)
1160 return 0;
1161 // Don't pass this as first argument, pass the worker to itself
1162 res = effect.ShowHostInterface(effect,
1163 parent, factory, pNewInstance, *newAccess, false );
1164 if (!res)
1165 return 0;
1166
1167 // Wrap the new settings in the old settings
1169 auto &nyquistSettings = GetSettings(settings);
1170 nyquistSettings.proxySettings = std::move(newSettings);
1171 nyquistSettings.proxyDebug = this->mDebug;
1172 nyquistSettings.controls = move(effect.mControls);
1173 return nullptr;
1174 });
1175 }
1176 if (!pNewInstance)
1177 // Propagate the failure from nested ShowHostInterface
1178 pInstance.reset();
1179 return res;
1180}
static RegisteredToolbarFactory factory
@ eDebugID
Definition: ShuttleGui.h:628
bool GetParameters(wxString &parms)
unsigned TestUIFlags(unsigned mask)
Definition: Effect.cpp:291
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
virtual int ShowHostInterface(EffectBase &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:225
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:175

References eDebugID, 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:

◆ StaticOSCallback()

void NyquistEffect::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2667 of file Nyquist.cpp.

2668{
2669 ((NyquistEffect *)This)->OSCallback();
2670}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2651 of file Nyquist.cpp.

2652{
2653 ((NyquistEffect *)This)->OutputCallback(c);
2654}

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1928 of file Nyquist.cpp.

1929{
1930 mStop = true;
1931}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3423 of file Nyquist.cpp.

3424{
3425 int seconds = static_cast<int>(t);
3426 int hh = seconds / 3600;
3427 int mm = seconds % 3600;
3428 mm = mm / 60;
3429 return wxString::Format("%d:%d:%.3f", hh, mm, t - (hh * 3600 + mm * 60));
3430}

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2781 of file Nyquist.cpp.

2782{
2783 if (mControls.size() == 0)
2784 {
2785 return true;
2786 }
2787
2788 for (unsigned int i = 0; i < mControls.size(); i++)
2789 {
2790 NyqControl *ctrl = &mControls[i];
2791
2792 if (ctrl->type == NYQ_CTRL_STRING || ctrl->type == NYQ_CTRL_TEXT)
2793 {
2794 continue;
2795 }
2796
2797 if (ctrl->val == UNINITIALIZED_CONTROL)
2798 {
2799 ctrl->val = GetCtrlValue(ctrl->valStr);
2800 }
2801
2802 if (ctrl->type == NYQ_CTRL_CHOICE)
2803 {
2804 continue;
2805 }
2806
2807 if (ctrl->type == NYQ_CTRL_FILE)
2808 {
2809 resolveFilePath(ctrl->valStr);
2810
2811 wxString path;
2812 if (ctrl->valStr.StartsWith("\"", &path))
2813 {
2814 // Validate if a list of quoted paths.
2815 if (path.EndsWith("\"", &path))
2816 {
2817 path.Replace("\"\"", "\"");
2818 wxStringTokenizer tokenizer(path, "\"");
2819 while (tokenizer.HasMoreTokens())
2820 {
2821 wxString token = tokenizer.GetNextToken();
2822 if(!validatePath(token))
2823 {
2824 const auto message =
2825 XO("\"%s\" is not a valid file path.").Format( token );
2827 message,
2828 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2829 XO("Error") );
2830 return false;
2831 }
2832 }
2833 continue;
2834 }
2835 else
2836 {
2837 const auto message =
2838 /* i18n-hint: Warning that there is one quotation mark rather than a pair.*/
2839 XO("Mismatched quotes in\n%s").Format( ctrl->valStr );
2841 message,
2842 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2843 XO("Error") );
2844 return false;
2845 }
2846 }
2847 // Validate a single path.
2848 else if (validatePath(ctrl->valStr))
2849 {
2850 continue;
2851 }
2852
2853 // Validation failed
2854 const auto message =
2855 XO("\"%s\" is not a valid file path.").Format( ctrl->valStr );
2857 message,
2858 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2859 XO("Error") );
2860 return false;
2861 }
2862
2863 if (ctrl->type == NYQ_CTRL_TIME)
2864 {
2865 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
2866 ctrl->val = n->GetValue();
2867 }
2868
2869 if (ctrl->type == NYQ_CTRL_INT_TEXT && ctrl->lowStr.IsSameAs(wxT("nil"), false)) {
2870 ctrl->low = INT_MIN;
2871 }
2872 else if ((ctrl->type == NYQ_CTRL_FLOAT_TEXT || ctrl->type == NYQ_CTRL_TIME) &&
2873 ctrl->lowStr.IsSameAs(wxT("nil"), false))
2874 {
2875 ctrl->low = -(FLT_MAX);
2876 }
2877 else
2878 {
2879 ctrl->low = GetCtrlValue(ctrl->lowStr);
2880 }
2881
2882 if (ctrl->type == NYQ_CTRL_INT_TEXT && ctrl->highStr.IsSameAs(wxT("nil"), false)) {
2883 ctrl->high = INT_MAX;
2884 }
2885 else if ((ctrl->type == NYQ_CTRL_FLOAT_TEXT || ctrl->type == NYQ_CTRL_TIME) &&
2886 ctrl->highStr.IsSameAs(wxT("nil"), false))
2887 {
2888 ctrl->high = FLT_MAX;
2889 }
2890 else
2891 {
2892 ctrl->high = GetCtrlValue(ctrl->highStr);
2893 }
2894
2895 if (ctrl->high < ctrl->low)
2896 {
2897 ctrl->high = ctrl->low + 1;
2898 }
2899
2900 if (ctrl->val < ctrl->low)
2901 {
2902 ctrl->val = ctrl->low;
2903 }
2904
2905 if (ctrl->val > ctrl->high)
2906 {
2907 ctrl->val = ctrl->high;
2908 }
2909
2910 ctrl->ticks = 1000;
2911 if (ctrl->type == NYQ_CTRL_INT &&
2912 (ctrl->high - ctrl->low < ctrl->ticks))
2913 {
2914 ctrl->ticks = (int)(ctrl->high - ctrl->low);
2915 }
2916 }
2917
2918 return true;
2919}
bool validatePath(wxString path)
Definition: Nyquist.cpp:3412

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

2764{
2765 mInputCmd = mCommandText->GetValue();
2766
2767 // Un-correct smart quoting, bothersomely applied in wxTextCtrl by
2768 // the native widget of MacOS 10.9 SDK
2769 const wxString left = wxT("\u201c"), right = wxT("\u201d"), dumb = '"';
2770 mInputCmd.Replace(left, dumb, true);
2771 mInputCmd.Replace(right, dumb, true);
2772
2773 const wxString leftSingle = wxT("\u2018"), rightSingle = wxT("\u2019"),
2774 dumbSingle = '\'';
2775 mInputCmd.Replace(leftSingle, dumbSingle, true);
2776 mInputCmd.Replace(rightSingle, dumbSingle, true);
2777
2778 return ParseCommand(mInputCmd);
2779}

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

1222{
1223 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
1224 {
1225 return false;
1226 }
1227
1228 if (mIsPrompt)
1229 {
1231 }
1233}
bool TransferDataFromPromptWindow()
Definition: Nyquist.cpp:2763
bool TransferDataFromEffectWindow()
Definition: Nyquist.cpp:2781

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

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2726 of file Nyquist.cpp.

2727{
2728 for (size_t i = 0, cnt = mControls.size(); i < cnt; i++)
2729 {
2730 NyqControl & ctrl = mControls[i];
2731
2732 if (ctrl.type == NYQ_CTRL_CHOICE)
2733 {
2734 const auto count = ctrl.choices.size();
2735
2736 int val = (int)ctrl.val;
2737 if (val < 0 || val >= (int)count)
2738 {
2739 val = 0;
2740 }
2741
2742 wxChoice *c = (wxChoice *) mUIParent->FindWindow(ID_Choice + i);
2743 c->SetSelection(val);
2744 }
2745 else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_FLOAT)
2746 {
2747 // wxTextCtrls are handled by the validators
2748 double range = ctrl.high - ctrl.low;
2749 int val = (int)(0.5 + ctrl.ticks * (ctrl.val - ctrl.low) / range);
2750 wxSlider *s = (wxSlider *) mUIParent->FindWindow(ID_Slider + i);
2751 s->SetValue(val);
2752 }
2753 else if (ctrl.type == NYQ_CTRL_TIME)
2754 {
2755 NumericTextCtrl *n = (NumericTextCtrl *) mUIParent->FindWindow(ID_Time + i);
2756 n->SetValue(ctrl.val);
2757 }
2758 }
2759
2760 return true;
2761}

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

2720{
2721 mCommandText->ChangeValue(mInputCmd);
2722
2723 return true;
2724}

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

1200{
1201 mUIParent->TransferDataToWindow();
1202
1203 bool success;
1204 if (mIsPrompt)
1205 {
1206 success = TransferDataToPromptWindow();
1207 }
1208 else
1209 {
1210 success = TransferDataToEffectWindow();
1211 }
1212
1213 if (success)
1214 {
1216 }
1217
1218 return success;
1219}
static bool EnablePreview(wxWindow *parent, bool enable=true)
bool TransferDataToPromptWindow()
Definition: Nyquist.cpp:2719
bool TransferDataToEffectWindow()
Definition: Nyquist.cpp:2726

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

1976{
1977 return UnQuoteMsgid( s, allowParens, pExtraString ).Translation();
1978}

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

1935{
1936 if (pExtraString)
1937 *pExtraString = wxString{};
1938
1939 int len = s.length();
1940 if (len >= 2 && s[0] == wxT('\"') && s[len - 1] == wxT('\"')) {
1941 auto unquoted = s.Mid(1, len - 2);
1942 // Sorry, no context strings, yet
1943 // (See also comments in NyquistEffectsModule::AutoRegisterPlugins)
1944 return TranslatableString{ unquoted, {} };
1945 }
1946 else if (allowParens &&
1947 len >= 2 && s[0] == wxT('(') && s[len - 1] == wxT(')')) {
1948 Tokenizer tzer;
1949 tzer.Tokenize(s, true, 1, 1);
1950 auto &tokens = tzer.tokens;
1951 if (tokens.size() > 1) {
1952 if (pExtraString && tokens[1][0] == '(') {
1953 // A choice with a distinct internal string form like
1954 // ("InternalString" (_ "Visible string"))
1955 // Recur to find the two strings
1956 *pExtraString = UnQuote(tokens[0], false);
1957 return UnQuoteMsgid(tokens[1]);
1958 }
1959 else {
1960 // Assume the first token was _ -- we don't check that
1961 // And the second is the string, which is internationalized
1962 // Sorry, no context strings, yet
1963 return UnQuoteMsgid( tokens[1], false );
1964 }
1965 }
1966 else
1967 return {};
1968 }
1969 else
1970 // If string was not quoted, assume no translation exists
1971 return Verbatim( s );
1972}

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

3413{
3414 wxFileName fname = path;
3415 wxString dir = fname.GetPath();
3416
3417 return (fname.wxFileName::IsOk() &&
3418 wxFileName::DirExists(dir) &&
3419 !fname.GetFullName().empty());
3420}

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

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

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

Member Data Documentation

◆ mAction

TranslatableString NyquistEffect::mAction
private

Definition at line 250 of file Nyquist.h.

Referenced by Parse().

◆ mAuthor

TranslatableString NyquistEffect::mAuthor
private

Definition at line 252 of file Nyquist.h.

Referenced by GetVendor(), and Parse().

◆ mBreak

bool NyquistEffect::mBreak
private

Definition at line 228 of file Nyquist.h.

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

◆ mCategories

wxArrayString NyquistEffect::mCategories
private

Definition at line 284 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mCmd

wxString NyquistEffect::mCmd
private

Definition at line 247 of file Nyquist.h.

Referenced by ParseProgram(), and ProcessOne().

◆ mCommandText

wxTextCtrl* NyquistEffect::mCommandText
private

◆ mCompiler

bool NyquistEffect::mCompiler
private

Definition at line 232 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mCont

bool NyquistEffect::mCont
private

Definition at line 229 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 257 of file Nyquist.h.

Referenced by GetDescription(), and Parse().

◆ mCount

unsigned NyquistEffect::mCount
private

Definition at line 281 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mDebug

bool NyquistEffect::mDebug
private

Definition at line 268 of file Nyquist.h.

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

◆ mDebugButton

bool NyquistEffect::mDebugButton
private

Definition at line 266 of file Nyquist.h.

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

◆ mDebugOutput

TranslatableString NyquistEffect::mDebugOutput
private

Definition at line 272 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mDebugOutputStr

wxString NyquistEffect::mDebugOutputStr
private

Definition at line 271 of file Nyquist.h.

Referenced by OutputCallback(), and Process().

◆ mEnablePreview

bool NyquistEffect::mEnablePreview
private

Definition at line 265 of file Nyquist.h.

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

◆ mExternal

bool NyquistEffect::mExternal
private

Definition at line 235 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 225 of file Nyquist.h.

◆ mFileName

wxFileName NyquistEffect::mFileName
private

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

Definition at line 224 of file Nyquist.h.

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

◆ mFirstInGroup

bool NyquistEffect::mFirstInGroup
private

Definition at line 279 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mFoundType

bool NyquistEffect::mFoundType
private

Definition at line 231 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mHelpFile

wxString NyquistEffect::mHelpFile
private

Definition at line 259 of file Nyquist.h.

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

◆ mHelpFileExists

bool NyquistEffect::mHelpFileExists
private

Definition at line 260 of file Nyquist.h.

Referenced by ParseProgram(), and Process().

◆ mHelpPage

FilePath NyquistEffect::mHelpPage
private

Definition at line 261 of file Nyquist.h.

Referenced by HelpPage(), and ParseProgram().

◆ mInfo

TranslatableString NyquistEffect::mInfo
private

Definition at line 251 of file Nyquist.h.

Referenced by Parse().

◆ mInitError

TranslatableString NyquistEffect::mInitError
private

Definition at line 244 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 242 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 234 of file Nyquist.h.

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

◆ mIsSpectral

bool NyquistEffect::mIsSpectral
private

Definition at line 236 of file Nyquist.h.

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

◆ mIsTool

bool NyquistEffect::mIsTool
private

Definition at line 237 of file Nyquist.h.

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

◆ mManPage

wxString NyquistEffect::mManPage
private

Definition at line 258 of file Nyquist.h.

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

◆ mMaxLen

sampleCount NyquistEffect::mMaxLen
private

Definition at line 277 of file Nyquist.h.

Referenced by Parse(), and Process().

◆ mMergeClips

int NyquistEffect::mMergeClips
private

Definition at line 290 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mName

TranslatableString NyquistEffect::mName
private

Name of the Effect (untranslated)

Definition at line 248 of file Nyquist.h.

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

◆ mNumSelectedChannels

unsigned NyquistEffect::mNumSelectedChannels
private

Definition at line 282 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mOK

bool NyquistEffect::mOK
private

Definition at line 243 of file Nyquist.h.

Referenced by IsOk(), and Parse().

◆ mOutputTime

double NyquistEffect::mOutputTime
private

Definition at line 280 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mParameters

wxString NyquistEffect::mParameters
private

Definition at line 246 of file Nyquist.h.

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

◆ mPerTrackProps

wxString NyquistEffect::mPerTrackProps
private

Definition at line 287 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mProjectChanged

bool NyquistEffect::mProjectChanged
private

Definition at line 270 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mPromptName

TranslatableString NyquistEffect::mPromptName
private

Definition at line 249 of file Nyquist.h.

Referenced by Init().

◆ mPromptType

EffectType NyquistEffect::mPromptType
private

Definition at line 263 of file Nyquist.h.

Referenced by DoLoadSettings(), and Init().

◆ mProps

wxString NyquistEffect::mProps
private

Definition at line 286 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mRedirectOutput

bool NyquistEffect::mRedirectOutput
private

Definition at line 269 of file Nyquist.h.

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

◆ mReentryCount

int NyquistEffect::mReentryCount = 0
staticprivate

Definition at line 148 of file Nyquist.h.

Referenced by Process().

◆ mReleaseVersion

TranslatableString NyquistEffect::mReleaseVersion
private

Definition at line 256 of file Nyquist.h.

Referenced by GetVersion(), and Parse().

◆ mRestoreSplits

bool NyquistEffect::mRestoreSplits
private

Definition at line 289 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mStop

bool NyquistEffect::mStop
private

Definition at line 227 of file Nyquist.h.

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

◆ mTrace

bool NyquistEffect::mTrace
private

Definition at line 233 of file Nyquist.h.

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

◆ mTrackIndex

int NyquistEffect::mTrackIndex
private

Definition at line 278 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mType

EffectType NyquistEffect::mType
private

Definition at line 262 of file Nyquist.h.

Referenced by DoLoadSettings(), GetClassification(), GetType(), Init(), Parse(), and ParseProgram().

◆ mUIParent

wxWeakRef<wxWindow> NyquistEffect::mUIParent {}
private

◆ mVersion

int NyquistEffect::mVersion
private

Definition at line 274 of file Nyquist.h.

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

◆ mXlispPath

wxString NyquistEffect::mXlispPath
private

Definition at line 222 of file Nyquist.h.


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