1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 Nyquist.h 6 7 Dominic Mazzoni 8 9 **********************************************************************/ 10 11 #ifndef __AUDACITY_EFFECT_NYQUIST__ 12 #define __AUDACITY_EFFECT_NYQUIST__ 13 14 #include "../Effect.h" 15 #include "FileNames.h" 16 17 #include "nyx.h" 18 19 class wxArrayString; 20 class wxFileName; 21 class wxCheckBox; 22 class wxTextCtrl; 23 24 #define NYQUISTEFFECTS_VERSION wxT("1.0.0.0") 25 26 enum NyqControlType 27 { 28 NYQ_CTRL_INT, 29 NYQ_CTRL_FLOAT, 30 NYQ_CTRL_STRING, 31 NYQ_CTRL_CHOICE, 32 NYQ_CTRL_INT_TEXT, 33 NYQ_CTRL_FLOAT_TEXT, 34 NYQ_CTRL_TEXT, 35 NYQ_CTRL_TIME, 36 NYQ_CTRL_FILE, 37 }; 38 39 class NyqControl 40 { 41 public: 42 NyqControl() = default; 43 NyqControl( const NyqControl& ) = default; 44 NyqControl &operator = ( const NyqControl & ) = default; 45 //NyqControl( NyqControl && ) = default; 46 //NyqControl &operator = ( NyqControl && ) = default; 47 48 int type; 49 wxString var; 50 wxString name; 51 wxString label; 52 std::vector<EnumValueSymbol> choices; 53 FileNames::FileTypes fileTypes; 54 wxString valStr; 55 wxString lowStr; 56 wxString highStr; 57 double val; 58 double low; 59 double high; 60 int ticks; 61 }; 62 63 64 class AUDACITY_DLL_API NyquistEffect final : public Effect 65 { 66 public: 67 68 /** @param fName File name of the Nyquist script defining this effect. If 69 * an empty string, then prompt the user for the Nyquist code to interpret. 70 */ 71 NyquistEffect(const wxString &fName); 72 virtual ~NyquistEffect(); 73 74 // ComponentInterface implementation 75 76 PluginPath GetPath() override; 77 ComponentInterfaceSymbol GetSymbol() override; 78 VendorSymbol GetVendor() override; 79 wxString GetVersion() override; 80 TranslatableString GetDescription() override; 81 82 ManualPageID ManualPage() override; 83 FilePath HelpPage() override; 84 85 // EffectDefinitionInterface implementation 86 87 EffectType GetType() override; 88 EffectType GetClassification() override; 89 EffectFamilySymbol GetFamily() override; 90 bool IsInteractive() override; 91 bool IsDefault() override; 92 93 // EffectClientInterface implementation 94 95 bool DefineParams( ShuttleParams & S ) override; 96 bool GetAutomationParameters(CommandParameters & parms) override; 97 bool SetAutomationParameters(CommandParameters & parms) override; 98 int SetLispVarsFromParameters(CommandParameters & parms, bool bTestOnly); 99 100 // Effect implementation 101 102 bool Init() override; 103 bool CheckWhetherSkipEffect() override; 104 bool Process() override; 105 bool ShowInterface( wxWindow &parent, 106 const EffectDialogFactory &factory, bool forceModal = false) override; 107 void PopulateOrExchange(ShuttleGui & S) override; 108 bool TransferDataToWindow() override; 109 bool TransferDataFromWindow() override; 110 111 // NyquistEffect implementation 112 // For Nyquist Workbench support 113 void RedirectOutput(); 114 void SetCommand(const wxString &cmd); 115 void Continue(); 116 void Break(); 117 void Stop(); 118 119 private: 120 static int mReentryCount; 121 // NyquistEffect implementation 122 123 bool ProcessOne(); 124 125 void BuildPromptWindow(ShuttleGui & S); 126 void BuildEffectWindow(ShuttleGui & S); 127 128 bool TransferDataToPromptWindow(); 129 bool TransferDataToEffectWindow(); 130 131 bool TransferDataFromPromptWindow(); 132 bool TransferDataFromEffectWindow(); 133 134 bool IsOk(); InitializationError()135 const TranslatableString &InitializationError() const { return mInitError; } 136 137 static FilePaths GetNyquistSearchPath(); 138 139 static wxString NyquistToWxString(const char *nyqString); 140 wxString EscapeString(const wxString & inStr); 141 static std::vector<EnumValueSymbol> ParseChoice(const wxString & text); 142 143 FileExtensions ParseFileExtensions(const wxString & text); 144 FileNames::FileType ParseFileType(const wxString & text); 145 FileNames::FileTypes ParseFileTypes(const wxString & text); 146 147 static int StaticGetCallback(float *buffer, int channel, 148 int64_t start, int64_t len, int64_t totlen, 149 void *userdata); 150 static int StaticPutCallback(float *buffer, int channel, 151 int64_t start, int64_t len, int64_t totlen, 152 void *userdata); 153 static void StaticOutputCallback(int c, void *userdata); 154 static void StaticOSCallback(void *userdata); 155 156 int GetCallback(float *buffer, int channel, 157 int64_t start, int64_t len, int64_t totlen); 158 int PutCallback(float *buffer, int channel, 159 int64_t start, int64_t len, int64_t totlen); 160 void OutputCallback(int c); 161 void OSCallback(); 162 163 void ParseFile(); 164 bool ParseCommand(const wxString & cmd); 165 bool ParseProgram(wxInputStream & stream); 166 struct Tokenizer { 167 bool sl { false }; 168 bool q { false }; 169 int paren{ 0 }; 170 wxString tok; 171 wxArrayStringEx tokens; 172 173 bool Tokenize( 174 const wxString &line, bool eof, 175 size_t trimStart, size_t trimEnd); 176 }; 177 bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first); 178 179 static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens = true, 180 wxString *pExtraString = nullptr); 181 static wxString UnQuote(const wxString &s, bool allowParens = true, 182 wxString *pExtraString = nullptr); 183 double GetCtrlValue(const wxString &s); 184 185 void OnLoad(wxCommandEvent & evt); 186 void OnSave(wxCommandEvent & evt); 187 void OnDebug(wxCommandEvent & evt); 188 189 void OnText(wxCommandEvent & evt); 190 void OnSlider(wxCommandEvent & evt); 191 void OnChoice(wxCommandEvent & evt); 192 void OnTime(wxCommandEvent & evt); 193 void OnFileButton(wxCommandEvent & evt); 194 195 void resolveFilePath(wxString & path, FileExtension extension = {}); 196 bool validatePath(wxString path); 197 wxString ToTimeFormat(double t); 198 199 private: 200 201 wxString mXlispPath; 202 203 wxFileName mFileName; ///< Name of the Nyquist script file this effect is loaded from 204 wxDateTime mFileModified; ///< When the script was last modified on disk 205 206 bool mStop; 207 bool mBreak; 208 bool mCont; 209 210 bool mFoundType; 211 bool mCompiler; 212 bool mTrace; // True when *tracenable* or *sal-traceback* are enabled 213 bool mIsSal; 214 bool mExternal; 215 bool mIsSpectral; 216 bool mIsTool; 217 /** True if the code to execute is obtained interactively from the user via 218 * the "Nyquist Effect Prompt", or "Nyquist Prompt", false for all other effects (lisp code read from 219 * files) 220 */ 221 bool mIsPrompt; 222 bool mOK; 223 TranslatableString mInitError; 224 wxString mInputCmd; // history: exactly what the user typed 225 wxString mParameters; // The parameters of to be fed to a nested prompt 226 wxString mCmd; // the command to be processed 227 TranslatableString mName; ///< Name of the Effect (untranslated) 228 TranslatableString mPromptName; // If a prompt, we need to remember original name. 229 TranslatableString mAction; 230 TranslatableString mInfo; 231 TranslatableString mAuthor; 232 // Version number of the specific plug-in (not to be confused with mVersion) 233 // For shipped plug-ins this will be the same as the Audacity release version 234 // when the plug-in was last modified. 235 TranslatableString mReleaseVersion; 236 TranslatableString mCopyright; 237 wxString mManPage; // ONLY use if a help page exists in the manual. 238 wxString mHelpFile; 239 bool mHelpFileExists; 240 EffectType mType; 241 EffectType mPromptType; // If a prompt, need to remember original type. 242 243 bool mEnablePreview; 244 bool mDebugButton; // Set to false to disable Debug button. 245 246 bool mDebug; // When true, debug window is shown. 247 bool mRedirectOutput; 248 bool mProjectChanged; 249 wxString mDebugOutputStr; 250 TranslatableString mDebugOutput; 251 252 int mVersion; // Syntactic version of Nyquist plug-in (not to be confused with mReleaseVersion) 253 std::vector<NyqControl> mControls; 254 255 unsigned mCurNumChannels; 256 WaveTrack *mCurTrack[2]; 257 sampleCount mCurStart[2]; 258 sampleCount mCurLen; 259 sampleCount mMaxLen; 260 int mTrackIndex; 261 bool mFirstInGroup; 262 double mOutputTime; 263 unsigned mCount; 264 unsigned mNumSelectedChannels; 265 double mProgressIn; 266 double mProgressOut; 267 double mProgressTot; 268 double mScale; 269 270 using Buffer = std::unique_ptr<float[]>; 271 Buffer mCurBuffer[2]; 272 sampleCount mCurBufferStart[2]; 273 size_t mCurBufferLen[2]; 274 275 WaveTrack *mOutputTrack[2]; 276 277 wxArrayString mCategories; 278 279 wxString mProps; 280 wxString mPerTrackProps; 281 282 bool mRestoreSplits; 283 int mMergeClips; 284 285 wxTextCtrl *mCommandText; 286 287 std::exception_ptr mpException {}; 288 289 DECLARE_EVENT_TABLE() 290 291 friend class NyquistEffectsModule; 292 }; 293 294 class NyquistOutputDialog final : public wxDialogWrapper 295 { 296 public: 297 NyquistOutputDialog(wxWindow * parent, wxWindowID id, 298 const TranslatableString & title, 299 const TranslatableString & prompt, 300 const TranslatableString &message); 301 302 private: 303 void OnOk(wxCommandEvent & event); 304 305 private: 306 DECLARE_EVENT_TABLE() 307 }; 308 309 310 #endif 311