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

202{
203}

Member Function Documentation

◆ Break()

void NyquistEffect::Break ( )

Definition at line 1911 of file Nyquist.cpp.

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

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2949 of file Nyquist.cpp.

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

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

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

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

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

References mCont.

◆ DoLoadSettings()

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

Definition at line 430 of file Nyquist.cpp.

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

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

References mDebugButton.

◆ EscapeString()

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

Definition at line 1789 of file Nyquist.cpp.

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

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

References EffectTypeTool, mIsTool, and mType.

◆ GetCtrlValue()

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

Definition at line 1973 of file Nyquist.cpp.

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

241{
242 return mCopyright;
243}
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 288 of file Nyquist.cpp.

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

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistEffect::GetNyquistSearchPath ( )
staticprivate

Definition at line 2698 of file Nyquist.cpp.

2699{
2700 const auto &audacityPathList = FileNames::AudacityPathList();
2701 FilePaths pathList;
2702
2703 for (size_t i = 0; i < audacityPathList.size(); i++)
2704 {
2705 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2706 FileNames::AddUniquePathToPathList(prefix + wxT("nyquist"), pathList);
2707 FileNames::AddUniquePathToPathList(prefix + wxT("plugins"), pathList);
2708 FileNames::AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList);
2709 }
2710 pathList.push_back(FileNames::PlugInDir());
2711
2712 return pathList;
2713}
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
FILES_API FilePath PlugInDir()
The user plug-in directory (not a system one)
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...

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

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

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

◆ GetPath()

PluginPath NyquistEffect::GetPath ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 207 of file Nyquist.cpp.

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

References mFileName, mIsPrompt, and NYQUIST_PROMPT_ID.

◆ GetSymbol()

ComponentInterfaceSymbol NyquistEffect::GetSymbol ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 215 of file Nyquist.cpp.

216{
217 if (mIsPrompt)
219
220 return mName;
221}
#define NYQUIST_PROMPT_NAME
TranslatableString mName
Name of the Effect (untranslated)
Definition: Nyquist.h: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 276 of file Nyquist.cpp.

277{
278 return mType;
279}

References mType.

Referenced by Process(), and ProcessOne().

Here is the caller graph for this function:

◆ GetVendor()

VendorSymbol NyquistEffect::GetVendor ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 223 of file Nyquist.cpp.

224{
225 if (mIsPrompt)
226 {
227 return XO("Audacity");
228 }
229
230 return mAuthor;
231}
TranslatableString mAuthor
Definition: Nyquist.h: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 233 of file Nyquist.cpp.

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

270{
271 return mHelpPage;
272}
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 565 of file Nyquist.cpp.

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

References EffectUIServices::DoMessageBox(), WaveChannelView::Find(), EffectBase::FindProject(), TrackList::Get(), SpectrogramSettings::Get(), mDebugButton, mEnablePreview, 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 303 of file Nyquist.cpp.

304{
305 return mIsPrompt;
306}

References mIsPrompt.

◆ IsInteractive()

bool NyquistEffect::IsInteractive ( ) const
overridevirtual

Whether the effect needs a dialog for entry of settings.

Implements EffectDefinitionInterface.

Definition at line 293 of file Nyquist.cpp.

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

References mControls, and mIsPrompt.

◆ IsOk()

bool NyquistEffect::IsOk ( )
private

Definition at line 3109 of file Nyquist.cpp.

3110{
3111 return mOK;
3112}

References mOK.

Referenced by NyquistEffectsModule::DiscoverPluginsAtPath().

Here is the caller graph for this function:

◆ LoadSettings()

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

Restore settings from keys and values.

Returns
true on success

Implements EffectSettingsManager.

Definition at line 423 of file Nyquist.cpp.

425{
426 // To do: externalize state so const_cast isn't needed
427 return const_cast<NyquistEffect*>(this)->DoLoadSettings(parms, settings);
428}
static Settings & settings()
Definition: TrackInfo.cpp:69
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:430

References DoLoadSettings(), and settings().

Referenced by ShowHostInterface(), and VisitSettings().

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

◆ ManualPage()

ManualPageID NyquistEffect::ManualPage ( ) const
overridevirtual

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

Reimplemented from EffectDefinitionInterface.

Definition at line 245 of file Nyquist.cpp.

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

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

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

Definition at line 1776 of file Nyquist.cpp.

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

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

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3254 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2652 of file Nyquist.cpp.

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

2092{
2093 if ( !tzer.Tokenize(line, eof, first ? 1 : 0, 0) )
2094 return false;
2095
2096 const auto &tokens = tzer.tokens;
2097 int len = tokens.size();
2098 if (len < 1) {
2099 return true;
2100 }
2101
2102 // Consistency decision is for "plug-in" as the correct spelling
2103 // "plugin" (deprecated) is allowed as an undocumented convenience.
2104 if (len == 2 && tokens[0] == wxT("nyquist") &&
2105 (tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin"))) {
2106 mOK = true;
2107 return true;
2108 }
2109
2110 if (len >= 2 && tokens[0] == wxT("type")) {
2111 wxString tok = tokens[1];
2112 mIsTool = false;
2113 if (tok == wxT("tool")) {
2114 mIsTool = true;
2116 // we allow
2117 // ;type tool
2118 // ;type tool process
2119 // ;type tool generate
2120 // ;type tool analyze
2121 // The last three are placed in the tool menu, but are processed as
2122 // process, generate or analyze.
2123 if (len >= 3)
2124 tok = tokens[2];
2125 }
2126
2127 if (tok == wxT("process")) {
2129 }
2130 else if (tok == wxT("generate")) {
2132 }
2133 else if (tok == wxT("analyze")) {
2135 }
2136
2137 if (len >= 3 && tokens[2] == wxT("spectral")) {;
2138 mIsSpectral = true;
2139 }
2140 return true;
2141 }
2142
2143 if (len == 2 && tokens[0] == wxT("codetype")) {
2144 // This will stop ParseProgram() from doing a best guess as program type.
2145 if (tokens[1] == wxT("lisp")) {
2146 mIsSal = false;
2147 mFoundType = true;
2148 }
2149 else if (tokens[1] == wxT("sal")) {
2150 mIsSal = true;
2151 mFoundType = true;
2152 }
2153 return true;
2154 }
2155
2156 if (len >= 2 && tokens[0] == wxT("debugflags")) {
2157 for (int i = 1; i < len; i++) {
2158 // "trace" sets *tracenable* (LISP) or *sal-traceback* (SAL)
2159 // and displays debug window IF there is anything to show.
2160 if (tokens[i] == wxT("trace")) {
2161 mTrace = true;
2162 }
2163 else if (tokens[i] == wxT("notrace")) {
2164 mTrace = false;
2165 }
2166 else if (tokens[i] == wxT("compiler")) {
2167 mCompiler = true;
2168 }
2169 else if (tokens[i] == wxT("nocompiler")) {
2170 mCompiler = false;
2171 }
2172 }
2173 return true;
2174 }
2175
2176 // We support versions 1, 2 and 3
2177 // (Version 2 added support for string parameters.)
2178 // (Version 3 added support for choice parameters.)
2179 // (Version 4 added support for project/track/selection information.)
2180 if (len >= 2 && tokens[0] == wxT("version")) {
2181 long v;
2182 tokens[1].ToLong(&v);
2183 if (v < 1 || v > 4) {
2184 // This is an unsupported plug-in version
2185 mOK = false;
2186 mInitError = XO(
2187"This version of Audacity does not support Nyquist plug-in version %ld")
2188 .Format( v );
2189 return true;
2190 }
2191 mVersion = (int) v;
2192 }
2193
2194 if (len >= 2 && tokens[0] == wxT("name")) {
2195 // Names do not yet support context strings for translations, or
2196 // internal names distinct from visible English names.
2197 // (See also comments in NyquistEffectsModule::AutoRegisterPlugins)
2198 auto name = UnQuote(tokens[1]);
2199 // Strip ... from name if it's present, perhaps in third party plug-ins
2200 // Menu system puts ... back if there are any controls
2201 // This redundant naming convention must NOT be followed for
2202 // shipped Nyquist effects with internationalization. Else the msgid
2203 // later looked up will lack the ... and will not be found.
2204 if (name.EndsWith(wxT("...")))
2205 name = name.RemoveLast(3);
2206 mName = TranslatableString{ name, {} };
2207 return true;
2208 }
2209
2210 if (len >= 2 && tokens[0] == wxT("action")) {
2211 mAction = TranslatableString{ UnQuote(tokens[1]), {} };
2212 return true;
2213 }
2214
2215 if (len >= 2 && tokens[0] == wxT("info")) {
2216 mInfo = TranslatableString{ UnQuote(tokens[1]), {} };
2217 return true;
2218 }
2219
2220 if (len >= 2 && tokens[0] == wxT("preview")) {
2221 if (tokens[1] == wxT("enabled") || tokens[1] == wxT("true")) {
2222 mEnablePreview = true;
2223 SetLinearEffectFlag(false);
2224 }
2225 else if (tokens[1] == wxT("linear")) {
2226 mEnablePreview = true;
2227 SetLinearEffectFlag(true);
2228 }
2229 else if (tokens[1] == wxT("selection")) {
2230 mEnablePreview = true;
2232 }
2233 else if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
2234 mEnablePreview = false;
2235 }
2236 return true;
2237 }
2238
2239 // Maximum number of samples to be processed. This can help the
2240 // progress bar if effect does not process all of selection.
2241 if (len >= 2 && tokens[0] == wxT("maxlen")) {
2242 long long v; // Note that Nyquist may overflow at > 2^31 samples (bug 439)
2243 tokens[1].ToLongLong(&v);
2244 mMaxLen = (sampleCount) v;
2245 }
2246
2247#if defined(EXPERIMENTAL_NYQUIST_SPLIT_CONTROL)
2248 if (len >= 2 && tokens[0] == wxT("mergeclips")) {
2249 long v;
2250 // -1 = auto (default), 0 = don't merge clips, 1 = do merge clips
2251 tokens[1].ToLong(&v);
2252 mMergeClips = v;
2253 return true;
2254 }
2255
2256 if (len >= 2 && tokens[0] == wxT("restoresplits")) {
2257 long v;
2258 // Splits are restored by default. Set to 0 to prevent.
2259 tokens[1].ToLong(&v);
2260 mRestoreSplits = !!v;
2261 return true;
2262 }
2263#endif
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:220
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:215
wxArrayString mPresetNames
Definition: EffectBase.h:99
wxString var
Definition: Nyquist.h:53
wxString lowStr
Definition: Nyquist.h:59
static double GetCtrlValue(const wxString &s)
Definition: Nyquist.cpp:1973
bool mRestoreSplits
Definition: Nyquist.h:287
bool mFoundType
Definition: Nyquist.h:229
FileNames::FileTypes ParseFileTypes(const wxString &text)
Definition: Nyquist.cpp:1859
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:1799
static wxString UnQuote(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1967
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 1799 of file Nyquist.cpp.

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

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

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

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

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

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

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:253
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
Definition: Nyquist.cpp:2090
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 1180 of file Nyquist.cpp.

1183{
1184 mUIParent = S.GetParent();
1185 if (mIsPrompt)
1187 else
1189 return nullptr;
1190}
void BuildEffectWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2949
void BuildPromptWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2917

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

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

References TrackList::Any(), FileNames::AudacityPathList(), FileNames::BaseDir(), FileNames::DataDir(), Effect::Delegate(), EffectUIServices::DoMessageBox(), EffectTypeProcess, EffectTypeTool, PackedArray::end(), EscapeString(), EffectBase::FindProject(), TranslatableString::Format(), BasicUI::Get(), EffectManager::Get(), ProjectRate::Get(), ViewInfo::Get(), TrackList::Get(), Effect::GetNumWaveGroups(), GetNyquistSearchPath(), 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, 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 1271 of file Nyquist.cpp.

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

1898{
1899 mRedirectOutput = true;
1900}

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

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

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

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

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

◆ SaveSettings()

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

Store settings as keys and values.

The override may assume parms is initially empty

Returns
true on success

Implements EffectSettingsManager.

Definition at line 372 of file Nyquist.cpp.

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

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

References mExternal, and ParseCommand().

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

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

◆ SetLispVarsFromParameters()

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

Definition at line 496 of file Nyquist.cpp.

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

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

Referenced by DoLoadSettings().

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

◆ ShowHostInterface()

int NyquistEffect::ShowHostInterface ( 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 1100 of file Nyquist.cpp.

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

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

Referenced by ShowHostInterface().

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

◆ StaticOSCallback()

void NyquistEffect::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2663 of file Nyquist.cpp.

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

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2647 of file Nyquist.cpp.

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

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1921 of file Nyquist.cpp.

1922{
1923 mStop = true;
1924}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3419 of file Nyquist.cpp.

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

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2777 of file Nyquist.cpp.

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

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

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

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

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

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

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2722 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

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

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

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

Referenced by TransferDataFromEffectWindow().

Here is the caller graph for this function:

◆ VisitSettings() [1/2]

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

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

Reimplemented from EffectSettingsManager.

Definition at line 316 of file Nyquist.cpp.

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

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

Here is the call graph for this function:

◆ VisitSettings() [2/2]

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

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

Reimplemented from EffectSettingsManager.

Definition at line 308 of file Nyquist.cpp.

310{
311 if (auto pSa = dynamic_cast<ShuttleSetAutomation*>(&visitor))
312 LoadSettings(*pSa->mpEap, settings);
313 return true;
314}
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
Definition: Nyquist.cpp:423
SettingsVisitor that sets parameters to a value (from a string)

References LoadSettings(), and settings().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ NyquistEffectsModule

friend class NyquistEffectsModule
friend

Definition at line 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: