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

1914{
1915 mBreak = true;
1916}
bool mBreak
Definition: Nyquist.h:226

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2948 of file Nyquist.cpp.

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

2917{
2918 S.StartVerticalLay();
2919 {
2920 S.StartMultiColumn(3, wxEXPAND);
2921 {
2922 S.SetStretchyCol(1);
2923
2924 S.AddVariableText(XO("Enter Nyquist Command: "));
2925
2926 S.AddSpace(1, 1);
2927 }
2928 S.EndMultiColumn();
2929
2930 S.StartHorizontalLay(wxEXPAND, 1);
2931 {
2932 mCommandText = S.Focus()
2933 .MinSize( { 500, 200 } )
2934 .AddTextWindow(wxT(""));
2935 }
2936 S.EndHorizontalLay();
2937
2938 S.StartHorizontalLay(wxALIGN_CENTER, 0);
2939 {
2940 S.Id(ID_Load).AddButton(XXO("&Load"));
2941 S.Id(ID_Save).AddButton(XXO("&Save"));
2942 }
2943 S.EndHorizontalLay();
2944 }
2945 S.EndVerticalLay();
2946}
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:2697

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

1919{
1920 mCont = true;
1921}
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:2551
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 1194 of file Nyquist.cpp.

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

References mDebugButton.

◆ EscapeString()

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

Definition at line 1791 of file Nyquist.cpp.

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

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

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

3109{
3110 return mOK;
3111}

References mOK.

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ LoadSettings()

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

Restore settings from keys and values.

Returns
true on success

Implements EffectSettingsManager.

Definition at line 424 of file Nyquist.cpp.

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

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

3218{
3219 mControls[evt.GetId() - ID_Choice].val = (double) evt.GetInt();
3220}

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3253 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2651 of file Nyquist.cpp.

2652{
2653 // Always collect Nyquist error messages for normal plug-ins
2654 if (!mRedirectOutput) {
2655 mDebugOutputStr += (wxChar)c;
2656 return;
2657 }
2658
2659 std::cout << (char)c;
2660}
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 2092 of file Nyquist.cpp.

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

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

2552{
2553 wxStringInputStream stream(cmd + wxT(" "));
2554
2555 return ParseProgram(stream);
2556}
bool ParseProgram(wxInputStream &stream)
Definition: Nyquist.cpp:2445

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

2544{
2545 wxFileInputStream rawStream(mFileName.GetFullPath());
2546 wxBufferedInputStream stream(rawStream, 10000);
2547
2548 ParseProgram(stream);
2549}

References mFileName, and ParseProgram().

Here is the call graph for this function:

◆ ParseFileExtensions()

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

Definition at line 1833 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

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

Here is the call graph for this function:

◆ Process()

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

Implements StatefulEffectBase.

Definition at line 710 of file Nyquist.cpp.

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

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

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

1900{
1901 mRedirectOutput = true;
1902}

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

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

1905{
1906 mExternal = true;
1907
1908 if (cmd.size()) {
1909 ParseCommand(cmd);
1910 }
1911}

References mExternal, and ParseCommand().

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

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

◆ SetLispVarsFromParameters()

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

Definition at line 497 of file Nyquist.cpp.

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

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

Referenced by DoLoadSettings().

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

◆ ShowHostInterface()

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

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

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

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

Reimplemented from EffectUIServices.

Definition at line 1102 of file Nyquist.cpp.

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

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

Referenced by ShowHostInterface().

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

◆ StaticOSCallback()

void NyquistEffect::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2662 of file Nyquist.cpp.

2663{
2664 ((NyquistEffect *)This)->OSCallback();
2665}

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2646 of file Nyquist.cpp.

2647{
2648 ((NyquistEffect *)This)->OutputCallback(c);
2649}

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1923 of file Nyquist.cpp.

1924{
1925 mStop = true;
1926}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3418 of file Nyquist.cpp.

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

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2776 of file Nyquist.cpp.

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

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

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

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

Referenced by TransferDataFromWindow().

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

◆ TransferDataFromWindow()

bool NyquistEffect::TransferDataFromWindow ( EffectSettings settings)
overridevirtual

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

Reimplemented from StatefulEffectUIServices.

Definition at line 1221 of file Nyquist.cpp.

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

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

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2721 of file Nyquist.cpp.

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

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

2715{
2716 mCommandText->ChangeValue(mInputCmd);
2717
2718 return true;
2719}

References mCommandText, and mInputCmd.

Referenced by TransferDataToWindow().

Here is the caller graph for this function:

◆ TransferDataToWindow()

bool NyquistEffect::TransferDataToWindow ( const EffectSettings settings)
overridevirtual

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

Reimplemented from StatefulEffectUIServices.

Definition at line 1199 of file Nyquist.cpp.

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

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

1971{
1972 return UnQuoteMsgid( s, allowParens, pExtraString ).Translation();
1973}

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

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

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

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

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: