337 lines
10 KiB
C++
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
|
|
|