mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 16:19:43 +02:00
801 lines
26 KiB
C++
801 lines
26 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
Effect.h
|
|
|
|
Dominic Mazzoni
|
|
Vaughan Johnson
|
|
|
|
**********************************************************************/
|
|
|
|
#ifndef __AUDACITY_EFFECT__
|
|
#define __AUDACITY_EFFECT__
|
|
|
|
#include "../Audacity.h"
|
|
|
|
#include "../Experimental.h"
|
|
|
|
#include <set>
|
|
|
|
#include <wx/defs.h>
|
|
|
|
class wxButton;
|
|
class wxCheckBox;
|
|
class wxChoice;
|
|
class wxListBox;
|
|
class wxWindow;
|
|
|
|
#include "audacity/ConfigInterface.h"
|
|
#include "audacity/EffectInterface.h"
|
|
|
|
#include "../SelectedRegion.h"
|
|
|
|
#include "../Track.h"
|
|
|
|
#include "../widgets/wxPanelWrapper.h" // to inherit
|
|
|
|
class wxArrayString;
|
|
class ShuttleGui;
|
|
class AudacityCommand;
|
|
|
|
#define BUILTIN_EFFECT_PREFIX wxT("Built-in Effect: ")
|
|
|
|
class AudacityProject;
|
|
class LabelTrack;
|
|
class NotifyingSelectedRegion;
|
|
class ProgressDialog;
|
|
class SelectedRegion;
|
|
class EffectUIHost;
|
|
class Track;
|
|
class TrackList;
|
|
class TrackFactory;
|
|
class WaveTrack;
|
|
|
|
/* 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 ( EffectFamilySymbol{ XO("Nyquist") } )
|
|
|
|
#define NYQUIST_PROMPT_ID wxT("Nyquist Prompt")
|
|
#define NYQUIST_WORKER_ID wxT("Nyquist Worker")
|
|
|
|
// TODO: Apr-06-2015
|
|
// TODO: Much more cleanup of old methods and variables is needed, but
|
|
// TODO: can't be done until after all effects are using the NEW API.
|
|
|
|
class AUDACITY_DLL_API Effect /* not final */ : public wxEvtHandler,
|
|
public EffectClientInterface,
|
|
public EffectUIClientInterface,
|
|
public EffectHostInterface
|
|
{
|
|
//
|
|
// public methods
|
|
//
|
|
// Used by the outside program to determine properties of an effect and
|
|
// apply the effect to one or more tracks.
|
|
//
|
|
public:
|
|
// The constructor is called once by each subclass at the beginning of the program.
|
|
// Avoid allocating memory or doing time-consuming processing here.
|
|
Effect();
|
|
virtual ~Effect();
|
|
|
|
// Type of a registered function that, if it returns true,
|
|
// causes ShowInterface to return early without making any dialog
|
|
using VetoDialogHook = bool (*) ( wxDialog* );
|
|
static VetoDialogHook SetVetoDialogHook( VetoDialogHook hook );
|
|
|
|
// ComponentInterface implementation
|
|
|
|
PluginPath GetPath() override;
|
|
|
|
ComponentInterfaceSymbol GetSymbol() override;
|
|
|
|
VendorSymbol GetVendor() override;
|
|
wxString GetVersion() override;
|
|
wxString GetDescription() override;
|
|
|
|
// EffectDefinitionInterface implementation
|
|
|
|
EffectType GetType() override;
|
|
EffectFamilySymbol GetFamily() override;
|
|
bool IsInteractive() override;
|
|
bool IsDefault() override;
|
|
bool IsLegacy() override;
|
|
bool SupportsRealtime() override;
|
|
bool SupportsAutomation() override;
|
|
|
|
// EffectClientInterface implementation
|
|
|
|
bool SetHost(EffectHostInterface *host) override;
|
|
|
|
unsigned GetAudioInCount() override;
|
|
unsigned GetAudioOutCount() override;
|
|
|
|
int GetMidiInCount() override;
|
|
int GetMidiOutCount() override;
|
|
|
|
sampleCount GetLatency() override;
|
|
size_t GetTailSize() override;
|
|
|
|
void SetSampleRate(double rate) override;
|
|
size_t SetBlockSize(size_t maxBlockSize) override;
|
|
size_t GetBlockSize() const override;
|
|
|
|
bool IsReady() override;
|
|
bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap = NULL) override;
|
|
bool ProcessFinalize() override;
|
|
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override;
|
|
|
|
bool RealtimeInitialize() override;
|
|
bool RealtimeAddProcessor(unsigned numChannels, float sampleRate) override;
|
|
bool RealtimeFinalize() override;
|
|
bool RealtimeSuspend() override;
|
|
bool RealtimeResume() override;
|
|
bool RealtimeProcessStart() override;
|
|
size_t RealtimeProcess(int group,
|
|
float **inbuf,
|
|
float **outbuf,
|
|
size_t numSamples) override;
|
|
bool RealtimeProcessEnd() override;
|
|
|
|
bool ShowInterface(wxWindow *parent, bool forceModal = false) override;
|
|
|
|
bool GetAutomationParameters(CommandParameters & parms) override;
|
|
bool SetAutomationParameters(CommandParameters & parms) override;
|
|
|
|
bool LoadUserPreset(const RegistryPath & name) override;
|
|
bool SaveUserPreset(const RegistryPath & name) override;
|
|
|
|
RegistryPaths GetFactoryPresets() override;
|
|
bool LoadFactoryPreset(int id) override;
|
|
bool LoadFactoryDefaults() override;
|
|
|
|
// EffectUIClientInterface implementation
|
|
|
|
void SetHostUI(EffectUIHostInterface *host) override;
|
|
bool PopulateUI(wxWindow *parent) override;
|
|
bool IsGraphicalUI() override;
|
|
bool ValidateUI() override;
|
|
bool HideUI() override;
|
|
bool CloseUI() override;
|
|
|
|
bool CanExportPresets() override;
|
|
void ExportPresets() override;
|
|
void ImportPresets() override;
|
|
|
|
bool HasOptions() override;
|
|
void ShowOptions() override;
|
|
|
|
// EffectHostInterface implementation
|
|
|
|
double GetDefaultDuration() override;
|
|
double GetDuration() override;
|
|
NumericFormatSymbol GetDurationFormat() override;
|
|
virtual NumericFormatSymbol GetSelectionFormat() /* not override? */; // time format in Selection toolbar
|
|
void SetDuration(double duration) override;
|
|
|
|
bool Apply() override;
|
|
void Preview() override;
|
|
|
|
wxDialog *CreateUI(wxWindow *parent, EffectUIClientInterface *client) override;
|
|
|
|
RegistryPath GetUserPresetsGroup(const RegistryPath & name) override;
|
|
RegistryPath GetCurrentSettingsGroup() override;
|
|
RegistryPath GetFactoryDefaultsGroup() override;
|
|
virtual wxString GetSavedStateGroup() /* not override? */;
|
|
|
|
// ConfigClientInterface implementation
|
|
|
|
bool HasSharedConfigGroup(const RegistryPath & group) override;
|
|
bool GetSharedConfigSubgroups(const RegistryPath & group, RegistryPaths &subgroups) override;
|
|
|
|
bool GetSharedConfig(const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = {}) override;
|
|
bool GetSharedConfig(const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override;
|
|
bool GetSharedConfig(const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override;
|
|
bool GetSharedConfig(const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override;
|
|
bool GetSharedConfig(const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override;
|
|
|
|
bool SetSharedConfig(const RegistryPath & group, const RegistryPath & key, const wxString & value) override;
|
|
bool SetSharedConfig(const RegistryPath & group, const RegistryPath & key, const int & value) override;
|
|
bool SetSharedConfig(const RegistryPath & group, const RegistryPath & key, const bool & value) override;
|
|
bool SetSharedConfig(const RegistryPath & group, const RegistryPath & key, const float & value) override;
|
|
bool SetSharedConfig(const RegistryPath & group, const RegistryPath & key, const double & value) override;
|
|
|
|
bool RemoveSharedConfigSubgroup(const RegistryPath & group) override;
|
|
bool RemoveSharedConfig(const RegistryPath & group, const RegistryPath & key) override;
|
|
|
|
bool HasPrivateConfigGroup(const RegistryPath & group) override;
|
|
bool GetPrivateConfigSubgroups(const RegistryPath & group, RegistryPaths &paths) override;
|
|
|
|
bool GetPrivateConfig(const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = {}) override;
|
|
bool GetPrivateConfig(const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override;
|
|
bool GetPrivateConfig(const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override;
|
|
bool GetPrivateConfig(const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override;
|
|
bool GetPrivateConfig(const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override;
|
|
|
|
bool SetPrivateConfig(const RegistryPath & group, const RegistryPath & key, const wxString & value) override;
|
|
bool SetPrivateConfig(const RegistryPath & group, const RegistryPath & key, const int & value) override;
|
|
bool SetPrivateConfig(const RegistryPath & group, const RegistryPath & key, const bool & value) override;
|
|
bool SetPrivateConfig(const RegistryPath & group, const RegistryPath & key, const float & value) override;
|
|
bool SetPrivateConfig(const RegistryPath & group, const RegistryPath & key, const double & value) override;
|
|
|
|
bool RemovePrivateConfigSubgroup(const RegistryPath & group) override;
|
|
bool RemovePrivateConfig(const RegistryPath & group, const RegistryPath & key) override;
|
|
|
|
// Effect implementation
|
|
|
|
// NEW virtuals
|
|
virtual PluginID GetID();
|
|
|
|
virtual bool Startup(EffectClientInterface *client);
|
|
virtual bool Startup();
|
|
|
|
virtual bool GetAutomationParameters(wxString & parms);
|
|
virtual bool SetAutomationParameters(const wxString & parms);
|
|
|
|
virtual RegistryPaths GetUserPresets();
|
|
virtual bool HasCurrentSettings();
|
|
virtual bool HasFactoryDefaults();
|
|
virtual wxString GetPreset(wxWindow * parent, const wxString & parms);
|
|
|
|
// Name of page in the Audacity alpha manual
|
|
virtual wxString ManualPage();
|
|
// Fully qualified local help file name
|
|
virtual wxString HelpPage();
|
|
|
|
virtual bool IsBatchProcessing();
|
|
virtual void SetBatchProcessing(bool start);
|
|
|
|
/* not virtual */ void SetPresetParameters( const wxArrayString * Names, const wxArrayString * Values ) {
|
|
if( Names ) mPresetNames = *Names;
|
|
if( Values ) mPresetValues = *Values;
|
|
}
|
|
|
|
// Returns true on success. Will only operate on tracks that
|
|
// have the "selected" flag set to true, which is consistent with
|
|
// Audacity's standard UI.
|
|
/* not virtual */ bool DoEffect(wxWindow *parent, double projectRate, TrackList *list,
|
|
TrackFactory *factory, NotifyingSelectedRegion &selectedRegion,
|
|
bool shouldPrompt = true);
|
|
|
|
bool Delegate( Effect &delegate, wxWindow *parent, bool shouldPrompt);
|
|
|
|
virtual bool IsHidden();
|
|
|
|
// Nonvirtual
|
|
// Display a message box, using effect's (translated) name as the prefix
|
|
// for the title.
|
|
enum : long { DefaultMessageBoxStyle = wxOK | wxCENTRE };
|
|
int MessageBox(const wxString& message,
|
|
long style = DefaultMessageBoxStyle,
|
|
const wxString& titleStr = wxString{});
|
|
|
|
static void IncEffectCounter(){ nEffectsDone++;};
|
|
|
|
//
|
|
// protected virtual methods
|
|
//
|
|
// Each subclass of Effect overrides one or more of these methods to
|
|
// do its processing.
|
|
//
|
|
protected:
|
|
|
|
// Called once each time an effect is called. Perform any initialization;
|
|
// make sure that the effect can be performed on the selected tracks and
|
|
// return false otherwise
|
|
virtual bool Init();
|
|
|
|
// If necessary, open a dialog to get parameters from the user.
|
|
// This method will not always be called (for example if a user
|
|
// repeats an effect) but if it is called, it will be called
|
|
// after Init.
|
|
virtual bool PromptUser(wxWindow *parent);
|
|
|
|
// Check whether effect should be skipped
|
|
// Typically this is only useful in automation, for example
|
|
// detecting that zero noise reduction is to be done,
|
|
// or that normalisation is being done without Dc bias shift
|
|
// or amplitude modification
|
|
virtual bool CheckWhetherSkipEffect() { return false; }
|
|
|
|
// Actually do the effect here.
|
|
virtual bool Process();
|
|
virtual bool ProcessPass();
|
|
virtual bool InitPass1();
|
|
virtual bool InitPass2();
|
|
virtual int GetPass();
|
|
|
|
// clean up any temporary memory, needed only per invocation of the
|
|
// effect, after either successful or failed or exception-aborted processing.
|
|
// Invoked inside a "finally" block so it must be no-throw.
|
|
virtual void End();
|
|
|
|
// Most effects just use the previewLength, but time-stretching/compressing
|
|
// effects need to use a different input length, so override this method.
|
|
virtual double CalcPreviewInputLength(double previewLength);
|
|
|
|
// The Effect class fully implements the Preview method for you.
|
|
// Only override it if you need to do preprocessing or cleanup.
|
|
virtual void Preview(bool dryOnly);
|
|
|
|
virtual void PopulateOrExchange(ShuttleGui & S);
|
|
virtual bool TransferDataToWindow() /* not override */;
|
|
virtual bool TransferDataFromWindow() /* not override */;
|
|
virtual bool EnableApply(bool enable = true);
|
|
virtual bool EnablePreview(bool enable = true);
|
|
virtual void EnableDebug(bool enable = true);
|
|
|
|
// No more virtuals!
|
|
|
|
// The Progress methods all return true if the user has cancelled;
|
|
// you should exit immediately if this happens (cleaning up memory
|
|
// is okay, but don't try to undo).
|
|
|
|
// Pass a fraction between 0.0 and 1.0
|
|
bool TotalProgress(double frac, const TranslatableString & = {});
|
|
|
|
// Pass a fraction between 0.0 and 1.0, for the current track
|
|
// (when doing one track at a time)
|
|
bool TrackProgress(int whichTrack, double frac, const TranslatableString & = {});
|
|
|
|
// Pass a fraction between 0.0 and 1.0, for the current track group
|
|
// (when doing stereo groups at a time)
|
|
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString & = {});
|
|
|
|
int GetNumWaveTracks() { return mNumTracks; }
|
|
int GetNumWaveGroups() { return mNumGroups; }
|
|
|
|
// Calculates the start time and selection length in samples
|
|
void GetSamples(
|
|
const WaveTrack *track, sampleCount *start, sampleCount *len);
|
|
|
|
// Previewing linear effect can be optimised by pre-mixing. However this
|
|
// should not be used for non-linear effects such as dynamic processors
|
|
// To allow pre-mixing before Preview, set linearEffectFlag to true.
|
|
void SetLinearEffectFlag(bool linearEffectFlag);
|
|
|
|
// Most effects only need to preview a short selection. However some
|
|
// (such as fade effects) need to know the full selection length.
|
|
void SetPreviewFullSelectionFlag(bool previewDurationFlag);
|
|
|
|
// Use this if the effect needs to know if it is previewing
|
|
bool IsPreviewing() { return mIsPreview; }
|
|
|
|
// Most effects only require selected tracks to be copied for Preview.
|
|
// If IncludeNotSelectedPreviewTracks(true), then non-linear effects have
|
|
// preview copies of all wave tracks.
|
|
void IncludeNotSelectedPreviewTracks(bool includeNotSelected);
|
|
|
|
// Use this method to copy the input tracks to mOutputTracks, if
|
|
// doing the processing on them, and replacing the originals only on success (and not cancel).
|
|
// If not all sync-locked selected, then only selected wave tracks.
|
|
void CopyInputTracks(bool allSyncLockSelected = false);
|
|
|
|
// A global counter of all the successful Effect invocations.
|
|
static int nEffectsDone;
|
|
|
|
// For the use of analyzers, which don't need to make output wave tracks,
|
|
// but may need to add label tracks.
|
|
class AddedAnalysisTrack {
|
|
friend Effect;
|
|
AddedAnalysisTrack(Effect *pEffect, const wxString &name);
|
|
AddedAnalysisTrack(const AddedAnalysisTrack&) PROHIBITED;
|
|
|
|
public:
|
|
|
|
AddedAnalysisTrack() {}
|
|
|
|
// So you can have a vector of them
|
|
AddedAnalysisTrack(AddedAnalysisTrack &&that);
|
|
|
|
LabelTrack *get() const { return mpTrack; }
|
|
|
|
// Call this to indicate successful completion of the analyzer.
|
|
void Commit();
|
|
|
|
// Destructor undoes the addition of the analysis track if not committed.
|
|
~AddedAnalysisTrack();
|
|
|
|
private:
|
|
Effect *mpEffect{};
|
|
LabelTrack *mpTrack{};
|
|
};
|
|
|
|
// Set name to given value if that is not empty, else use default name
|
|
std::shared_ptr<AddedAnalysisTrack> AddAnalysisTrack(const wxString &name = wxString());
|
|
|
|
// For the use of analyzers, which don't need to make output wave tracks,
|
|
// but may need to modify label tracks.
|
|
class ModifiedAnalysisTrack {
|
|
friend Effect;
|
|
ModifiedAnalysisTrack
|
|
(Effect *pEffect, const LabelTrack *pOrigTrack, const wxString &name);
|
|
ModifiedAnalysisTrack(const ModifiedAnalysisTrack&) PROHIBITED;
|
|
|
|
public:
|
|
|
|
ModifiedAnalysisTrack();
|
|
|
|
// So you can have a vector of them
|
|
ModifiedAnalysisTrack(ModifiedAnalysisTrack &&that);
|
|
|
|
LabelTrack *get() const { return mpTrack; }
|
|
|
|
// Call this to indicate successful completion of the analyzer.
|
|
void Commit();
|
|
|
|
// Destructor undoes the modification of the analysis track if not committed.
|
|
~ModifiedAnalysisTrack();
|
|
|
|
private:
|
|
Effect *mpEffect{};
|
|
LabelTrack *mpTrack{};
|
|
std::shared_ptr<Track> mpOrigTrack{};
|
|
};
|
|
|
|
// Set name to given value if that is not empty, else use default name
|
|
ModifiedAnalysisTrack ModifyAnalysisTrack
|
|
(const LabelTrack *pOrigTrack, const wxString &name = wxString());
|
|
|
|
// If bGoodResult, replace mWaveTracks tracks in mTracks with successfully processed
|
|
// mOutputTracks copies, get rid of old mWaveTracks, and set mWaveTracks to mOutputTracks.
|
|
// Else clear and DELETE mOutputTracks copies.
|
|
void ReplaceProcessedTracks(const bool bGoodResult);
|
|
|
|
// Use this to append a NEW output track.
|
|
Track *AddToOutputTracks(const std::shared_ptr<Track> &t);
|
|
|
|
//
|
|
// protected data
|
|
//
|
|
// The Effect base class will set these variables, some or all of which
|
|
// may be needed by any particular subclass of Effect.
|
|
//
|
|
protected:
|
|
|
|
ProgressDialog *mProgress; // Temporary pointer, NOT deleted in destructor.
|
|
double mProjectRate; // Sample rate of the project - NEW tracks should
|
|
// be created with this rate...
|
|
double mSampleRate;
|
|
wxWeakRef<NotifyingSelectedRegion> mpSelectedRegion{};
|
|
TrackFactory *mFactory;
|
|
const TrackList *inputTracks() const { return mTracks; }
|
|
std::shared_ptr<TrackList> mOutputTracks; // used only if CopyInputTracks() is called.
|
|
double mT0;
|
|
double mT1;
|
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
|
double mF0;
|
|
double mF1;
|
|
#endif
|
|
wxArrayString mPresetNames;
|
|
wxArrayString mPresetValues;
|
|
int mPass;
|
|
|
|
// UI
|
|
wxDialog *mUIDialog;
|
|
wxWindow *mUIParent;
|
|
int mUIResultID;
|
|
|
|
sampleCount mSampleCnt;
|
|
|
|
// Used only by the base Effect class
|
|
//
|
|
private:
|
|
void CommonInit();
|
|
void CountWaveTracks();
|
|
|
|
// Driver for client effects
|
|
bool ProcessTrack(int count,
|
|
ChannelNames map,
|
|
WaveTrack *left,
|
|
WaveTrack *right,
|
|
sampleCount leftStart,
|
|
sampleCount rightStart,
|
|
sampleCount len,
|
|
FloatBuffers &inBuffer,
|
|
FloatBuffers &outBuffer,
|
|
ArrayOf< float * > &inBufPos,
|
|
ArrayOf< float *> &outBufPos);
|
|
|
|
//
|
|
// private data
|
|
//
|
|
// Used only by the base Effect class
|
|
//
|
|
private:
|
|
TrackList *mTracks; // the complete list of all tracks
|
|
|
|
bool mIsBatch;
|
|
bool mIsLinearEffect;
|
|
bool mPreviewWithNotSelected;
|
|
bool mPreviewFullSelection;
|
|
|
|
bool mIsSelection;
|
|
double mDuration;
|
|
NumericFormatSymbol mDurationFormat;
|
|
|
|
bool mIsPreview;
|
|
|
|
bool mUIDebug;
|
|
|
|
std::vector<Track*> mIMap;
|
|
std::vector<Track*> mOMap;
|
|
|
|
int mNumTracks; //v This is really mNumWaveTracks, per CountWaveTracks() and GetNumWaveTracks().
|
|
int mNumGroups;
|
|
|
|
// For client driver
|
|
EffectClientInterface *mClient;
|
|
size_t mNumAudioIn;
|
|
size_t mNumAudioOut;
|
|
|
|
size_t mBufferSize;
|
|
size_t mBlockSize;
|
|
unsigned mNumChannels;
|
|
|
|
const static wxString kUserPresetIdent;
|
|
const static wxString kFactoryPresetIdent;
|
|
const static wxString kCurrentSettingsIdent;
|
|
const static wxString kFactoryDefaultsIdent;
|
|
|
|
friend class EffectManager;// so it can call PromptUser in support of batch commands.
|
|
friend class EffectRack;
|
|
friend class EffectUIHost;
|
|
friend class EffectPresetsDialog;
|
|
};
|
|
|
|
// FIXME:
|
|
// FIXME: Remove this once all effects are using the NEW dialog
|
|
// FIXME:
|
|
|
|
#define ID_EFFECT_PREVIEW ePreviewID
|
|
|
|
// Base dialog for regular effect
|
|
class AUDACITY_DLL_API EffectDialog /* not final */ : public wxDialogWrapper
|
|
{
|
|
public:
|
|
// constructors and destructors
|
|
EffectDialog(wxWindow * parent,
|
|
const wxString & title,
|
|
int type = 0,
|
|
int flags = wxDEFAULT_DIALOG_STYLE,
|
|
int additionalButtons = 0);
|
|
|
|
void Init();
|
|
|
|
bool TransferDataToWindow() override;
|
|
bool TransferDataFromWindow() override;
|
|
bool Validate() override;
|
|
|
|
// NEW virtuals:
|
|
virtual void PopulateOrExchange(ShuttleGui & S);
|
|
virtual void OnPreview(wxCommandEvent & evt);
|
|
virtual void OnOk(wxCommandEvent & evt);
|
|
|
|
private:
|
|
int mType;
|
|
int mAdditionalButtons;
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
wxDECLARE_NO_COPY_CLASS(EffectDialog);
|
|
};
|
|
|
|
//
|
|
class EffectUIHost final : public wxDialogWrapper,
|
|
public EffectUIHostInterface
|
|
{
|
|
public:
|
|
// constructors and destructors
|
|
EffectUIHost(wxWindow *parent,
|
|
Effect *effect,
|
|
EffectUIClientInterface *client);
|
|
EffectUIHost(wxWindow *parent,
|
|
AudacityCommand *command,
|
|
EffectUIClientInterface *client);
|
|
virtual ~EffectUIHost();
|
|
|
|
bool TransferDataToWindow() override;
|
|
bool TransferDataFromWindow() override;
|
|
|
|
int ShowModal() override;
|
|
|
|
bool Initialize();
|
|
|
|
private:
|
|
void OnInitDialog(wxInitDialogEvent & evt);
|
|
void OnErase(wxEraseEvent & evt);
|
|
void OnPaint(wxPaintEvent & evt);
|
|
void OnClose(wxCloseEvent & evt);
|
|
void OnApply(wxCommandEvent & evt);
|
|
void DoCancel();
|
|
void OnCancel(wxCommandEvent & evt);
|
|
void OnHelp(wxCommandEvent & evt);
|
|
void OnDebug(wxCommandEvent & evt);
|
|
void OnMenu(wxCommandEvent & evt);
|
|
void OnEnable(wxCommandEvent & evt);
|
|
void OnPlay(wxCommandEvent & evt);
|
|
void OnRewind(wxCommandEvent & evt);
|
|
void OnFFwd(wxCommandEvent & evt);
|
|
void OnPlayback(wxCommandEvent & evt);
|
|
void OnCapture(wxCommandEvent & evt);
|
|
void OnUserPreset(wxCommandEvent & evt);
|
|
void OnFactoryPreset(wxCommandEvent & evt);
|
|
void OnDeletePreset(wxCommandEvent & evt);
|
|
void OnSaveAs(wxCommandEvent & evt);
|
|
void OnImport(wxCommandEvent & evt);
|
|
void OnExport(wxCommandEvent & evt);
|
|
void OnOptions(wxCommandEvent & evt);
|
|
void OnDefaults(wxCommandEvent & evt);
|
|
|
|
void UpdateControls();
|
|
wxBitmap CreateBitmap(const char * const xpm[], bool up, bool pusher);
|
|
void LoadUserPresets();
|
|
|
|
void InitializeRealtime();
|
|
void CleanupRealtime();
|
|
void Resume();
|
|
|
|
private:
|
|
AudacityProject *mProject;
|
|
wxWindow *mParent;
|
|
Effect *mEffect;
|
|
AudacityCommand * mCommand;
|
|
EffectUIClientInterface *mClient;
|
|
|
|
RegistryPaths mUserPresets;
|
|
bool mInitialized;
|
|
bool mSupportsRealtime;
|
|
bool mIsGUI;
|
|
bool mIsBatch;
|
|
|
|
wxButton *mApplyBtn;
|
|
wxButton *mCloseBtn;
|
|
wxButton *mMenuBtn;
|
|
wxButton *mPlayBtn;
|
|
wxButton *mRewindBtn;
|
|
wxButton *mFFwdBtn;
|
|
wxCheckBox *mEnableCb;
|
|
|
|
wxButton *mEnableToggleBtn;
|
|
wxButton *mPlayToggleBtn;
|
|
|
|
wxBitmap mPlayBM;
|
|
wxBitmap mPlayDisabledBM;
|
|
wxBitmap mStopBM;
|
|
wxBitmap mStopDisabledBM;
|
|
|
|
bool mEnabled;
|
|
|
|
bool mDisableTransport;
|
|
bool mPlaying;
|
|
bool mCapturing;
|
|
|
|
SelectedRegion mRegion;
|
|
double mPlayPos;
|
|
|
|
bool mDismissed{};
|
|
bool mNeedsResume{};
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
class EffectPresetsDialog final : public wxDialogWrapper
|
|
{
|
|
public:
|
|
EffectPresetsDialog(wxWindow *parent, Effect *effect);
|
|
virtual ~EffectPresetsDialog();
|
|
|
|
wxString GetSelected() const;
|
|
void SetSelected(const wxString & parms);
|
|
|
|
private:
|
|
void SetPrefix(const wxString & type, const wxString & prefix);
|
|
void UpdateUI();
|
|
|
|
void OnType(wxCommandEvent & evt);
|
|
void OnOk(wxCommandEvent & evt);
|
|
void OnCancel(wxCommandEvent & evt);
|
|
|
|
private:
|
|
wxChoice *mType;
|
|
wxListBox *mPresets;
|
|
|
|
RegistryPaths mFactoryPresets;
|
|
RegistryPaths mUserPresets;
|
|
wxString mSelection;
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
// Utility functions
|
|
|
|
inline float TrapFloat(float x, float min, float max)
|
|
{
|
|
if (x <= min)
|
|
return min;
|
|
|
|
if (x >= max)
|
|
return max;
|
|
|
|
return x;
|
|
}
|
|
|
|
inline double TrapDouble(double x, double min, double max)
|
|
{
|
|
if (x <= min)
|
|
return min;
|
|
|
|
if (x >= max)
|
|
return max;
|
|
|
|
return x;
|
|
}
|
|
|
|
inline long TrapLong(long x, long min, long max)
|
|
{
|
|
if (x <= min)
|
|
return min;
|
|
|
|
if (x >= max)
|
|
return max;
|
|
|
|
return x;
|
|
}
|
|
|
|
// Helper macros for defining, reading and verifying effect parameters
|
|
|
|
#define Param(name, type, key, def, min, max, scale) \
|
|
static const wxChar * KEY_ ## name = (key); \
|
|
static const type DEF_ ## name = (def); \
|
|
static const type MIN_ ## name = (min); \
|
|
static const type MAX_ ## name = (max); \
|
|
static const type SCL_ ## name = (scale);
|
|
|
|
#define PBasic(name, type, key, def) \
|
|
static const wxChar * KEY_ ## name = (key); \
|
|
static const type DEF_ ## name = (def);
|
|
|
|
#define PRange(name, type, key, def, min, max) \
|
|
PBasic(name, type, key, def); \
|
|
static const type MIN_ ## name = (min); \
|
|
static const type MAX_ ## name = (max);
|
|
|
|
#define PScale(name, type, key, def, min, max, scale) \
|
|
PRange(name, type, key, def, min, max); \
|
|
static const type SCL_ ## name = (scale);
|
|
|
|
#define ReadParam(type, name) \
|
|
type name = DEF_ ## name; \
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name, MIN_ ## name, MAX_ ## name)) \
|
|
return false;
|
|
|
|
#define ReadBasic(type, name) \
|
|
type name; \
|
|
wxUnusedVar(MIN_ ##name); \
|
|
wxUnusedVar(MAX_ ##name); \
|
|
wxUnusedVar(SCL_ ##name); \
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name)) \
|
|
return false;
|
|
|
|
#define ReadAndVerifyEnum(name, list, listSize) \
|
|
int name; \
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name, list, listSize)) \
|
|
return false;
|
|
|
|
#define ReadAndVerifyEnumWithObsoletes(name, list, listSize, obsoleteList, nObsolete) \
|
|
int name; \
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name, \
|
|
list, listSize, obsoleteList, nObsolete)) \
|
|
return false;
|
|
|
|
#define ReadAndVerifyInt(name) ReadParam(int, name)
|
|
#define ReadAndVerifyDouble(name) ReadParam(double, name)
|
|
#define ReadAndVerifyFloat(name) ReadParam(float, name)
|
|
#define ReadAndVerifyBool(name) ReadBasic(bool, name)
|
|
#define ReadAndVerifyString(name) ReadBasic(wxString, name)
|
|
|
|
#endif
|