audacia/src/effects/Effect.h

337 lines
10 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
Effect.h
Dominic Mazzoni
Vaughan Johnson
**********************************************************************/
#ifndef __AUDACITY_EFFECT__
#define __AUDACITY_EFFECT__
#include <set>
#include <wx/dynarray.h>
#include <wx/intl.h>
#include <wx/string.h>
class wxDialog;
class wxWindow;
#include "../WaveTrack.h"
#include "../Shuttle.h"
#include "../ShuttleGui.h"
#include "../Internat.h"
#include "../widgets/ProgressDialog.h"
class TimeWarper;
#define PLUGIN_EFFECT 0x0001
#define BUILTIN_EFFECT 0x0002
// ADVANCED_EFFECT was introduced for Lynn Allan's 'CleanSpeech'
// it allows the list of effects to be filtered to exclude
// the advanced effects.
// Left in when CLEANSPEECH is removed, as it may be useful at some point.
#define ADVANCED_EFFECT 0x0004
// HIDDEN_EFFECT allows an item to be excluded from the effects
// menu in both CleanSpeech and in normal builds. // CLEANSPEECH ??
#define HIDDEN_EFFECT 0x0008
#define INSERT_EFFECT 0x0010
#define PROCESS_EFFECT 0x0020
#define ANALYZE_EFFECT 0x0040
#define ALL_EFFECTS 0x00FF
// Flag used to disable prompting for configuration
// parameteres.
#define CONFIGURED_EFFECT 0x8000
//CLEAN-ME: Rogue value to skip unwanted effects in a chain.
//lda: SKIP_EFFECT_MILLISECOND is a rogue value, used where a millisecond
//time is required to indicate "Don't do this effect".
//It is used in SpikeCleaner and TruncSilence.
//MERGE: Maybe we can remove this now that we have configurable batch
//and so can just drop the steps we don't want?
#define SKIP_EFFECT_MILLISECOND 99999
class AUDACITY_DLL_API Effect {
//
// public methods
//
// Used by the outside program to determine properties of an effect and
// apply the effect to one or more tracks.
//
public:
// Each subclass of Effect should override this method.
// This name will go in the menu bar;
// append "..." if your effect pops up a dialog
virtual wxString GetEffectName() = 0;
// Each subclass of Effect should override this method.
// This should return the category of this effect, which
// will determine where in the menu it's placed.
#ifdef EFFECT_CATEGORIES
virtual std::set<wxString> GetEffectCategories() = 0;
#endif
// Totally optional - if you need a way to identify your effect
// from somewhere else in the program. This should be human-readable,
// but should NOT be translated. Use wxT(""), not _("").
virtual wxString GetEffectIdentifier() { return wxT(""); }
// Each subclass of Effect should override this method.
// This name will go in the progress dialog, but can be used
// elsewhere, and it should describe what is being done.
// For example, if the effect is "Filter", the action is
// "Filtering", or if the effect is "Bass Boost", the action
// is "Boosting Bass Frequencies".
virtual wxString GetEffectAction() = 0;
// Each subclass of Effect should override this method.
// This description will go in the History state.
// Override to include effect parameters, so typically useful only after PromptUser.
virtual wxString GetEffectDescription() {
// Default provides effect name.
return wxString::Format(_("Applied effect: %s"),
this->GetEffectName().c_str());
}
// Return flags which tell you what kind of effect this is.
// It will be either a built-in or a plug-in effect, and it
// will be one of Insert, Process, or Analyze.
virtual int GetEffectFlags() {
// Default of BUILTIN_EFFECT | PROCESS_EFFECT | ADVANCED_EFFECT (set in constructor) -
// covers most built-in effects.
return mFlags;
}
// Return true if the effect supports processing via batch chains.
virtual bool SupportsChains() {
// All builtin effect support chains (???)
return (mFlags & BUILTIN_EFFECT) != 0;
}
// Called to set or retrieve parameter values. Return true if successful.
virtual bool TransferParameters( Shuttle & WXUNUSED(shuttle) ) {
return true;
}
void SetEffectFlags( int NewFlags )
{
mFlags = NewFlags;
}
// The Effect class fully implements the Preview method for you.
// Only override it if you need to do preprocessing or cleanup.
virtual void Preview();
// 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);
// Get an unique ID assigned to each registered effect.
// The first effect will have ID zero.
int GetID() {
return mID;
}
// 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.
bool DoEffect(wxWindow *parent, int flags, double projectRate, TrackList *list,
TrackFactory *factory, double *t0, double *t1, wxString params);
wxString GetPreviewName();
//ANSWER-ME: Isn't this pointless?
// None of the built-in functions has an ampersand in the result of
// GetEffectName(), the only strings on which this method is used.
// In fact, the example 'E&qualizer' does not exist in the code!
// Strip ampersand ('&' char) from string. This effectively removes the
// shortcut from the string ('E&qualizer' becomes 'Equalizer'). This is
// important for sorting.
static wxString StripAmpersand(const wxString& str);
//
// protected virtual methods
//
// Each subclass of Effect overrides one or more of these methods to
// do its processing.
//
protected:
// 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();
// 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() {
return true;
}
// 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() {
return true;
}
// 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() = 0;
// clean up any temporary memory
virtual void End() {
}
//
// 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:
wxWindow *mParent;
ProgressDialog *mProgress;
double mProjectRate; // Sample rate of the project - new tracks should
// be created with this rate...
TrackFactory *mFactory;
TrackList *mTracks; // the complete list of all tracks
TrackList *mOutputTracks; // used only if CopyInputTracks() is called.
double mT0;
double mT1;
TimeWarper *mWarper;
//
// protected methods
//
// These methods can be used by subclasses of Effect in order to display a
// progress dialog or perform common calculations
//
protected:
// 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);
// 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, wxString = wxT(""));
// 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);
int GetNumWaveTracks() { return mNumTracks; }
int GetNumWaveGroups() { return mNumGroups; }
// Calculates the start time and selection length in samples
void GetSamples(WaveTrack *track, sampleCount *start, sampleCount *len);
void SetTimeWarper(TimeWarper *warper);
TimeWarper *GetTimeWarper();
//
// protected static data
//
// Preferences shared by all effects
//
protected:
static double sDefaultGenerateLen;
int mFlags;
double mLength;
// type of the tracks on mOutputTracks
int mOutputTracksType;
//
// private methods
//
// Use these two methods to copy the input tracks to mOutputTracks, if
// doing the processing on them, and replacing the originals only on success (and not cancel).
void CopyInputTracks(int trackType = Track::Wave);
// 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.
void AddToOutputTracks(Track *t);
// Used only by the base Effect class
//
private:
void CountWaveTracks();
//
// private data
//
// Used only by the base Effect class
//
private:
wxArrayPtrVoid mIMap;
wxArrayPtrVoid mOMap;
int mNumTracks; //v This is really mNumWaveTracks, per CountWaveTracks() and GetNumWaveTracks().
int mNumGroups;
int mID;
friend class BatchCommands;// so can call PromptUser.
friend class EffectManager;// so it can delete effects and access mID.
};
// Base dialog for generate effect
#define ID_EFFECT_PREVIEW ePreviewID
// Base dialog for regular effect
class AUDACITY_DLL_API EffectDialog:public wxDialog
{
public:
// constructors and destructors
EffectDialog(wxWindow * parent,
const wxString & title,
int type = PROCESS_EFFECT,
int flags = wxDEFAULT_DIALOG_STYLE);
void Init();
virtual void PopulateOrExchange(ShuttleGui & S);
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
virtual bool Validate();
virtual void OnPreview(wxCommandEvent & event);
private:
int mType;
};
// Utility functions
float TrapFloat(float x, float min, float max);
double TrapDouble(double x, double min, double max);
long TrapLong(long x, long min, long max);
#endif