637 lines
22 KiB
C++
637 lines
22 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
Effect.h
|
|
|
|
Dominic Mazzoni
|
|
Vaughan Johnson
|
|
|
|
**********************************************************************/
|
|
|
|
#ifndef __AUDACITY_EFFECT__
|
|
#define __AUDACITY_EFFECT__
|
|
|
|
|
|
|
|
#include <functional>
|
|
#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 WaveTrackFactory;
|
|
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_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;
|
|
TranslatableString 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,
|
|
const EffectDialogFactory &factory, 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(ShuttleGui &S) final;
|
|
bool IsGraphicalUI() override;
|
|
bool ValidateUI() override;
|
|
bool HideUI() override;
|
|
bool CloseUI() override;
|
|
|
|
bool CanExportPresets() override;
|
|
void ExportPresets() override;
|
|
void ImportPresets() override;
|
|
|
|
static CommandID GetSquashedName(wxString name);
|
|
|
|
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;
|
|
|
|
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();
|
|
|
|
// Name of page in the Audacity alpha manual
|
|
virtual ManualPageID ManualPage();
|
|
// Fully qualified local help file name
|
|
virtual FilePath HelpPage();
|
|
|
|
virtual void SetUIFlags(unsigned flags);
|
|
virtual unsigned TestUIFlags(unsigned mask);
|
|
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.
|
|
// Create a user interface only if the supplied function is not null.
|
|
/* not virtual */ bool DoEffect( double projectRate, TrackList *list,
|
|
WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion,
|
|
// Prompt the user for input only if these arguments are both not null.
|
|
wxWindow *pParent = nullptr,
|
|
const EffectDialogFactory &dialogFactory = {} );
|
|
|
|
bool Delegate( Effect &delegate,
|
|
wxWindow &parent, const EffectDialogFactory &factory );
|
|
|
|
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 TranslatableString& message,
|
|
long style = DefaultMessageBoxStyle,
|
|
const TranslatableString& titleStr = {});
|
|
|
|
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();
|
|
|
|
// 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 length in samples for one or two channels
|
|
void GetBounds(
|
|
const WaveTrack &track, const WaveTrack *pRight,
|
|
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 AUDACITY_DLL_API 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 AUDACITY_DLL_API 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{};
|
|
WaveTrackFactory *mFactory;
|
|
const TrackList *inputTracks() const { return mTracks; }
|
|
const AudacityProject *FindProject() const;
|
|
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;
|
|
unsigned mUIFlags;
|
|
|
|
sampleCount mSampleCnt;
|
|
|
|
// Used only by the base Effect class
|
|
//
|
|
private:
|
|
void CountWaveTracks();
|
|
|
|
// Driver for client effects
|
|
bool ProcessTrack(int count,
|
|
ChannelNames map,
|
|
WaveTrack *left,
|
|
WaveTrack *right,
|
|
sampleCount start,
|
|
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;
|
|
|
|
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;
|
|
|
|
public:
|
|
const static wxString kUserPresetIdent;
|
|
const static wxString kFactoryPresetIdent;
|
|
const static wxString kCurrentSettingsIdent;
|
|
const static wxString kFactoryDefaultsIdent;
|
|
|
|
friend class EffectUIHost;
|
|
};
|
|
|
|
// FIXME:
|
|
// FIXME: Remove this once all effects are using the NEW dialog
|
|
// FIXME:
|
|
|
|
#define ID_EFFECT_PREVIEW ePreviewID
|
|
|
|
// 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
|