audacia/src/effects/nyquist/Nyquist.h

311 lines
9.1 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
Nyquist.h
Dominic Mazzoni
**********************************************************************/
#ifndef __AUDACITY_EFFECT_NYQUIST__
#define __AUDACITY_EFFECT_NYQUIST__
#include <wx/button.h>
#include <wx/datetime.h>
#include <wx/dialog.h>
#include <wx/filename.h>
#include <wx/intl.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/stattext.h>
#include <wx/textbuf.h>
#include <wx/textctrl.h>
#include <wx/tokenzr.h>
#include "../Effect.h"
#include "nyx.h"
#define NYQUISTEFFECTS_VERSION wxT("1.0.0.0")
/* i18n-hint: "Nyquist" is an embedded interpreted programming language in
Audacity, named in honor of the Swedish-American Harry Nyquist (or Nyqvist).
In the translations of this and other strings, you may transliterate the
name into another alphabet. */
#define NYQUISTEFFECTS_FAMILY ( IdentInterfaceSymbol{ XO("Nyquist") } )
#define NYQUIST_PROMPT_ID wxT("Nyquist Prompt")
#define NYQUIST_TOOLS_PROMPT_ID wxT("Nyquist Tools Prompt")
#define NYQUIST_WORKER_ID wxT("Nyquist Worker")
enum NyqControlType
{
NYQ_CTRL_INT,
NYQ_CTRL_FLOAT,
NYQ_CTRL_STRING,
NYQ_CTRL_CHOICE,
NYQ_CTRL_INT_TEXT,
NYQ_CTRL_FLOAT_TEXT,
NYQ_CTRL_TEXT,
NYQ_CTRL_TIME,
NYQ_CTRL_FILE,
};
class NyqControl
{
public:
NyqControl() = default;
NyqControl( const NyqControl& ) = default;
NyqControl &operator = ( const NyqControl & ) = default;
//NyqControl( NyqControl && ) = default;
//NyqControl &operator = ( NyqControl && ) = default;
int type;
wxString var;
wxString name;
wxString label;
std::vector<IdentInterfaceSymbol> choices;
wxString valStr;
wxString lowStr;
wxString highStr;
double val;
double low;
double high;
int ticks;
};
class AUDACITY_DLL_API NyquistEffect final : public Effect
{
public:
/** @param fName File name of the Nyquist script defining this effect. If
* an empty string, then prompt the user for the Nyquist code to interpret.
*/
NyquistEffect(const wxString &fName);
virtual ~NyquistEffect();
// IdentInterface implementation
wxString GetPath() override;
IdentInterfaceSymbol GetSymbol() override;
IdentInterfaceSymbol GetVendor() override;
wxString GetVersion() override;
wxString GetDescription() override;
wxString ManualPage() override;
wxString HelpPage() override;
// EffectDefinitionInterface implementation
EffectType GetType() override;
IdentInterfaceSymbol GetFamilyId() override;
bool IsInteractive() override;
bool IsDefault() override;
// EffectClientInterface implementation
bool DefineParams( ShuttleParams & S ) override;
bool GetAutomationParameters(CommandParameters & parms) override;
bool SetAutomationParameters(CommandParameters & parms) override;
// Effect implementation
bool Init() override;
bool CheckWhetherSkipEffect() override;
bool Process() override;
bool ShowInterface(wxWindow *parent, bool forceModal = false) override;
void PopulateOrExchange(ShuttleGui & S) override;
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
// NyquistEffect implementation
// For Nyquist Workbench support
void RedirectOutput();
void SetCommand(const wxString &cmd);
void Continue();
void Break();
void Stop();
private:
// NyquistEffect implementation
bool ProcessOne();
void BuildPromptWindow(ShuttleGui & S);
void BuildEffectWindow(ShuttleGui & S);
bool TransferDataToPromptWindow();
bool TransferDataToEffectWindow();
bool TransferDataFromPromptWindow();
bool TransferDataFromEffectWindow();
bool IsOk();
const wxString &InitializationError() const { return mInitError; }
static wxArrayString GetNyquistSearchPath();
static wxString NyquistToWxString(const char *nyqString);
wxString EscapeString(const wxString & inStr);
static std::vector<IdentInterfaceSymbol> ParseChoice(const wxString & text);
static int StaticGetCallback(float *buffer, int channel,
long start, long len, long totlen,
void *userdata);
static int StaticPutCallback(float *buffer, int channel,
long start, long len, long totlen,
void *userdata);
static void StaticOutputCallback(int c, void *userdata);
static void StaticOSCallback(void *userdata);
int GetCallback(float *buffer, int channel,
long start, long len, long totlen);
int PutCallback(float *buffer, int channel,
long start, long len, long totlen);
void OutputCallback(int c);
void OSCallback();
void ParseFile();
bool ParseCommand(const wxString & cmd);
bool ParseProgram(wxInputStream & stream);
struct Tokenizer {
bool sl { false };
bool q { false };
int paren{ 0 };
wxString tok;
wxArrayString tokens;
bool Tokenize(
const wxString &line, bool eof,
size_t trimStart, size_t trimEnd);
};
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first);
static wxString UnQuote(const wxString &s, bool allowParens = true,
wxString *pExtraString = nullptr);
double GetCtrlValue(const wxString &s);
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);
void resolveFilePath(wxString & path, wxString extension = "");
bool validatePath(wxString path);
wxString ToTimeFormat(double t);
private:
wxString mXlispPath;
wxFileName mFileName; ///< Name of the Nyquist script file this effect is loaded from
wxDateTime mFileModified; ///< When the script was last modified on disk
bool mStop;
bool mBreak;
bool mCont;
bool mFoundType;
bool mCompiler;
bool mTrace; // True when *tracenable* or *sal-traceback* are enabled
bool mIsSal;
bool mExternal;
bool mIsSpectral;
/** True if the code to execute is obtained interactively from the user via
* the "Nyquist Prompt", or "Nyquist Tools Prompt", false for all other effects (lisp code read from
* files)
*/
bool mIsPrompt;
bool mOK;
wxString mInitError;
wxString mInputCmd; // history: exactly what the user typed
wxString mCmd; // the command to be processed
wxString mName; ///< Name of the Effect (untranslated)
wxString mAction; // translatable
wxString mInfo; // translatable
wxString mAuthor;
// Version number of the specific plug-in (not to be confused with mVersion)
// For shipped plug-ins this will be the same as the Audacity release version
// when the plug-in was last modified.
wxString mReleaseVersion;
wxString mCopyright;
wxString mManPage; // ONLY use if a help page exists in the manual.
wxString mHelpFile;
bool mHelpFileExists;
EffectType mType;
bool mEnablePreview;
bool mDebugButton; // Set to false to disable Debug button.
bool mDebug; // When true, debug window is shown.
bool mRedirectOutput;
bool mProjectChanged;
wxString mDebugOutput;
int mVersion; // Syntactic version of Nyquist plug-in (not to be confused with mReleaseVersion)
std::vector<NyqControl> mControls;
unsigned mCurNumChannels;
WaveTrack *mCurTrack[2];
sampleCount mCurStart[2];
sampleCount mCurLen;
sampleCount mMaxLen;
int mTrackIndex;
bool mFirstInGroup;
double mOutputTime;
unsigned mCount;
unsigned mNumSelectedChannels;
double mProgressIn;
double mProgressOut;
double mProgressTot;
double mScale;
SampleBuffer mCurBuffer[2];
sampleCount mCurBufferStart[2];
size_t mCurBufferLen[2];
WaveTrack *mOutputTrack[2];
wxArrayString mCategories;
wxString mProps;
wxString mPerTrackProps;
bool mRestoreSplits;
int mMergeClips;
wxTextCtrl *mCommandText;
wxCheckBox *mVersionCheckBox;
std::exception_ptr mpException {};
DECLARE_EVENT_TABLE()
friend class NyquistEffectsModule;
};
class NyquistOutputDialog final : public wxDialogWrapper
{
public:
NyquistOutputDialog(wxWindow * parent, wxWindowID id,
const wxString & title,
const wxString & prompt,
const wxString &message);
private:
void OnOk(wxCommandEvent & event);
private:
DECLARE_EVENT_TABLE()
};
#endif