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
 
EffectType GetType () const override
 Type determines how it behaves. More...
 
EffectFamilySymbol GetFamily () const override
 Report identifier and user-visible name of the effect protocol. More...
 
bool IsInteractive () const override
 Whether the effect needs a dialog for entry of settings. More...
 
bool IsDefault () const override
 Whether the effect sorts "above the line" in the menus. More...
 
RealtimeSince RealtimeSupport () const override
 Since which version of Audacity has the effect supported realtime? More...
 
bool SupportsAutomation () const override
 Whether the effect has any automatable controls. More...
 
bool SaveSettings (const EffectSettings &settings, CommandParameters &parms) const override
 Store settings as keys and values. More...
 
bool LoadSettings (const CommandParameters &parms, EffectSettings &settings) const override
 Restore settings from keys and values. More...
 
OptionalMessage LoadUserPreset (const RegistryPath &name, EffectSettings &settings) const override
 
bool SaveUserPreset (const RegistryPath &name, const EffectSettings &settings) const override
 Save settings in the configuration file as a user-named preset. More...
 
RegistryPaths GetFactoryPresets () const override
 Report names of factory presets. More...
 
OptionalMessage LoadFactoryPreset (int id, EffectSettings &settings) const override
 
OptionalMessage LoadFactoryDefaults (EffectSettings &settings) const override
 
virtual const EffectParameterMethodsParameters () const
 
bool CanExportPresets () const override
 Whether the effect supports export of presets to files, and importing too. More...
 
bool HasOptions () const override
 
const EffectSettingsManagerGetDefinition () const override
 
virtual NumericFormatSymbol GetSelectionFormat ()
 
bool SaveSettingsAsString (const EffectSettings &settings, wxString &parms) const override
 
OptionalMessage LoadSettingsFromString (const wxString &parms, EffectSettings &settings) const override
 
bool IsBatchProcessing () const override
 
void SetBatchProcessing () override
 
void UnsetBatchProcessing () override
 
unsigned TestUIFlags (unsigned mask)
 
bool Delegate (Effect &delegate, EffectSettings &settings, 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 200 of file Nyquist.cpp.

201{
202}

Member Function Documentation

◆ Break()

void NyquistEffect::Break ( )

Definition at line 1875 of file Nyquist.cpp.

1876{
1877 mBreak = true;
1878}
bool mBreak
Definition: Nyquist.h:226

References mBreak.

◆ BuildEffectWindow()

void NyquistEffect::BuildEffectWindow ( ShuttleGui S)
private

Definition at line 2913 of file Nyquist.cpp.

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

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

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

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

1881{
1882 mCont = true;
1883}
bool mCont
Definition: Nyquist.h:227

References mCont.

◆ DoLoadSettings()

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

Definition at line 429 of file Nyquist.cpp.

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

1184{
1185 return mDebugButton;
1186}
bool mDebugButton
Definition: Nyquist.h:264

References mDebugButton.

◆ EscapeString()

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

Definition at line 1753 of file Nyquist.cpp.

1754{
1755 wxString str = inStr;
1756
1757 str.Replace(wxT("\\"), wxT("\\\\"));
1758 str.Replace(wxT("\""), wxT("\\\""));
1759
1760 return str;
1761}
#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 280 of file Nyquist.cpp.

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

References EffectTypeTool, mIsTool, and mType.

◆ GetCtrlValue()

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

Definition at line 1937 of file Nyquist.cpp.

1938{
1939 /* For this to work correctly requires that the plug-in header is
1940 * parsed on each run so that the correct value for "half-srate" may
1941 * be determined.
1942 *
1943 auto project = FindProject();
1944 if (project && s.IsSameAs(wxT("half-srate"), false)) {
1945 auto rate =
1946 TrackList::Get( *project ).Selected< const WaveTrack >()
1947 .min( &WaveTrack::GetRate );
1948 return (rate / 2.0);
1949 }
1950 */
1951
1953}
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:133

References Internat::CompatibleToDouble().

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

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

◆ GetDescription()

TranslatableString NyquistEffect::GetDescription ( ) const
overridevirtual

Implements ComponentInterface.

Definition at line 239 of file Nyquist.cpp.

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

288{
290}
#define NYQUISTEFFECTS_FAMILY
Definition: EffectBase.h:134

References NYQUISTEFFECTS_FAMILY.

◆ GetNyquistSearchPath()

FilePaths NyquistEffect::GetNyquistSearchPath ( )
staticprivate

Definition at line 2662 of file Nyquist.cpp.

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

207{
208 if (mIsPrompt)
209 return NYQUIST_PROMPT_ID;
210
211 return mFileName.GetFullPath();
212}
#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 214 of file Nyquist.cpp.

215{
216 if (mIsPrompt)
218
219 return mName;
220}
#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 275 of file Nyquist.cpp.

276{
277 return mType;
278}

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

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

233{
234 // Are Nyquist version strings really supposed to be translatable?
235 // See commit a06e561 which used XO for at least one of them
237}
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 268 of file Nyquist.cpp.

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

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

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

303{
304 return mIsPrompt;
305}

References mIsPrompt.

◆ IsInteractive()

bool NyquistEffect::IsInteractive ( ) const
overridevirtual

Whether the effect needs a dialog for entry of settings.

Implements EffectDefinitionInterface.

Definition at line 292 of file Nyquist.cpp.

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

References mControls, and mIsPrompt.

◆ IsOk()

bool NyquistEffect::IsOk ( )
private

Definition at line 3073 of file Nyquist.cpp.

3074{
3075 return mOK;
3076}

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

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

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

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

References mIsPrompt, and mManPage.

◆ NyquistToWxString()

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

Definition at line 1740 of file Nyquist.cpp.

1741{
1742 wxString str(nyqString, wxConvUTF8);
1743 if (nyqString != NULL && nyqString[0] && str.empty()) {
1744 // invalid UTF-8 string, convert as Latin-1
1745 str = _("[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1746 // TODO: internationalization of strings from Nyquist effects, at least
1747 // from those shipped with Audacity
1748 str += LAT1CTOWX(nyqString);
1749 }
1750 return str;
1751}
#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 3182 of file Nyquist.cpp.

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

References ID_Choice, and mControls.

◆ OnDebug()

void NyquistEffect::OnDebug ( wxCommandEvent &  evt)
private

◆ OnFileButton()

void NyquistEffect::OnFileButton ( wxCommandEvent &  evt)
private

Definition at line 3218 of file Nyquist.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

References mBreak, mCont, and mStop.

◆ OutputCallback()

void NyquistEffect::OutputCallback ( int  c)
private

Definition at line 2616 of file Nyquist.cpp.

2617{
2618 // Always collect Nyquist error messages for normal plug-ins
2619 if (!mRedirectOutput) {
2620 mDebugOutputStr += (wxChar)c;
2621 return;
2622 }
2623
2624 std::cout << (char)c;
2625}
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 2054 of file Nyquist.cpp.

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

1764{
1765 std::vector<EnumValueSymbol> results;
1766 if (text[0] == wxT('(')) {
1767 // New style: expecting a Lisp-like list of strings
1768 Tokenizer tzer;
1769 tzer.Tokenize(text, true, 1, 1);
1770 auto &choices = tzer.tokens;
1771 wxString extra;
1772 for (auto &choice : choices) {
1773 auto label = UnQuote(choice, true, &extra);
1774 if (extra.empty())
1775 results.push_back( TranslatableString{ label, {} } );
1776 else
1777 results.push_back(
1778 { extra, TranslatableString{ label, {} } } );
1779 }
1780 }
1781 else {
1782 // Old style: expecting a comma-separated list of
1783 // un-internationalized names, ignoring leading and trailing spaces
1784 // on each; and the whole may be quoted
1785 auto choices = wxStringTokenize(
1786 text[0] == wxT('"') ? text.Mid(1, text.length() - 2) : text,
1787 wxT(",")
1788 );
1789 for (auto &choice : choices)
1790 results.push_back( { choice.Trim(true).Trim(false) } );
1791 }
1792 return results;
1793}
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 2515 of file Nyquist.cpp.

2516{
2517 wxStringInputStream stream(cmd + wxT(" "));
2518
2519 return ParseProgram(stream);
2520}
bool ParseProgram(wxInputStream &stream)
Definition: Nyquist.cpp:2409

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

2508{
2509 wxFileInputStream rawStream(mFileName.GetFullPath());
2510 wxBufferedInputStream stream(rawStream, 10000);
2511
2512 ParseProgram(stream);
2513}

References mFileName, and ParseProgram().

Here is the call graph for this function:

◆ ParseFileExtensions()

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

Definition at line 1795 of file Nyquist.cpp.

1796{
1797 // todo: error handling
1798 FileExtensions results;
1799 if (text[0] == wxT('(')) {
1800 Tokenizer tzer;
1801 tzer.Tokenize(text, true, 1, 1);
1802 for (const auto &token : tzer.tokens)
1803 results.push_back( UnQuote( token ) );
1804 }
1805 return results;
1806}

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

1809{
1810 // todo: error handling
1811 FileNames::FileType result;
1812 if (text[0] == wxT('(')) {
1813 Tokenizer tzer;
1814 tzer.Tokenize(text, true, 1, 1);
1815 auto &tokens = tzer.tokens;
1816 if ( tokens.size() == 2 )
1817 result =
1818 { UnQuoteMsgid( tokens[0] ), ParseFileExtensions( tokens[1] ) };
1819 }
1820 return result;
1821}
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
Definition: Nyquist.cpp:1890
FileExtensions ParseFileExtensions(const wxString &text)
Definition: Nyquist.cpp:1795

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

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

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

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

1174{
1175 mUIParent = S.GetParent();
1176 if (mIsPrompt)
1178 else
1180 return nullptr;
1181}
void BuildEffectWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2913
void BuildPromptWindow(ShuttleGui &S)
Definition: Nyquist.cpp:2881

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

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

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

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(), LabelTrack::GetDefaultName(), 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, TrackList::Temporary(), 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 1861 of file Nyquist.cpp.

1862{
1863 mRedirectOutput = true;
1864}

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

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

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

1867{
1868 mExternal = true;
1869
1870 if (cmd.size()) {
1871 ParseCommand(cmd);
1872 }
1873}

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

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

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

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

Referenced by ShowHostInterface().

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

◆ StaticOSCallback()

void NyquistEffect::StaticOSCallback ( void *  userdata)
staticprivate

Definition at line 2627 of file Nyquist.cpp.

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

Referenced by Process().

Here is the caller graph for this function:

◆ StaticOutputCallback()

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

Definition at line 2611 of file Nyquist.cpp.

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

Referenced by Process().

Here is the caller graph for this function:

◆ Stop()

void NyquistEffect::Stop ( )

Definition at line 1885 of file Nyquist.cpp.

1886{
1887 mStop = true;
1888}

References mStop.

Referenced by NyqBench::OnStop().

Here is the caller graph for this function:

◆ ToTimeFormat()

wxString NyquistEffect::ToTimeFormat ( double  t)
private

Definition at line 3383 of file Nyquist.cpp.

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

Referenced by OnTime().

Here is the caller graph for this function:

◆ TransferDataFromEffectWindow()

bool NyquistEffect::TransferDataFromEffectWindow ( )
private

Definition at line 2741 of file Nyquist.cpp.

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

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

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

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

1211{
1212 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
1213 {
1214 return false;
1215 }
1216
1217 if (mIsPrompt)
1218 {
1220 }
1222}
bool TransferDataFromPromptWindow()
Definition: Nyquist.cpp:2723
bool TransferDataFromEffectWindow()
Definition: Nyquist.cpp:2741

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

Here is the call graph for this function:

◆ TransferDataToEffectWindow()

bool NyquistEffect::TransferDataToEffectWindow ( )
private

Definition at line 2686 of file Nyquist.cpp.

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

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

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

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

1189{
1190 mUIParent->TransferDataToWindow();
1191
1192 bool success;
1193 if (mIsPrompt)
1194 {
1195 success = TransferDataToPromptWindow();
1196 }
1197 else
1198 {
1199 success = TransferDataToEffectWindow();
1200 }
1201
1202 if (success)
1203 {
1205 }
1206
1207 return success;
1208}
static bool EnablePreview(wxWindow *parent, bool enable=true)
bool TransferDataToPromptWindow()
Definition: Nyquist.cpp:2679
bool TransferDataToEffectWindow()
Definition: Nyquist.cpp:2686

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

1933{
1934 return UnQuoteMsgid( s, allowParens, pExtraString ).Translation();
1935}

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

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

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

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

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

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

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