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)
 
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 76 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 1910 of file Nyquist.cpp.

1911{
1912 mBreak = true;
1913}
bool mBreak
Definition: Nyquist.h:226

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2945 of file Nyquist.cpp.

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

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

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:257
static FilePaths GetNyquistSearchPath()
Definition: Nyquist.cpp:2694

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

1916{
1917 mCont = true;
1918}
bool mCont
Definition: Nyquist.h:227

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:260
bool ParseCommand(const wxString &cmd)
Definition: Nyquist.cpp:2548
int SetLispVarsFromParameters(const CommandParameters &parms, bool bTestOnly)
Definition: Nyquist.cpp:497
const bool mIsPrompt
Definition: Nyquist.h:240
wxString mInputCmd
Definition: Nyquist.h:243
bool mExternal
Definition: Nyquist.h:233
bool mIsTool
Definition: Nyquist.h:235
wxString mParameters
Definition: Nyquist.h:244
EffectType mPromptType
Definition: Nyquist.h:261

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

1192{
1193 return mDebugButton;
1194}
bool mDebugButton
Definition: Nyquist.h:264

References mDebugButton.

◆ EscapeString()

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

Definition at line 1788 of file Nyquist.cpp.

1789{
1790 wxString str = inStr;
1791
1792 str.Replace(wxT("\\"), wxT("\\\\"));
1793 str.Replace(wxT("\""), wxT("\\\""));
1794
1795 return str;
1796}
#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 1972 of file Nyquist.cpp.

1973{
1974 /* For this to work correctly requires that the plug-in header is
1975 * parsed on each run so that the correct value for "half-srate" may
1976 * be determined.
1977 *
1978 auto project = FindProject();
1979 if (project && s.IsSameAs(wxT("half-srate"), false)) {
1980 auto rate =
1981 TrackList::Get( *project ).Selected< const WaveTrack >()
1982 .min( &WaveTrack::GetRate );
1983 return (rate / 2.0);
1984 }
1985 */
1986
1988}
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:255

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:132

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistEffect::GetNyquistSearchPath ( )
staticprivate

Definition at line 2694 of file Nyquist.cpp.

2695{
2696 const auto &audacityPathList = FileNames::AudacityPathList();
2697 FilePaths pathList;
2698
2699 for (size_t i = 0; i < audacityPathList.size(); i++)
2700 {
2701 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2702 FileNames::AddUniquePathToPathList(prefix + wxT("nyquist"), pathList);
2703 FileNames::AddUniquePathToPathList(prefix + wxT("plugins"), pathList);
2704 FileNames::AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList);
2705 }
2706 pathList.push_back(FileNames::PlugInDir());
2707
2708 return pathList;
2709}
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:222

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:246

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:250

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:254
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:259

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:94
double mF1
Definition: EffectBase.h:95
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:234
bool mEnablePreview
Definition: Nyquist.h:263
int mVersion
Definition: Nyquist.h:272
TranslatableString mPromptName
Definition: Nyquist.h:247
wxDateTime mFileModified
When the script was last modified on disk.
Definition: Nyquist.h:223
sampleCount mMaxLen
Definition: Nyquist.h:275
void ParseFile()
Definition: Nyquist.cpp:2540
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 162 of file Nyquist.h.

162{ return mInitError; }
TranslatableString mInitError
Definition: Nyquist.h:242

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

3106{
3107 return mOK;
3108}

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:47
An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class.
Definition: Nyquist.h:78
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:256

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

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

Definition at line 1775 of file Nyquist.cpp.

1776{
1777 wxString str(nyqString, wxConvUTF8);
1778 if (nyqString != NULL && nyqString[0] && str.empty()) {
1779 // invalid UTF-8 string, convert as Latin-1
1780 str = _("[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1781 // TODO: internationalization of strings from Nyquist effects, at least
1782 // from those shipped with Audacity
1783 str += LAT1CTOWX(nyqString);
1784 }
1785 return str;
1786}
#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 3214 of file Nyquist.cpp.

3215{
3216 mControls[evt.GetId() - ID_Choice].val = (double) evt.GetInt();
3217}

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3250 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

3426{
3427 int i = evt.GetId() - ID_Text;
3428
3429 NyqControl & ctrl = mControls[i];
3430
3431 if (wxDynamicCast(evt.GetEventObject(), wxWindow)->GetValidator()->TransferFromWindow())
3432 {
3433 if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_INT)
3434 {
3435 int pos = (int)floor((ctrl.val - ctrl.low) /
3436 (ctrl.high - ctrl.low) * ctrl.ticks + 0.5);
3437
3438 wxSlider *slider = (wxSlider *)mUIParent->FindWindow(ID_Slider + i);
3439 slider->SetValue(pos);
3440 }
3441 }
3442}

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

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

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

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

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2648 of file Nyquist.cpp.

2649{
2650 // Always collect Nyquist error messages for normal plug-ins
2651 if (!mRedirectOutput) {
2652 mDebugOutputStr += (wxChar)c;
2653 return;
2654 }
2655
2656 std::cout << (char)c;
2657}
bool mRedirectOutput
Definition: Nyquist.h:267
wxString mDebugOutputStr
Definition: Nyquist.h:269

References mDebugOutputStr, and mRedirectOutput.

◆ Parse()

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

Definition at line 2089 of file Nyquist.cpp.

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

1799{
1800 std::vector<EnumValueSymbol> results;
1801 if (text[0] == wxT('(')) {
1802 // New style: expecting a Lisp-like list of strings
1803 Tokenizer tzer;
1804 tzer.Tokenize(text, true, 1, 1);
1805 auto &choices = tzer.tokens;
1806 wxString extra;
1807 for (auto &choice : choices) {
1808 auto label = UnQuote(choice, true, &extra);
1809 if (extra.empty())
1810 results.push_back( TranslatableString{ label, {} } );
1811 else
1812 results.push_back(
1813 { extra, TranslatableString{ label, {} } } );
1814 }
1815 }
1816 else {
1817 // Old style: expecting a comma-separated list of
1818 // un-internationalized names, ignoring leading and trailing spaces
1819 // on each; and the whole may be quoted
1820 auto choices = wxStringTokenize(
1821 text[0] == wxT('"') ? text.Mid(1, text.length() - 2) : text,
1822 wxT(",")
1823 );
1824 for (auto &choice : choices)
1825 results.push_back( { choice.Trim(true).Trim(false) } );
1826 }
1827 return results;
1828}
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 2548 of file Nyquist.cpp.

2549{
2550 wxStringInputStream stream(cmd + wxT(" "));
2551
2552 return ParseProgram(stream);
2553}
bool ParseProgram(wxInputStream &stream)
Definition: Nyquist.cpp:2442

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

2541{
2542 wxFileInputStream rawStream(mFileName.GetFullPath());
2543 wxBufferedInputStream stream(rawStream, 10000);
2544
2545 ParseProgram(stream);
2546}

References mFileName, and ParseProgram().

Here is the call graph for this function:

◆ ParseFileExtensions()

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

Definition at line 1830 of file Nyquist.cpp.

1831{
1832 // todo: error handling
1833 FileExtensions results;
1834 if (text[0] == wxT('(')) {
1835 Tokenizer tzer;
1836 tzer.Tokenize(text, true, 1, 1);
1837 for (const auto &token : tzer.tokens)
1838 results.push_back( UnQuote( token ) );
1839 }
1840 return results;
1841}

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

1844{
1845 // todo: error handling
1846 FileNames::FileType result;
1847 if (text[0] == wxT('(')) {
1848 Tokenizer tzer;
1849 tzer.Tokenize(text, true, 1, 1);
1850 auto &tokens = tzer.tokens;
1851 if ( tokens.size() == 2 )
1852 result =
1853 { UnQuoteMsgid( tokens[0] ), ParseFileExtensions( tokens[1] ) };
1854 }
1855 return result;
1856}
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1925
FileExtensions ParseFileExtensions(const wxString &text)
Definition: Nyquist.cpp:1830

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

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

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

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

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

1182{
1183 mUIParent = S.GetParent();
1184 if (mIsPrompt)
1186 else
1188 return nullptr;
1189}
void BuildEffectWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2945
void BuildPromptWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2913

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->Channels().begin()).get();
941 mCurNumChannels = 1;
942 if ( (mT1 >= mT0) || bOnePassTool ) {
943 if (bOnePassTool) {
944 }
945 else {
946 if (auto channels = mCurChannelGroup->Channels()
947 ; channels.size() > 1
948 ) {
949 // TODO: more-than-two-channels
950 // Pay attention to consistency of mNumSelectedChannels
951 // with the running tally made by this loop!
952 mCurNumChannels = 2;
953
954 mCurTrack[1] = (* ++ channels.first).get();
955 }
956
957 // Check whether we're in the same group as the last selected track
958 Track *gt = *SyncLock::Group(*mCurChannelGroup).first;
959 mFirstInGroup = !gtLast || (gtLast != gt);
960 gtLast = gt;
961
962 mCurStart = mCurChannelGroup->TimeToLongSamples(mT0);
963 auto end = mCurChannelGroup->TimeToLongSamples(mT1);
964 mCurLen = end - mCurStart;
965
966 wxASSERT(mCurLen <= NYQ_MAX_LEN);
967
968 mCurLen = std::min(mCurLen, mMaxLen);
969 }
970
971 // libnyquist breaks except in LC_NUMERIC=="C".
972 //
973 // Note that we must set the locale to "C" even before calling
974 // nyx_init() because otherwise some effects will not work!
975 //
976 // MB: setlocale is not thread-safe. Should use uselocale()
977 // if available, or fix libnyquist to be locale-independent.
978 // See also http://bugzilla.audacityteam.org/show_bug.cgi?id=642#c9
979 // for further info about this thread safety question.
980 wxString prevlocale = wxSetlocale(LC_NUMERIC, NULL);
981 wxSetlocale(LC_NUMERIC, wxString(wxT("C")));
982
983 nyx_init();
984 nyx_set_os_callback(StaticOSCallback, (void *)this);
985 nyx_capture_output(StaticOutputCallback, (void *)this);
986
987 auto cleanup = finally( [&] {
988 nyx_capture_output(NULL, (void *)NULL);
989 nyx_set_os_callback(NULL, (void *)NULL);
990 nyx_cleanup();
991 } );
992
993
994 if (mVersion >= 4)
995 {
996 mPerTrackProps = wxEmptyString;
997 wxString lowHz = wxT("nil");
998 wxString highHz = wxT("nil");
999 wxString centerHz = wxT("nil");
1000 wxString bandwidth = wxT("nil");
1001
1002 if (mF0 >= 0.0) {
1003 lowHz.Printf(wxT("(float %s)"), Internat::ToString(mF0));
1004 }
1005
1006 if (mF1 >= 0.0) {
1007 highHz.Printf(wxT("(float %s)"), Internat::ToString(mF1));
1008 }
1009
1010 if ((mF0 >= 0.0) && (mF1 >= 0.0)) {
1011 centerHz.Printf(wxT("(float %s)"), Internat::ToString(sqrt(mF0 * mF1)));
1012 }
1013
1014 if ((mF0 > 0.0) && (mF1 >= mF0)) {
1015 // with very small values, bandwidth calculation may be inf.
1016 // (Observed on Linux)
1017 double bw = log(mF1 / mF0) / log(2.0);
1018 if (!std::isinf(bw)) {
1019 bandwidth.Printf(wxT("(float %s)"), Internat::ToString(bw));
1020 }
1021 }
1022
1023 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'LOW-HZ)\n"), lowHz);
1024 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'CENTER-HZ)\n"), centerHz);
1025 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'HIGH-HZ)\n"), highHz);
1026 mPerTrackProps += wxString::Format(wxT("(putprop '*SELECTION* %s 'BANDWIDTH)\n"), bandwidth);
1027
1028 const auto t0 =
1029 mCurChannelGroup ? mCurChannelGroup->SnapToSample(mT0) : mT0;
1030 const auto t1 =
1031 mCurChannelGroup ? mCurChannelGroup->SnapToSample(mT1) : mT1;
1032 mPerTrackProps += wxString::Format(
1033 wxT("(putprop '*SELECTION* (float %s) 'START)\n"),
1034 Internat::ToString(t0));
1035 mPerTrackProps += wxString::Format(
1036 wxT("(putprop '*SELECTION* (float %s) 'END)\n"),
1037 Internat::ToString(t1));
1038 }
1039
1040 success = ProcessOne(nyxContext, oOutputs ? &*oOutputs : nullptr);
1041
1042 // Reset previous locale
1043 wxSetlocale(LC_NUMERIC, prevlocale);
1044
1045 if (!success || bOnePassTool) {
1046 goto finish;
1047 }
1048 progressTot += nyxContext.mProgressIn + nyxContext.mProgressOut;
1049 }
1050
1051 mCount += mCurNumChannels;
1052 }
1053
1054 if (mOutputTime > 0.0) {
1055 mT1 = mT0 + mOutputTime;
1056 }
1057
1058finish:
1059
1060 // Show debug window if trace set in plug-in header and something to show.
1061 mDebug = (mTrace && !mDebugOutput.Translation().empty())? true : mDebug;
1062
1063 if (mDebug && !mRedirectOutput) {
1064 NyquistOutputDialog dlog(nullptr, -1,
1065 mName,
1066 XO("Debug Output: "),
1067 mDebugOutput);
1068 dlog.CentreOnParent();
1069 dlog.ShowModal();
1070 }
1071
1072 // Has rug been pulled from under us by some effect done within Nyquist??
1073 if (!bOnePassTool && (nEffectsSoFar == EffectOutputTracks::nEffectsDone)) {
1074 if (success)
1075 oOutputs->Commit();
1076 }
1077 else {
1078 // Do not use the results.
1079 // Selection is to be set to whatever it is in the project.
1080 auto project = FindProject();
1081 if (project) {
1082 auto &selectedRegion = ViewInfo::Get( *project ).selectedRegion;
1083 mT0 = selectedRegion.t0();
1084 mT1 = selectedRegion.t1();
1085 }
1086 else {
1087 mT0 = 0;
1088 mT1 = -1;
1089 }
1090
1091 }
1092
1093 if (!mProjectChanged)
1094 em.SetSkipStateFlag(true);
1095
1096 return success;
1097}
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:3612
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
size_t size() const
Definition: Project.cpp:17
double mT1
Definition: EffectBase.h:114
bool IsPreviewing() const
Definition: EffectBase.h:89
std::shared_ptr< TrackList > mTracks
Definition: EffectBase.h:107
double mT0
Definition: EffectBase.h:113
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:48
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:95
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:78
TranslatableString mDebugOutput
Definition: Nyquist.h:270
bool ProcessOne(NyxContext &nyxContext, EffectOutputTracks *pOutputs)
Definition: Nyquist.cpp:1270
static void StaticOSCallback(void *userdata)
Definition: Nyquist.cpp:2659
static void StaticOutputCallback(int c, void *userdata)
Definition: Nyquist.cpp:2643
EffectType GetType() const override
Type determines how it behaves.
Definition: Nyquist.cpp:277
wxString mPerTrackProps
Definition: Nyquist.h:285
static int mReentryCount
Definition: Nyquist.h:146
unsigned mNumSelectedChannels
Definition: Nyquist.h:280
bool mProjectChanged
Definition: Nyquist.h:268
bool mFirstInGroup
Definition: Nyquist.h:277
wxString EscapeString(const wxString &inStr)
Definition: Nyquist.cpp:1788
wxString mProps
Definition: Nyquist.h:284
int mTrackIndex
Definition: Nyquist.h:276
double mOutputTime
Definition: Nyquist.h:278
unsigned mCount
Definition: Nyquist.h:279
Dialog used with NyquistEffect.
Definition: Nyquist.h:298
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:215
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
size_t NChannels() const override
A constant property.
Definition: WaveTrack.cpp:532
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:201
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
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(), BasicUI::Get(), EffectManager::Get(), ProjectRate::Get(), ViewInfo::Get(), TrackList::Get(), 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 1270 of file Nyquist.cpp.

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

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

1897{
1898 mRedirectOutput = true;
1899}

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

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

1902{
1903 mExternal = true;
1904
1905 if (cmd.size()) {
1906 ParseCommand(cmd);
1907 }
1908}

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

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

2660{
2661 ((NyquistEffect *)This)->OSCallback();
2662}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2643 of file Nyquist.cpp.

2644{
2645 ((NyquistEffect *)This)->OutputCallback(c);
2646}

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1920 of file Nyquist.cpp.

1921{
1922 mStop = true;
1923}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3415 of file Nyquist.cpp.

3416{
3417 int seconds = static_cast<int>(t);
3418 int hh = seconds / 3600;
3419 int mm = seconds % 3600;
3420 mm = mm / 60;
3421 return wxString::Format("%d:%d:%.3f", hh, mm, t - (hh * 3600 + mm * 60));
3422}

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2773 of file Nyquist.cpp.

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

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

2756{
2757 mInputCmd = mCommandText->GetValue();
2758
2759 // Un-correct smart quoting, bothersomely applied in wxTextCtrl by
2760 // the native widget of MacOS 10.9 SDK
2761 const wxString left = wxT("\u201c"), right = wxT("\u201d"), dumb = '"';
2762 mInputCmd.Replace(left, dumb, true);
2763 mInputCmd.Replace(right, dumb, true);
2764
2765 const wxString leftSingle = wxT("\u2018"), rightSingle = wxT("\u2019"),
2766 dumbSingle = '\'';
2767 mInputCmd.Replace(leftSingle, dumbSingle, true);
2768 mInputCmd.Replace(rightSingle, dumbSingle, true);
2769
2770 return ParseCommand(mInputCmd);
2771}

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

1219{
1220 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
1221 {
1222 return false;
1223 }
1224
1225 if (mIsPrompt)
1226 {
1228 }
1230}
bool TransferDataFromPromptWindow()
Definition: Nyquist.cpp:2755
bool TransferDataFromEffectWindow()
Definition: Nyquist.cpp:2773

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

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2718 of file Nyquist.cpp.

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

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

2712{
2713 mCommandText->ChangeValue(mInputCmd);
2714
2715 return true;
2716}

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

1197{
1198 mUIParent->TransferDataToWindow();
1199
1200 bool success;
1201 if (mIsPrompt)
1202 {
1203 success = TransferDataToPromptWindow();
1204 }
1205 else
1206 {
1207 success = TransferDataToEffectWindow();
1208 }
1209
1210 if (success)
1211 {
1213 }
1214
1215 return success;
1216}
static bool EnablePreview(wxWindow *parent, bool enable=true)
bool TransferDataToPromptWindow()
Definition: Nyquist.cpp:2711
bool TransferDataToEffectWindow()
Definition: Nyquist.cpp:2718

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

1968{
1969 return UnQuoteMsgid( s, allowParens, pExtraString ).Translation();
1970}

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

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

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

3405{
3406 wxFileName fname = path;
3407 wxString dir = fname.GetPath();
3408
3409 return (fname.wxFileName::IsOk() &&
3410 wxFileName::DirExists(dir) &&
3411 !fname.GetFullName().empty());
3412}

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

Member Data Documentation

◆ mAction

TranslatableString NyquistEffect::mAction
private

Definition at line 248 of file Nyquist.h.

Referenced by Parse().

◆ mAuthor

TranslatableString NyquistEffect::mAuthor
private

Definition at line 250 of file Nyquist.h.

Referenced by GetVendor(), and Parse().

◆ mBreak

bool NyquistEffect::mBreak
private

Definition at line 226 of file Nyquist.h.

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

◆ mCategories

wxArrayString NyquistEffect::mCategories
private

Definition at line 282 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mCmd

wxString NyquistEffect::mCmd
private

Definition at line 245 of file Nyquist.h.

Referenced by ParseProgram(), and ProcessOne().

◆ mCommandText

wxTextCtrl* NyquistEffect::mCommandText
private

◆ mCompiler

bool NyquistEffect::mCompiler
private

Definition at line 230 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mCont

bool NyquistEffect::mCont
private

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

Referenced by GetDescription(), and Parse().

◆ mCount

unsigned NyquistEffect::mCount
private

Definition at line 279 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mDebug

bool NyquistEffect::mDebug
private

Definition at line 266 of file Nyquist.h.

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

◆ mDebugButton

bool NyquistEffect::mDebugButton
private

Definition at line 264 of file Nyquist.h.

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

◆ mDebugOutput

TranslatableString NyquistEffect::mDebugOutput
private

Definition at line 270 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mDebugOutputStr

wxString NyquistEffect::mDebugOutputStr
private

Definition at line 269 of file Nyquist.h.

Referenced by OutputCallback(), and Process().

◆ mEnablePreview

bool NyquistEffect::mEnablePreview
private

Definition at line 263 of file Nyquist.h.

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

◆ mExternal

bool NyquistEffect::mExternal
private

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

◆ mFileName

wxFileName NyquistEffect::mFileName
private

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

Definition at line 222 of file Nyquist.h.

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

◆ mFirstInGroup

bool NyquistEffect::mFirstInGroup
private

Definition at line 277 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mFoundType

bool NyquistEffect::mFoundType
private

Definition at line 229 of file Nyquist.h.

Referenced by Parse(), and ParseProgram().

◆ mHelpFile

wxString NyquistEffect::mHelpFile
private

Definition at line 257 of file Nyquist.h.

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

◆ mHelpFileExists

bool NyquistEffect::mHelpFileExists
private

Definition at line 258 of file Nyquist.h.

Referenced by ParseProgram(), and Process().

◆ mHelpPage

FilePath NyquistEffect::mHelpPage
private

Definition at line 259 of file Nyquist.h.

Referenced by HelpPage(), and ParseProgram().

◆ mInfo

TranslatableString NyquistEffect::mInfo
private

Definition at line 249 of file Nyquist.h.

Referenced by Parse().

◆ mInitError

TranslatableString NyquistEffect::mInitError
private

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

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

◆ mIsSpectral

bool NyquistEffect::mIsSpectral
private

Definition at line 234 of file Nyquist.h.

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

◆ mIsTool

bool NyquistEffect::mIsTool
private

Definition at line 235 of file Nyquist.h.

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

◆ mManPage

wxString NyquistEffect::mManPage
private

Definition at line 256 of file Nyquist.h.

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

◆ mMaxLen

sampleCount NyquistEffect::mMaxLen
private

Definition at line 275 of file Nyquist.h.

Referenced by Parse(), and Process().

◆ mMergeClips

int NyquistEffect::mMergeClips
private

Definition at line 288 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mName

TranslatableString NyquistEffect::mName
private

Name of the Effect (untranslated)

Definition at line 246 of file Nyquist.h.

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

◆ mNumSelectedChannels

unsigned NyquistEffect::mNumSelectedChannels
private

Definition at line 280 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mOK

bool NyquistEffect::mOK
private

Definition at line 241 of file Nyquist.h.

Referenced by IsOk(), and Parse().

◆ mOutputTime

double NyquistEffect::mOutputTime
private

Definition at line 278 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mParameters

wxString NyquistEffect::mParameters
private

Definition at line 244 of file Nyquist.h.

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

◆ mPerTrackProps

wxString NyquistEffect::mPerTrackProps
private

Definition at line 285 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mProjectChanged

bool NyquistEffect::mProjectChanged
private

Definition at line 268 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mPromptName

TranslatableString NyquistEffect::mPromptName
private

Definition at line 247 of file Nyquist.h.

Referenced by Init().

◆ mPromptType

EffectType NyquistEffect::mPromptType
private

Definition at line 261 of file Nyquist.h.

Referenced by DoLoadSettings(), and Init().

◆ mProps

wxString NyquistEffect::mProps
private

Definition at line 284 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mRedirectOutput

bool NyquistEffect::mRedirectOutput
private

Definition at line 267 of file Nyquist.h.

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

◆ mReentryCount

int NyquistEffect::mReentryCount = 0
staticprivate

Definition at line 146 of file Nyquist.h.

Referenced by Process().

◆ mReleaseVersion

TranslatableString NyquistEffect::mReleaseVersion
private

Definition at line 254 of file Nyquist.h.

Referenced by GetVersion(), and Parse().

◆ mRestoreSplits

bool NyquistEffect::mRestoreSplits
private

Definition at line 287 of file Nyquist.h.

Referenced by Parse(), and ProcessOne().

◆ mStop

bool NyquistEffect::mStop
private

Definition at line 225 of file Nyquist.h.

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

◆ mTrace

bool NyquistEffect::mTrace
private

Definition at line 231 of file Nyquist.h.

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

◆ mTrackIndex

int NyquistEffect::mTrackIndex
private

Definition at line 276 of file Nyquist.h.

Referenced by Process(), and ProcessOne().

◆ mType

EffectType NyquistEffect::mType
private

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

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

◆ mXlispPath

wxString NyquistEffect::mXlispPath
private

Definition at line 220 of file Nyquist.h.


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