2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
Effect.h
|
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
Vaughan Johnson
|
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef __AUDACITY_EFFECT__
|
|
|
|
#define __AUDACITY_EFFECT__
|
|
|
|
|
|
|
|
#include <set>
|
|
|
|
|
2014-12-02 08:55:02 +00:00
|
|
|
#include <wx/bmpbuttn.h>
|
2010-01-23 19:44:49 +00:00
|
|
|
#include <wx/dynarray.h>
|
2014-06-03 20:30:19 +00:00
|
|
|
#include <wx/intl.h>
|
2010-01-23 19:44:49 +00:00
|
|
|
#include <wx/string.h>
|
2014-12-16 21:41:58 +00:00
|
|
|
#include <wx/tglbtn.h>
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
class wxDialog;
|
|
|
|
class wxWindow;
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
#include "audacity/ConfigInterface.h"
|
|
|
|
#include "audacity/EffectInterface.h"
|
|
|
|
|
2014-10-18 14:19:38 +00:00
|
|
|
#include "../Experimental.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../WaveTrack.h"
|
2014-12-04 06:10:27 +00:00
|
|
|
#include "../SelectedRegion.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../Shuttle.h"
|
|
|
|
#include "../ShuttleGui.h"
|
|
|
|
#include "../Internat.h"
|
|
|
|
#include "../widgets/ProgressDialog.h"
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
#define BUILTIN_EFFECT_PREFIX wxT("Builtin Effect: ")
|
|
|
|
|
2014-10-05 17:10:09 +00:00
|
|
|
class SelectedRegion;
|
2010-01-23 19:44:49 +00:00
|
|
|
class TimeWarper;
|
2014-12-13 18:24:11 +00:00
|
|
|
class EffectUIHost;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// 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 : public wxEvtHandler,
|
|
|
|
public EffectClientInterface,
|
|
|
|
public EffectUIClientInterface,
|
|
|
|
public EffectHostInterface
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
{
|
2014-06-03 20:30:19 +00:00
|
|
|
//
|
2010-01-23 19:44:49 +00:00
|
|
|
// public methods
|
|
|
|
//
|
|
|
|
// Used by the outside program to determine properties of an effect and
|
|
|
|
// apply the effect to one or more tracks.
|
2014-06-03 20:30:19 +00:00
|
|
|
//
|
2010-01-23 19:44:49 +00:00
|
|
|
public:
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// 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();
|
|
|
|
|
|
|
|
// IdentInterface implementation
|
|
|
|
|
|
|
|
virtual wxString GetPath();
|
2014-12-15 21:54:23 +00:00
|
|
|
virtual wxString GetSymbol();
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual wxString GetName();
|
|
|
|
virtual wxString GetVendor();
|
|
|
|
virtual wxString GetVersion();
|
|
|
|
virtual wxString GetDescription();
|
|
|
|
|
|
|
|
// EffectIdentInterface implementation
|
|
|
|
|
|
|
|
virtual EffectType GetType();
|
|
|
|
virtual wxString GetFamily();
|
|
|
|
virtual bool IsInteractive();
|
|
|
|
virtual bool IsDefault();
|
|
|
|
virtual bool IsLegacy();
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool SupportsRealtime();
|
|
|
|
virtual bool SupportsAutomation();
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// EffectClientInterface implementation
|
|
|
|
|
|
|
|
virtual bool SetHost(EffectHostInterface *host);
|
|
|
|
|
|
|
|
virtual int GetAudioInCount();
|
|
|
|
virtual int GetAudioOutCount();
|
|
|
|
|
|
|
|
virtual int GetMidiInCount();
|
|
|
|
virtual int GetMidiOutCount();
|
|
|
|
|
|
|
|
virtual sampleCount GetLatency();
|
|
|
|
virtual sampleCount GetTailSize();
|
|
|
|
|
|
|
|
virtual void SetSampleRate(sampleCount rate);
|
|
|
|
virtual sampleCount SetBlockSize(sampleCount maxBlockSize);
|
|
|
|
|
|
|
|
virtual bool IsReady();
|
|
|
|
virtual bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap = NULL);
|
|
|
|
virtual bool ProcessFinalize();
|
|
|
|
virtual sampleCount ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen);
|
|
|
|
|
|
|
|
virtual bool RealtimeInitialize();
|
|
|
|
virtual bool RealtimeAddProcessor(int numChannels, float sampleRate);
|
|
|
|
virtual bool RealtimeFinalize();
|
|
|
|
virtual bool RealtimeSuspend();
|
|
|
|
virtual bool RealtimeResume();
|
|
|
|
virtual bool RealtimeProcessStart();
|
|
|
|
virtual sampleCount RealtimeProcess(int group,
|
|
|
|
float **inbuf,
|
|
|
|
float **outbuf,
|
|
|
|
sampleCount numSamples);
|
|
|
|
virtual bool RealtimeProcessEnd();
|
|
|
|
|
|
|
|
virtual bool ShowInterface(wxWindow *parent, bool forceModal = false);
|
|
|
|
|
|
|
|
virtual bool GetAutomationParameters(EffectAutomationParameters & parms);
|
|
|
|
virtual bool SetAutomationParameters(EffectAutomationParameters & parms);
|
|
|
|
|
|
|
|
virtual bool LoadUserPreset(const wxString & name);
|
|
|
|
virtual bool SaveUserPreset(const wxString & name);
|
|
|
|
|
|
|
|
virtual wxArrayString GetFactoryPresets();
|
|
|
|
virtual bool LoadFactoryPreset(int id);
|
|
|
|
virtual bool LoadFactoryDefaults();
|
|
|
|
|
|
|
|
// EffectUIClientInterface implementation
|
|
|
|
|
|
|
|
virtual void SetHostUI(EffectUIHostInterface *host);
|
|
|
|
virtual bool PopulateUI(wxWindow *parent);
|
|
|
|
virtual bool IsGraphicalUI();
|
|
|
|
virtual bool ValidateUI();
|
|
|
|
virtual bool HideUI();
|
|
|
|
virtual bool CloseUI();
|
|
|
|
|
|
|
|
virtual bool CanExportPresets();
|
|
|
|
virtual void ExportPresets();
|
|
|
|
virtual void ImportPresets();
|
|
|
|
|
|
|
|
virtual bool HasOptions();
|
|
|
|
virtual void ShowOptions();
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// EffectHostInterface implementation
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
virtual double GetDefaultDuration();
|
2015-05-27 13:42:15 +00:00
|
|
|
virtual double GetDuration();
|
|
|
|
virtual wxString GetDurationFormat();
|
2015-04-20 00:44:10 +00:00
|
|
|
virtual void SetDuration(double duration);
|
2014-11-07 09:54:04 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual bool Apply();
|
|
|
|
virtual void Preview();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual wxDialog *CreateUI(wxWindow *parent, EffectUIClientInterface *client);
|
|
|
|
|
|
|
|
virtual wxString GetUserPresetsGroup(const wxString & name);
|
|
|
|
virtual wxString GetCurrentSettingsGroup();
|
|
|
|
virtual wxString GetFactoryDefaultsGroup();
|
2015-04-27 14:22:47 +00:00
|
|
|
virtual wxString GetSavedStateGroup();
|
2014-11-14 03:03:17 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// ConfigClientInterface implementation
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
virtual bool HasSharedConfigGroup(const wxString & group);
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool GetSharedConfigSubgroups(const wxString & group, wxArrayString & subgroups);
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString);
|
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, int & value, int defval = 0);
|
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, bool & value, bool defval = false);
|
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, float & value, float defval = 0.0);
|
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, double & value, double defval = 0.0);
|
|
|
|
virtual bool GetSharedConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0);
|
|
|
|
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const wxString & value);
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const int & value);
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const bool & value);
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const float & value);
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const double & value);
|
|
|
|
virtual bool SetSharedConfig(const wxString & group, const wxString & key, const sampleCount & value);
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool RemoveSharedConfigSubgroup(const wxString & group);
|
|
|
|
virtual bool RemoveSharedConfig(const wxString & group, const wxString & key);
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
virtual bool HasPrivateConfigGroup(const wxString & group);
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool GetPrivateConfigSubgroups(const wxString & group, wxArrayString & subgroups);
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString);
|
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, int & value, int defval = 0);
|
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, bool & value, bool defval = false);
|
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, float & value, float defval = 0.0);
|
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, double & value, double defval = 0.0);
|
|
|
|
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0);
|
|
|
|
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const wxString & value);
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const int & value);
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const bool & value);
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const float & value);
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const double & value);
|
|
|
|
virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const sampleCount & value);
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool RemovePrivateConfigSubgroup(const wxString & group);
|
|
|
|
virtual bool RemovePrivateConfig(const wxString & group, const wxString & key);
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// Effect implementation
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2015-01-19 16:28:48 +00:00
|
|
|
virtual PluginID GetID();
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2014-11-05 20:41:29 +00:00
|
|
|
virtual bool Startup(EffectClientInterface *client);
|
2015-04-17 03:53:42 +00:00
|
|
|
virtual bool Startup();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
virtual bool GetAutomationParameters(wxString & parms);
|
|
|
|
virtual bool SetAutomationParameters(const wxString & parms);
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
virtual wxArrayString GetUserPresets();
|
|
|
|
virtual bool HasCurrentSettings();
|
|
|
|
virtual bool HasFactoryDefaults();
|
2015-04-27 10:02:56 +00:00
|
|
|
virtual wxString GetPreset(wxWindow * parent, const wxString & parms);
|
2015-04-26 21:41:05 +00:00
|
|
|
|
|
|
|
virtual bool IsBatchProcessing();
|
2015-04-27 14:22:47 +00:00
|
|
|
virtual void SetBatchProcessing(bool start);
|
2015-04-26 21:41:05 +00:00
|
|
|
|
2014-10-24 20:27:04 +00:00
|
|
|
void SetPresetParameters( const wxArrayString * Names, const wxArrayString * Values ){
|
|
|
|
if( Names ) mPresetNames = *Names;
|
|
|
|
if( Values ) mPresetValues = *Values;
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// 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.
|
2015-04-17 03:53:42 +00:00
|
|
|
bool DoEffect(wxWindow *parent, double projectRate, TrackList *list,
|
2014-10-05 17:10:09 +00:00
|
|
|
TrackFactory *factory, SelectedRegion *selectedRegion,
|
2015-04-17 03:53:42 +00:00
|
|
|
bool shouldPrompt = true);
|
2014-11-03 06:48:54 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// Realtime Effect Processing
|
2015-01-02 05:24:43 +00:00
|
|
|
bool RealtimeAddProcessor(int group, int chans, float rate);
|
2014-11-03 06:48:54 +00:00
|
|
|
sampleCount RealtimeProcess(int group,
|
|
|
|
int chans,
|
|
|
|
float **inbuf,
|
|
|
|
float **outbuf,
|
|
|
|
sampleCount numSamples);
|
2014-12-13 18:24:11 +00:00
|
|
|
bool IsRealtimeActive();
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
virtual bool IsHidden();
|
2015-04-26 21:41:05 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
//
|
|
|
|
// protected virtual methods
|
|
|
|
//
|
|
|
|
// Each subclass of Effect overrides one or more of these methods to
|
|
|
|
// do its processing.
|
|
|
|
//
|
|
|
|
protected:
|
2010-01-23 19:44:49 +00:00
|
|
|
// 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
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual bool Init();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// 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.
|
2015-04-26 21:41:05 +00:00
|
|
|
virtual bool PromptUser(wxWindow *parent);
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Check whether effect should be skipped
|
|
|
|
// Typically this is only useful in automation, for example
|
|
|
|
// detecting that zero noise reduction is to be done,
|
2014-06-03 20:30:19 +00:00
|
|
|
// or that normalisation is being done without Dc bias shift
|
2010-01-23 19:44:49 +00:00
|
|
|
// or amplitude modification
|
|
|
|
virtual bool CheckWhetherSkipEffect() { return false; }
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Actually do the effect here.
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual bool Process();
|
2015-04-17 03:53:42 +00:00
|
|
|
virtual bool ProcessPass();
|
|
|
|
virtual bool InitPass1();
|
|
|
|
virtual bool InitPass2();
|
|
|
|
virtual int GetPass();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// clean up any temporary memory
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
virtual void End();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// 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);
|
2014-10-24 20:27:04 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// 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();
|
|
|
|
virtual bool TransferDataFromWindow();
|
|
|
|
virtual bool EnableApply(bool enable = true);
|
|
|
|
virtual bool EnablePreview(bool enable = true);
|
2015-04-22 20:55:58 +00:00
|
|
|
virtual void EnableDebug(bool enable = true);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// 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).
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Pass a fraction between 0.0 and 1.0
|
|
|
|
bool TotalProgress(double frac);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Pass a fraction between 0.0 and 1.0, for the current track
|
|
|
|
// (when doing one track at a time)
|
2012-05-03 22:28:58 +00:00
|
|
|
bool TrackProgress(int whichTrack, double frac, wxString = wxT(""));
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// 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();
|
|
|
|
|
2015-05-15 11:47:51 +00:00
|
|
|
// 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);
|
|
|
|
|
2015-05-28 16:31:07 +00:00
|
|
|
// 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);
|
|
|
|
|
2015-05-15 15:57:29 +00:00
|
|
|
// 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);
|
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
// Use these two methods to copy the input tracks to mOutputTracks, if
|
2010-01-23 19:44:49 +00:00
|
|
|
// doing the processing on them, and replacing the originals only on success (and not cancel).
|
|
|
|
void CopyInputTracks(int trackType = Track::Wave);
|
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
// If bGoodResult, replace mWaveTracks tracks in mTracks with successfully processed
|
|
|
|
// mOutputTracks copies, get rid of old mWaveTracks, and set mWaveTracks to mOutputTracks.
|
2010-01-23 19:44:49 +00:00
|
|
|
// Else clear and delete mOutputTracks copies.
|
|
|
|
void ReplaceProcessedTracks(const bool bGoodResult);
|
|
|
|
|
|
|
|
// Use this to append a new output track.
|
|
|
|
void AddToOutputTracks(Track *t);
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
double mProjectRate; // Sample rate of the project - new tracks should
|
|
|
|
// be created with this rate...
|
|
|
|
double mSampleRate;
|
|
|
|
TrackFactory *mFactory;
|
|
|
|
TrackList *mTracks; // the complete list of all tracks
|
|
|
|
TrackList *mOutputTracks; // used only if CopyInputTracks() is called.
|
|
|
|
double mT0;
|
|
|
|
double mT1;
|
|
|
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
|
|
|
double mF0;
|
|
|
|
double mF1;
|
|
|
|
#endif
|
|
|
|
TimeWarper *mWarper;
|
|
|
|
wxArrayString mPresetNames;
|
|
|
|
wxArrayString mPresetValues;
|
|
|
|
int mPass;
|
|
|
|
|
|
|
|
// UI
|
|
|
|
wxDialog *mUIDialog;
|
|
|
|
wxWindow *mUIParent;
|
2015-04-22 20:55:58 +00:00
|
|
|
int mUIResultID;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
sampleCount mSampleCnt;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
// type of the tracks on mOutputTracks
|
2015-04-22 20:55:58 +00:00
|
|
|
int mOutputTracksType;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Used only by the base Effect class
|
|
|
|
//
|
|
|
|
private:
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
void CommonInit();
|
2010-01-23 19:44:49 +00:00
|
|
|
void CountWaveTracks();
|
2014-06-03 20:30:19 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// Driver for client effects
|
|
|
|
bool ProcessTrack(int count,
|
2015-04-17 03:53:42 +00:00
|
|
|
ChannelNames map,
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
WaveTrack *left,
|
|
|
|
WaveTrack *right,
|
|
|
|
sampleCount leftStart,
|
|
|
|
sampleCount rightStart,
|
|
|
|
sampleCount len);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
//
|
|
|
|
// private data
|
|
|
|
//
|
|
|
|
// Used only by the base Effect class
|
|
|
|
//
|
2015-04-17 03:53:42 +00:00
|
|
|
private:
|
|
|
|
wxWindow *mParent;
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
bool mIsBatch;
|
|
|
|
|
2015-05-15 11:47:51 +00:00
|
|
|
bool mIsLinearEffect;
|
2015-05-15 15:57:29 +00:00
|
|
|
bool mPreviewWithNotSelected;
|
2015-05-28 16:31:07 +00:00
|
|
|
bool mPreviewFullSelection;
|
2015-05-15 11:47:51 +00:00
|
|
|
|
2015-05-27 13:42:15 +00:00
|
|
|
bool mIsSelection;
|
2015-04-20 00:44:10 +00:00
|
|
|
double mDuration;
|
2015-05-27 13:42:15 +00:00
|
|
|
wxString mDurationFormat;
|
2015-05-28 16:31:07 +00:00
|
|
|
|
|
|
|
bool mIsPreview;
|
2015-04-20 00:44:10 +00:00
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
bool mUIDebug;
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
wxArrayPtrVoid mIMap;
|
|
|
|
wxArrayPtrVoid mOMap;
|
|
|
|
|
|
|
|
int mNumTracks; //v This is really mNumWaveTracks, per CountWaveTracks() and GetNumWaveTracks().
|
|
|
|
int mNumGroups;
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
// For client driver
|
|
|
|
EffectClientInterface *mClient;
|
|
|
|
int mNumAudioIn;
|
|
|
|
int mNumAudioOut;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
float **mInBuffer;
|
|
|
|
float **mOutBuffer;
|
|
|
|
float **mInBufPos;
|
|
|
|
float **mOutBufPos;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
sampleCount mBufferSize;
|
|
|
|
sampleCount mBlockSize;
|
|
|
|
int mNumChannels;
|
|
|
|
|
2015-01-02 05:24:43 +00:00
|
|
|
wxArrayInt mGroupProcessor;
|
|
|
|
int mCurrentProcessor;
|
2014-11-03 22:47:55 +00:00
|
|
|
|
2014-12-13 18:24:11 +00:00
|
|
|
wxCriticalSection mRealtimeSuspendLock;
|
|
|
|
int mRealtimeSuspendCount;
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
const static wxString kUserPresetIdent;
|
|
|
|
const static wxString kFactoryPresetIdent;
|
|
|
|
const static wxString kCurrentSettingsIdent;
|
|
|
|
const static wxString kFactoryDefaultsIdent;
|
|
|
|
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
friend class EffectManager;// so it can call PromptUser in support of batch commands.
|
|
|
|
friend class EffectRack;
|
2015-04-17 03:53:42 +00:00
|
|
|
friend class EffectUIHost;
|
2015-04-26 21:41:05 +00:00
|
|
|
friend class EffectPresetsDialog;
|
The fabled realtime effects...
I've made it where you can enable and disable via experimentals:
EXPERIMENTAL_REALTIME_EFFECTS
EXPERIMENTAL_EFFECTS_RACK
You will notice that, as of now, the only effects currently set up for
realtime are VSTs. Now that this is in, I will start converting the
rest.
As I start to convert the effects, the astute of you may notice that
they no longer directly access tracks or any "internal" Audacity
objects. This isolates the effects from changes in Audacity and makes
it much easier to add new ones.
Anyway, all 3 platforms can now display VST effects in graphical mode.
Yes, that means Linux too. There are quite a few VSTs for Linux if
you search for them.
The so-called "rack" definitely needs some discussion, work, and attention
from someone much better at graphics than me. I'm not really sure it should
stay in as-is. I'd originally planned for it to be simply a utility window
where you can store your (preconfigured) favorite effects. It should probably
revert back to that idea.
You may notice that this DOES include the API work I did. The realtime effects
were too tied to it and I didn't want to redo the whole thing. As I mentioned
elsewhere, the API stuff may or may not be very future proof.
So, let the critter complaints commence. I absolute KNOW there will be some.
(I know I'll be hearing from the Linux peeps pretty darn quickly. ;-))
2014-10-26 03:24:10 +00:00
|
|
|
};
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
// FIXME:
|
|
|
|
// FIXME: Remove this once all effects are using the new dialog
|
|
|
|
// FIXME:
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#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,
|
2015-04-17 03:53:42 +00:00
|
|
|
int type = 0,
|
2013-05-02 23:41:27 +00:00
|
|
|
int flags = wxDEFAULT_DIALOG_STYLE,
|
|
|
|
int additionalButtons = 0);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
void Init();
|
|
|
|
|
|
|
|
virtual void PopulateOrExchange(ShuttleGui & S);
|
|
|
|
virtual bool TransferDataToWindow();
|
|
|
|
virtual bool TransferDataFromWindow();
|
|
|
|
virtual bool Validate();
|
2015-04-17 03:53:42 +00:00
|
|
|
virtual void OnPreview(wxCommandEvent & evt);
|
|
|
|
virtual void OnOk(wxCommandEvent & evt);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
int mType;
|
2013-05-02 23:41:27 +00:00
|
|
|
int mAdditionalButtons;
|
2014-12-12 08:53:28 +00:00
|
|
|
|
|
|
|
DECLARE_EVENT_TABLE();
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
//
|
|
|
|
class EffectUIHost : public wxDialog,
|
|
|
|
public EffectUIHostInterface
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// constructors and destructors
|
|
|
|
EffectUIHost(wxWindow *parent,
|
2014-11-27 12:22:41 +00:00
|
|
|
Effect *effect,
|
2014-11-14 03:03:17 +00:00
|
|
|
EffectUIClientInterface *client);
|
|
|
|
virtual ~EffectUIHost();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
#if defined(__WXMAC__)
|
|
|
|
virtual bool Show(bool show = true);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
virtual bool TransferDataToWindow();
|
|
|
|
virtual bool TransferDataFromWindow();
|
|
|
|
|
|
|
|
virtual int ShowModal();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool Initialize();
|
|
|
|
|
|
|
|
private:
|
2015-04-29 08:26:47 +00:00
|
|
|
void OnInitDialog(wxInitDialogEvent & evt);
|
2015-04-17 03:53:42 +00:00
|
|
|
void OnErase(wxEraseEvent & evt);
|
|
|
|
void OnPaint(wxPaintEvent & evt);
|
2014-12-04 06:10:27 +00:00
|
|
|
void OnClose(wxCloseEvent & evt);
|
|
|
|
void OnApply(wxCommandEvent & evt);
|
|
|
|
void OnCancel(wxCommandEvent & evt);
|
2015-04-22 20:55:58 +00:00
|
|
|
void OnDebug(wxCommandEvent & evt);
|
2014-12-02 08:55:02 +00:00
|
|
|
void OnMenu(wxCommandEvent & evt);
|
2014-12-19 06:57:22 +00:00
|
|
|
void OnEnable(wxCommandEvent & evt);
|
2014-12-02 08:55:02 +00:00
|
|
|
void OnPlay(wxCommandEvent & evt);
|
|
|
|
void OnRewind(wxCommandEvent & evt);
|
|
|
|
void OnFFwd(wxCommandEvent & evt);
|
|
|
|
void OnPlayback(wxCommandEvent & evt);
|
|
|
|
void OnCapture(wxCommandEvent & evt);
|
2014-12-04 06:10:27 +00:00
|
|
|
void OnUserPreset(wxCommandEvent & evt);
|
|
|
|
void OnFactoryPreset(wxCommandEvent & evt);
|
|
|
|
void OnDeletePreset(wxCommandEvent & evt);
|
2014-11-14 03:03:17 +00:00
|
|
|
void OnSaveAs(wxCommandEvent & evt);
|
|
|
|
void OnImport(wxCommandEvent & evt);
|
|
|
|
void OnExport(wxCommandEvent & evt);
|
|
|
|
void OnOptions(wxCommandEvent & evt);
|
|
|
|
void OnDefaults(wxCommandEvent & evt);
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void UpdateControls();
|
|
|
|
wxBitmap CreateBitmap(const char *xpm[], bool up, bool pusher);
|
2014-11-14 03:03:17 +00:00
|
|
|
void LoadUserPresets();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void InitializeRealtime();
|
|
|
|
void CleanupRealtime();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
private:
|
2014-12-19 16:38:56 +00:00
|
|
|
AudacityProject *mProject;
|
2014-11-14 03:03:17 +00:00
|
|
|
wxWindow *mParent;
|
2014-11-27 12:22:41 +00:00
|
|
|
Effect *mEffect;
|
2014-11-14 03:03:17 +00:00
|
|
|
EffectUIClientInterface *mClient;
|
|
|
|
|
|
|
|
wxArrayString mUserPresets;
|
2014-11-27 12:22:41 +00:00
|
|
|
bool mInitialized;
|
2015-04-17 03:53:42 +00:00
|
|
|
bool mSupportsRealtime;
|
2014-12-16 21:41:58 +00:00
|
|
|
bool mIsGUI;
|
2015-04-26 21:41:05 +00:00
|
|
|
bool mIsBatch;
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
#if defined(__WXMAC__)
|
|
|
|
bool mIsModal;
|
|
|
|
#endif
|
|
|
|
|
2014-12-02 08:55:02 +00:00
|
|
|
wxButton *mApplyBtn;
|
|
|
|
wxButton *mCloseBtn;
|
2014-12-16 21:41:58 +00:00
|
|
|
wxButton *mMenuBtn;
|
|
|
|
wxButton *mPlayBtn;
|
|
|
|
wxButton *mRewindBtn;
|
|
|
|
wxButton *mFFwdBtn;
|
2014-12-20 18:22:44 +00:00
|
|
|
wxCheckBox *mEnableCb;
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2014-12-19 06:57:22 +00:00
|
|
|
wxButton *mEnableToggleBtn;
|
2014-12-16 21:41:58 +00:00
|
|
|
wxButton *mPlayToggleBtn;
|
2014-12-02 08:55:02 +00:00
|
|
|
|
|
|
|
wxBitmap mPlayBM;
|
|
|
|
wxBitmap mPlayDisabledBM;
|
|
|
|
wxBitmap mStopBM;
|
|
|
|
wxBitmap mStopDisabledBM;
|
|
|
|
|
2014-12-20 18:22:44 +00:00
|
|
|
bool mEnabled;
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
bool mDisableTransport;
|
2014-12-02 08:55:02 +00:00
|
|
|
bool mPlaying;
|
|
|
|
bool mCapturing;
|
2014-12-04 06:10:27 +00:00
|
|
|
|
|
|
|
SelectedRegion mRegion;
|
|
|
|
double mPlayPos;
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
DECLARE_EVENT_TABLE();
|
|
|
|
};
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
class EffectPresetsDialog : public wxDialog
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
EffectPresetsDialog(wxWindow *parent, Effect *effect);
|
|
|
|
virtual ~EffectPresetsDialog();
|
|
|
|
|
|
|
|
wxString GetSelected() const;
|
2015-04-27 10:02:56 +00:00
|
|
|
void SetSelected(const wxString & parms);
|
2015-04-26 21:41:05 +00:00
|
|
|
|
|
|
|
private:
|
2015-04-27 10:02:56 +00:00
|
|
|
void SetPrefix(const wxString & type, const wxString & prefix);
|
2015-04-26 21:41:05 +00:00
|
|
|
void UpdateUI();
|
|
|
|
|
|
|
|
void OnType(wxCommandEvent & evt);
|
|
|
|
void OnOk(wxCommandEvent & evt);
|
|
|
|
void OnCancel(wxCommandEvent & evt);
|
|
|
|
|
|
|
|
private:
|
|
|
|
wxChoice *mType;
|
|
|
|
wxListBox *mPresets;
|
|
|
|
|
|
|
|
wxArrayString mFactoryPresets;
|
|
|
|
wxArrayString mUserPresets;
|
|
|
|
wxString mSelection;
|
|
|
|
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
|
|
};
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Utility functions
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
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; \
|
|
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name, MIN_ ## name, MAX_ ## name)) \
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#define ReadBasic(type, name) \
|
|
|
|
type name; \
|
|
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name)) \
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#define ReadAndVerifyEnum(name, list) \
|
|
|
|
int name; \
|
|
|
|
if (!parms.ReadAndVerify(KEY_ ## name, &name, DEF_ ## name, list)) \
|
|
|
|
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)
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#endif
|