2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
Effect.cpp
|
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
Vaughan Johnson
|
|
|
|
Martyn Shaw
|
|
|
|
|
|
|
|
*******************************************************************//**
|
|
|
|
|
|
|
|
\class Effect
|
|
|
|
\brief Base class for many of the effects in Audacity.
|
|
|
|
|
|
|
|
*//****************************************************************//**
|
|
|
|
|
|
|
|
\class EffectDialog
|
2014-06-03 20:30:19 +00:00
|
|
|
\brief New (Jun-2006) base class for effects dialogs. Likely to get
|
2010-01-23 19:44:49 +00:00
|
|
|
greater use in future.
|
|
|
|
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
|
|
|
#include "../Audacity.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "Effect.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-01-21 15:41:03 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
#include <wx/defs.h>
|
2015-04-27 18:16:08 +00:00
|
|
|
#include <wx/hashmap.h>
|
2010-01-23 19:44:49 +00:00
|
|
|
#include <wx/msgdlg.h>
|
|
|
|
#include <wx/sizer.h>
|
2015-04-27 18:16:08 +00:00
|
|
|
#include <wx/stockitem.h>
|
|
|
|
#include <wx/string.h>
|
2014-12-02 08:55:02 +00:00
|
|
|
#include <wx/tglbtn.h>
|
2015-04-27 18:16:08 +00:00
|
|
|
#include <wx/timer.h>
|
2014-12-12 14:44:50 +00:00
|
|
|
#include <wx/utils.h>
|
2015-05-28 16:31:07 +00:00
|
|
|
#include <wx/log.h>
|
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
|
|
|
#include "audacity/ConfigInterface.h"
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../AudioIO.h"
|
2016-02-27 19:24:57 +00:00
|
|
|
#include "../LabelTrack.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../Mix.h"
|
|
|
|
#include "../Prefs.h"
|
|
|
|
#include "../Project.h"
|
2015-06-18 14:24:36 +00:00
|
|
|
#include "../ShuttleGui.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../WaveTrack.h"
|
2014-12-04 06:10:27 +00:00
|
|
|
#include "../toolbars/ControlToolBar.h"
|
2014-12-02 08:55:02 +00:00
|
|
|
#include "../widgets/AButton.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "../widgets/ProgressDialog.h"
|
|
|
|
#include "../ondemand/ODManager.h"
|
|
|
|
#include "TimeWarper.h"
|
2015-05-28 16:31:07 +00:00
|
|
|
#include "nyquist/Nyquist.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-07-12 00:33:04 +00:00
|
|
|
#if defined(__WXMAC__)
|
|
|
|
#include <Cocoa/Cocoa.h>
|
|
|
|
#endif
|
|
|
|
|
2015-08-31 19:50:50 +00:00
|
|
|
#include "../Experimental.h"
|
|
|
|
|
2015-07-18 04:18:55 +00:00
|
|
|
static const int kDummyID = 20000;
|
|
|
|
static const int kSaveAsID = 20001;
|
|
|
|
static const int kImportID = 20002;
|
|
|
|
static const int kExportID = 20003;
|
|
|
|
static const int kDefaultsID = 20004;
|
|
|
|
static const int kOptionsID = 20005;
|
|
|
|
static const int kUserPresetsDummyID = 20006;
|
|
|
|
static const int kDeletePresetDummyID = 20007;
|
|
|
|
static const int kMenuID = 20100;
|
|
|
|
static const int kEnableID = 20101;
|
|
|
|
static const int kPlayID = 20102;
|
|
|
|
static const int kRewindID = 20103;
|
|
|
|
static const int kFFwdID = 20104;
|
|
|
|
static const int kPlaybackID = 20105;
|
|
|
|
static const int kCaptureID = 20106;
|
|
|
|
static const int kUserPresetsID = 21000;
|
|
|
|
static const int kDeletePresetID = 22000;
|
|
|
|
static const int kFactoryPresetsID = 23000;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
const wxString Effect::kUserPresetIdent = wxT("User Preset:");
|
|
|
|
const wxString Effect::kFactoryPresetIdent = wxT("Factory Preset:");
|
|
|
|
const wxString Effect::kCurrentSettingsIdent = wxT("<Current Settings>");
|
|
|
|
const wxString Effect::kFactoryDefaultsIdent = wxT("<Factory Defaults>");
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
WX_DECLARE_VOIDPTR_HASH_MAP( bool, t2bHash );
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
Effect::Effect()
|
|
|
|
{
|
2014-11-14 03:03:17 +00:00
|
|
|
mParent = NULL;
|
|
|
|
|
2014-11-05 20:41:29 +00:00
|
|
|
mClient = NULL;
|
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-11-05 20:41:29 +00:00
|
|
|
mWarper = NULL;
|
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-11-05 20:41:29 +00:00
|
|
|
mTracks = NULL;
|
|
|
|
mOutputTracks = NULL;
|
|
|
|
mOutputTracksType = Track::None;
|
2015-05-13 04:19:56 +00:00
|
|
|
mT0 = 0.0;
|
|
|
|
mT1 = 0.0;
|
2014-11-07 09:54:04 +00:00
|
|
|
mDuration = 0.0;
|
2015-05-28 16:31:07 +00:00
|
|
|
mIsPreview = false;
|
2015-05-15 11:47:51 +00:00
|
|
|
mIsLinearEffect = false;
|
2015-05-15 15:57:29 +00:00
|
|
|
mPreviewWithNotSelected = false;
|
2015-05-28 16:31:07 +00:00
|
|
|
mPreviewFullSelection = false;
|
2014-11-05 20:41:29 +00:00
|
|
|
mNumTracks = 0;
|
|
|
|
mNumGroups = 0;
|
|
|
|
mProgress = NULL;
|
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-12-13 18:24:11 +00:00
|
|
|
mRealtimeSuspendLock.Enter();
|
|
|
|
mRealtimeSuspendCount = 1; // Effects are initially suspended
|
|
|
|
mRealtimeSuspendLock.Leave();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mUIParent = NULL;
|
|
|
|
mUIDialog = NULL;
|
2014-11-05 20:41:29 +00:00
|
|
|
|
|
|
|
mNumAudioIn = 0;
|
|
|
|
mNumAudioOut = 0;
|
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
|
|
|
|
|
|
|
mInBuffer = NULL;
|
|
|
|
mOutBuffer = NULL;
|
|
|
|
mInBufPos = NULL;
|
|
|
|
mOutBufPos = NULL;
|
|
|
|
|
|
|
|
mBufferSize = 0;
|
|
|
|
mBlockSize = 0;
|
|
|
|
mNumChannels = 0;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
mUIDebug = false;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
AudacityProject *p = GetActiveProject();
|
|
|
|
mProjectRate = p ? p->GetRate() : 44100;
|
2015-04-26 21:41:05 +00:00
|
|
|
|
|
|
|
mIsBatch = false;
|
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::~Effect()
|
|
|
|
{
|
2015-04-26 21:41:05 +00:00
|
|
|
if (mOutputTracks)
|
|
|
|
{
|
|
|
|
delete mOutputTracks;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (mWarper != NULL)
|
|
|
|
{
|
|
|
|
delete mWarper;
|
|
|
|
}
|
2015-04-26 21:41:05 +00:00
|
|
|
|
|
|
|
if (mUIDialog)
|
|
|
|
{
|
|
|
|
mUIDialog->Close();
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// EffectIdentInterface implementation
|
|
|
|
|
|
|
|
EffectType Effect::GetType()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetType();
|
|
|
|
}
|
|
|
|
|
|
|
|
return EffectTypeNone;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetPath()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetPath();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return BUILTIN_EFFECT_PREFIX + 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
|
|
|
}
|
|
|
|
|
2014-12-15 21:54:23 +00:00
|
|
|
wxString Effect::GetSymbol()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetSymbol();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return wxEmptyString;
|
2014-12-15 21:54:23 +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
|
|
|
wxString Effect::GetName()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetName();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return 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
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetVendor()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetVendor();
|
|
|
|
}
|
|
|
|
|
2015-06-05 23:56:24 +00:00
|
|
|
return XO("Audacity");
|
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
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetVersion()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetVersion();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return AUDACITY_VERSION_STRING;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetDescription()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetDescription();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return wxEmptyString;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetFamily()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetFamily();
|
|
|
|
}
|
|
|
|
|
2015-06-05 23:56:24 +00:00
|
|
|
return XO("Audacity");
|
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-11-14 03:03:17 +00:00
|
|
|
bool Effect::IsInteractive()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->IsInteractive();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
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
|
|
|
bool Effect::IsDefault()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->IsDefault();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::IsLegacy()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool Effect::SupportsRealtime()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->SupportsRealtime();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool Effect::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
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
2014-11-14 03:03:17 +00:00
|
|
|
return mClient->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
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// EffectClientInterface implementation
|
|
|
|
|
|
|
|
bool Effect::SetHost(EffectHostInterface *host)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->SetHost(host);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Effect::GetAudioInCount()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetAudioInCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Effect::GetAudioOutCount()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetAudioOutCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Effect::GetMidiInCount()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetMidiInCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Effect::GetMidiOutCount()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetMidiOutCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::SetSampleRate(sampleCount rate)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
mClient->SetSampleRate(rate);
|
|
|
|
}
|
|
|
|
|
|
|
|
mSampleRate = rate;
|
|
|
|
}
|
|
|
|
|
|
|
|
sampleCount Effect::SetBlockSize(sampleCount maxBlockSize)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->SetBlockSize(maxBlockSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
mBlockSize = maxBlockSize;
|
|
|
|
|
|
|
|
return mBlockSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
sampleCount Effect::GetLatency()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetLatency();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sampleCount Effect::GetTailSize()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetTailSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::IsReady()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->IsReady();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::ProcessInitialize(sampleCount totalLen, ChannelNames chanMap)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->ProcessInitialize(totalLen, chanMap);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::ProcessFinalize()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->ProcessFinalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
sampleCount Effect::ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->ProcessBlock(inBlock, outBlock, blockLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeInitialize()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
mBlockSize = mClient->SetBlockSize(512);
|
|
|
|
return mClient->RealtimeInitialize();
|
|
|
|
}
|
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
mBlockSize = 512;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeAddProcessor(int numChannels, float sampleRate)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->RealtimeAddProcessor(numChannels, sampleRate);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeFinalize()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->RealtimeFinalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeSuspend()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
if (mClient->RealtimeSuspend())
|
|
|
|
{
|
|
|
|
mRealtimeSuspendLock.Enter();
|
|
|
|
mRealtimeSuspendCount++;
|
|
|
|
mRealtimeSuspendLock.Leave();
|
|
|
|
return true;
|
|
|
|
}
|
2015-08-01 12:03:02 +00:00
|
|
|
|
|
|
|
return false;
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
mRealtimeSuspendLock.Enter();
|
|
|
|
mRealtimeSuspendCount++;
|
|
|
|
mRealtimeSuspendLock.Leave();
|
|
|
|
|
|
|
|
return true;
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeResume()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
if (mClient->RealtimeResume())
|
|
|
|
{
|
|
|
|
mRealtimeSuspendLock.Enter();
|
|
|
|
mRealtimeSuspendCount--;
|
|
|
|
mRealtimeSuspendLock.Leave();
|
|
|
|
return true;
|
|
|
|
}
|
2015-08-01 12:03:02 +00:00
|
|
|
|
|
|
|
return false;
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
|
|
|
|
2015-08-01 12:03:02 +00:00
|
|
|
mRealtimeSuspendLock.Enter();
|
|
|
|
mRealtimeSuspendCount--;
|
|
|
|
mRealtimeSuspendLock.Leave();
|
|
|
|
|
|
|
|
return true;
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeProcessStart()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->RealtimeProcessStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
sampleCount Effect::RealtimeProcess(int group,
|
|
|
|
float **inbuf,
|
|
|
|
float **outbuf,
|
|
|
|
sampleCount numSamples)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->RealtimeProcess(group, inbuf, outbuf, numSamples);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RealtimeProcessEnd()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->RealtimeProcessEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::ShowInterface(wxWindow *parent, bool forceModal)
|
|
|
|
{
|
2015-04-26 21:41:05 +00:00
|
|
|
if (!IsInteractive())
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mUIDialog)
|
|
|
|
{
|
|
|
|
mUIDialog->Close(true);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->ShowInterface(parent, forceModal);
|
|
|
|
}
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
mParent = parent;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mUIDialog = CreateUI(parent, this);
|
|
|
|
if (!mUIDialog)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mUIDialog->Layout();
|
|
|
|
mUIDialog->Fit();
|
|
|
|
mUIDialog->SetMinSize(mUIDialog->GetSize());
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
if (SupportsRealtime() && !forceModal)
|
|
|
|
{
|
|
|
|
mUIDialog->Show();
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
// Return false to bypass effect processing
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool res = mUIDialog->ShowModal() != 0;
|
2015-04-17 03:53:42 +00:00
|
|
|
mUIDialog = NULL;
|
2015-04-26 21:41:05 +00:00
|
|
|
mParent = NULL;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetAutomationParameters(EffectAutomationParameters & parms)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetAutomationParameters(parms);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetAutomationParameters(EffectAutomationParameters & parms)
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->SetAutomationParameters(parms);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::LoadUserPreset(const wxString & name)
|
|
|
|
{
|
2015-04-23 13:17:33 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->LoadUserPreset(name);
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
wxString parms;
|
|
|
|
if (!GetPrivateConfig(name, wxT("Parameters"), parms))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SetAutomationParameters(parms);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SaveUserPreset(const wxString & name)
|
|
|
|
{
|
2015-04-23 13:17:33 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->SaveUserPreset(name);
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
wxString parms;
|
|
|
|
if (!GetAutomationParameters(parms))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SetPrivateConfig(name, wxT("Parameters"), parms);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxArrayString Effect::GetFactoryPresets()
|
|
|
|
{
|
2015-04-23 13:04:32 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->GetFactoryPresets();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return wxArrayString();
|
|
|
|
}
|
|
|
|
|
2015-04-23 13:04:32 +00:00
|
|
|
bool Effect::LoadFactoryPreset(int id)
|
2015-04-17 03:53:42 +00:00
|
|
|
{
|
2015-04-23 13:04:32 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->LoadFactoryPreset(id);
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::LoadFactoryDefaults()
|
|
|
|
{
|
2015-04-23 13:04:32 +00:00
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return mClient->LoadFactoryDefaults();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return LoadUserPreset(GetFactoryDefaultsGroup());
|
|
|
|
}
|
|
|
|
|
|
|
|
// EffectUIClientInterface implementation
|
|
|
|
|
|
|
|
void Effect::SetHostUI(EffectUIHostInterface *WXUNUSED(host))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::PopulateUI(wxWindow *parent)
|
|
|
|
{
|
|
|
|
mUIParent = parent;
|
|
|
|
mUIParent->PushEventHandler(this);
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
// LoadUserPreset(GetCurrentSettingsGroup());
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
ShuttleGui S(mUIParent, eIsCreating);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
|
|
|
|
mUIParent->SetMinSize(mUIParent->GetSizer()->GetMinSize());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::IsGraphicalUI()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::ValidateUI()
|
|
|
|
{
|
|
|
|
return mUIParent->Validate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::HideUI()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::CloseUI()
|
|
|
|
{
|
|
|
|
mUIParent->RemoveEventHandler(this);
|
|
|
|
|
|
|
|
mUIParent = NULL;
|
2015-08-01 12:03:02 +00:00
|
|
|
mUIDialog = NULL;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::CanExportPresets()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::ExportPresets()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::ImportPresets()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::HasOptions()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::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
|
|
|
double Effect::GetDefaultDuration()
|
|
|
|
{
|
|
|
|
return 30.0;
|
|
|
|
}
|
|
|
|
|
2015-05-27 13:42:15 +00:00
|
|
|
double Effect::GetDuration()
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
2015-04-20 00:44:10 +00:00
|
|
|
if (mDuration < 0.0)
|
|
|
|
{
|
|
|
|
mDuration = 0.0;
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
|
2015-04-20 00:44:10 +00:00
|
|
|
return mDuration;
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
|
2015-05-27 13:42:15 +00:00
|
|
|
wxString Effect::GetDurationFormat()
|
|
|
|
{
|
|
|
|
return mDurationFormat;
|
|
|
|
}
|
|
|
|
|
2015-07-18 17:31:36 +00:00
|
|
|
wxString Effect::GetSelectionFormat()
|
|
|
|
{
|
|
|
|
return GetActiveProject()->GetSelectionFormat();
|
|
|
|
}
|
|
|
|
|
2015-04-20 00:44:10 +00:00
|
|
|
void Effect::SetDuration(double seconds)
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
2015-04-20 00:44:10 +00:00
|
|
|
if (seconds < 0.0)
|
|
|
|
{
|
|
|
|
seconds = 0.0;
|
|
|
|
}
|
|
|
|
|
2015-05-27 13:42:15 +00:00
|
|
|
if (GetType() == EffectTypeGenerate)
|
2015-04-20 00:44:10 +00:00
|
|
|
{
|
|
|
|
SetPrivateConfig(GetCurrentSettingsGroup(), wxT("LastUsedDuration"), seconds);
|
|
|
|
}
|
|
|
|
|
2014-11-07 09:54:04 +00:00
|
|
|
mDuration = seconds;
|
|
|
|
|
2015-05-27 13:42:15 +00:00
|
|
|
mIsSelection = false;
|
|
|
|
|
2015-04-20 00:44:10 +00:00
|
|
|
return;
|
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
|
|
|
bool Effect::Apply()
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
// This is absolute hackage...but easy and I can't think of another way just now.
|
2014-11-07 09:54:04 +00:00
|
|
|
//
|
|
|
|
// It should callback to the EffectManager to kick off the processing
|
2015-04-17 03:53:42 +00:00
|
|
|
return GetActiveProject()->OnEffect(GetID(), AudacityProject::OnEffectFlags::kConfigured);
|
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 Effect::Preview()
|
|
|
|
{
|
|
|
|
Preview(false);
|
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
wxDialog *Effect::CreateUI(wxWindow *parent, EffectUIClientInterface *client)
|
|
|
|
{
|
|
|
|
EffectUIHost *dlg = new EffectUIHost(parent, this, client);
|
|
|
|
|
|
|
|
if (dlg->Initialize())
|
|
|
|
{
|
|
|
|
return dlg;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete dlg;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetUserPresetsGroup(const wxString & name)
|
|
|
|
{
|
|
|
|
wxString group = wxT("UserPresets");
|
|
|
|
if (!name.IsEmpty())
|
|
|
|
{
|
|
|
|
group += wxCONFIG_PATH_SEPARATOR + name;
|
|
|
|
}
|
|
|
|
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetCurrentSettingsGroup()
|
|
|
|
{
|
|
|
|
return wxT("CurrentSettings");
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString Effect::GetFactoryDefaultsGroup()
|
|
|
|
{
|
|
|
|
return wxT("FactoryDefaults");
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:22:47 +00:00
|
|
|
wxString Effect::GetSavedStateGroup()
|
|
|
|
{
|
|
|
|
return wxT("SavedState");
|
|
|
|
}
|
|
|
|
|
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
|
|
|
bool Effect::HasSharedConfigGroup(const wxString & group)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().HasSharedConfigGroup(GetID(), group);
|
|
|
|
}
|
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-11-14 03:03:17 +00:00
|
|
|
bool Effect::GetSharedConfigSubgroups(const wxString & group, wxArrayString & subgroups)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfigSubgroups(GetID(), group, 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
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, int & value, int defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, bool & value, bool defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, float & value, float defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, double & value, double defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetSharedConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const wxString & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const int & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const bool & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const float & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const double & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const sampleCount & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetSharedConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool Effect::RemoveSharedConfigSubgroup(const wxString & group)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().RemoveSharedConfigSubgroup(GetID(), group);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RemoveSharedConfig(const wxString & group, const wxString & key)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().RemoveSharedConfig(GetID(), group, key);
|
|
|
|
}
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
bool Effect::HasPrivateConfigGroup(const wxString & group)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().HasPrivateConfigGroup(GetID(), group);
|
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool Effect::GetPrivateConfigSubgroups(const wxString & group, wxArrayString & subgroups)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfigSubgroups(GetID(), group, 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
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, int & value, int defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, bool & value, bool defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, float & value, float defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, double & value, double defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const wxString & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const int & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const bool & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const float & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const double & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const sampleCount & value)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value);
|
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool Effect::RemovePrivateConfigSubgroup(const wxString & group)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().RemovePrivateConfigSubgroup(GetID(), group);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::RemovePrivateConfig(const wxString & group, const wxString & key)
|
|
|
|
{
|
|
|
|
return PluginManager::Get().RemovePrivateConfig(GetID(), group, 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
|
|
|
|
|
2015-01-19 16:28:48 +00:00
|
|
|
PluginID Effect::GetID()
|
|
|
|
{
|
|
|
|
if (mClient)
|
|
|
|
{
|
|
|
|
return PluginManager::GetID(mClient);
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return PluginManager::GetID(this);
|
2015-01-19 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2014-11-05 20:41:29 +00:00
|
|
|
bool Effect::Startup(EffectClientInterface *client)
|
|
|
|
{
|
2014-11-07 09:54:04 +00:00
|
|
|
// Let destructor know we need to be shutdown
|
|
|
|
mClient = client;
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
// Set host so client startup can use our services
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!SetHost(this))
|
2014-11-05 20:41:29 +00:00
|
|
|
{
|
2014-11-14 03:03:17 +00:00
|
|
|
// Bail if the client startup fails
|
2014-11-07 09:54:04 +00:00
|
|
|
mClient = NULL;
|
2014-11-05 20:41:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mNumAudioIn = GetAudioInCount();
|
|
|
|
mNumAudioOut = GetAudioOutCount();
|
2014-11-05 20:41:29 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool haveDefaults;
|
|
|
|
GetPrivateConfig(GetFactoryDefaultsGroup(), wxT("Initialized"), haveDefaults, false);
|
|
|
|
if (!haveDefaults)
|
2014-11-05 20:41:29 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
SaveUserPreset(GetFactoryDefaultsGroup());
|
|
|
|
SetPrivateConfig(GetFactoryDefaultsGroup(), wxT("Initialized"), true);
|
2014-11-05 20:41:29 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
LoadUserPreset(GetCurrentSettingsGroup());
|
2014-11-05 20:41:29 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return Startup();
|
2014-11-05 20:41:29 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool Effect::Startup()
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool Effect::GetAutomationParameters(wxString & parms)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
EffectAutomationParameters eap;
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mUIDialog && !TransferDataFromWindow())
|
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
|
|
|
return false;
|
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
|
|
|
if (!GetAutomationParameters(eap))
|
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
|
|
|
return false;
|
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
|
|
|
return eap.GetParameters(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-17 03:53:42 +00:00
|
|
|
bool Effect::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
|
|
|
wxString preset = parms;
|
|
|
|
bool success = false;
|
|
|
|
if (preset.StartsWith(kUserPresetIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(kUserPresetIdent, wxEmptyString, false);
|
|
|
|
success = LoadUserPreset(GetUserPresetsGroup(preset));
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(kFactoryPresetIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(kFactoryPresetIdent, wxEmptyString, false);
|
|
|
|
wxArrayString presets = GetFactoryPresets();
|
|
|
|
success = LoadFactoryPreset(presets.Index(preset));
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(kCurrentSettingsIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(kCurrentSettingsIdent, wxEmptyString, false);
|
|
|
|
success = LoadUserPreset(GetCurrentSettingsGroup());
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(kFactoryDefaultsIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(kFactoryDefaultsIdent, wxEmptyString, false);
|
|
|
|
success = LoadUserPreset(GetFactoryDefaultsGroup());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EffectAutomationParameters eap(parms);
|
|
|
|
success = SetAutomationParameters(eap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!success)
|
2015-04-17 03:53:42 +00:00
|
|
|
{
|
|
|
|
wxMessageBox(
|
|
|
|
wxString::Format(
|
2016-03-09 21:20:54 +00:00
|
|
|
_("%s: Could not load settings below. Default settings will be used.\n\n%s"),
|
2015-04-17 03:53:42 +00:00
|
|
|
GetName().c_str(),
|
2015-04-26 21:41:05 +00:00
|
|
|
preset.c_str()
|
2015-04-17 03:53:42 +00:00
|
|
|
)
|
|
|
|
);
|
2015-04-26 21:41:05 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mUIDialog)
|
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
|
|
|
return true;
|
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
|
|
|
return TransferDataToWindow();
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
wxArrayString Effect::GetUserPresets()
|
|
|
|
{
|
|
|
|
wxArrayString presets;
|
|
|
|
|
|
|
|
GetPrivateConfigSubgroups(GetUserPresetsGroup(wxEmptyString), presets);
|
|
|
|
|
|
|
|
presets.Sort();
|
|
|
|
|
|
|
|
return presets;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::HasCurrentSettings()
|
|
|
|
{
|
|
|
|
return HasPrivateConfigGroup(GetCurrentSettingsGroup());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::HasFactoryDefaults()
|
|
|
|
{
|
|
|
|
return HasPrivateConfigGroup(GetFactoryDefaultsGroup());
|
|
|
|
}
|
|
|
|
|
2015-04-27 10:02:56 +00:00
|
|
|
wxString Effect::GetPreset(wxWindow * parent, const wxString & parms)
|
2015-04-26 21:41:05 +00:00
|
|
|
{
|
|
|
|
EffectPresetsDialog dlg(parent, this);
|
|
|
|
dlg.Layout();
|
|
|
|
dlg.Fit();
|
|
|
|
dlg.SetSize(dlg.GetMinSize());
|
2015-04-28 02:14:47 +00:00
|
|
|
dlg.CenterOnParent();
|
2015-04-27 10:02:56 +00:00
|
|
|
dlg.SetSelected(parms);
|
2015-04-26 21:41:05 +00:00
|
|
|
|
|
|
|
if (dlg.ShowModal())
|
|
|
|
{
|
|
|
|
return dlg.GetSelected();
|
|
|
|
}
|
|
|
|
|
|
|
|
return wxEmptyString;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::IsBatchProcessing()
|
|
|
|
{
|
|
|
|
return mIsBatch;
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:22:47 +00:00
|
|
|
void Effect::SetBatchProcessing(bool start)
|
2015-04-26 21:41:05 +00:00
|
|
|
{
|
2015-04-27 14:22:47 +00:00
|
|
|
mIsBatch = start;
|
|
|
|
|
|
|
|
if (start)
|
|
|
|
{
|
|
|
|
SaveUserPreset(GetSavedStateGroup());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LoadUserPreset(GetSavedStateGroup());
|
|
|
|
}
|
2015-04-26 21:41:05 +00:00
|
|
|
}
|
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
namespace {
|
|
|
|
struct SetProgress {
|
|
|
|
SetProgress(ProgressDialog *& mProgress_, ProgressDialog *progress)
|
|
|
|
: mProgress(mProgress_)
|
|
|
|
{ mProgress = progress; }
|
|
|
|
~SetProgress() { mProgress = nullptr; }
|
|
|
|
ProgressDialog *& mProgress;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool Effect::DoEffect(wxWindow *parent,
|
2010-01-23 19:44:49 +00:00
|
|
|
double projectRate,
|
|
|
|
TrackList *list,
|
|
|
|
TrackFactory *factory,
|
2015-04-17 03:53:42 +00:00
|
|
|
SelectedRegion *selectedRegion,
|
|
|
|
bool shouldPrompt /* = true */)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-18 03:52:34 +00:00
|
|
|
wxASSERT(selectedRegion->duration() >= 0.0);
|
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
|
|
|
if (mOutputTracks)
|
|
|
|
{
|
2010-01-23 19:44:49 +00:00
|
|
|
delete mOutputTracks;
|
|
|
|
mOutputTracks = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mFactory = factory;
|
|
|
|
mProjectRate = projectRate;
|
|
|
|
mParent = parent;
|
|
|
|
mTracks = list;
|
2015-05-27 13:42:15 +00:00
|
|
|
|
|
|
|
bool isSelection = false;
|
|
|
|
|
|
|
|
mDuration = 0.0;
|
|
|
|
|
|
|
|
if (GetType() == EffectTypeGenerate)
|
|
|
|
{
|
|
|
|
GetPrivateConfig(GetCurrentSettingsGroup(), wxT("LastUsedDuration"), mDuration, GetDefaultDuration());
|
|
|
|
}
|
|
|
|
|
2015-04-18 03:52:34 +00:00
|
|
|
mT0 = selectedRegion->t0();
|
|
|
|
mT1 = selectedRegion->t1();
|
2015-05-27 13:42:15 +00:00
|
|
|
if (mT1 > mT0)
|
|
|
|
{
|
|
|
|
// there is a selection: let's fit in there...
|
|
|
|
// MJS: note that this is just for the TTC and is independent of the track rate
|
|
|
|
// but we do need to make sure we have the right number of samples at the project rate
|
|
|
|
double quantMT0 = QUANTIZED_TIME(mT0, mProjectRate);
|
|
|
|
double quantMT1 = QUANTIZED_TIME(mT1, mProjectRate);
|
|
|
|
mDuration = quantMT1 - quantMT0;
|
|
|
|
mT1 = mT0 + mDuration;
|
|
|
|
|
|
|
|
isSelection = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDurationFormat = isSelection ? _("hh:mm:ss + samples") : _("hh:mm:ss + milliseconds");
|
|
|
|
|
2014-10-18 14:19:38 +00:00
|
|
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
|
|
|
mF0 = selectedRegion->f0();
|
|
|
|
mF1 = selectedRegion->f1();
|
2014-10-24 20:27:04 +00:00
|
|
|
wxArrayString Names;
|
|
|
|
if( mF0 != SelectedRegion::UndefinedFrequency )
|
|
|
|
Names.Add(wxT("control-f0"));
|
|
|
|
if( mF1 != SelectedRegion::UndefinedFrequency )
|
|
|
|
Names.Add(wxT("control-f1"));
|
|
|
|
SetPresetParameters( &Names, NULL );
|
|
|
|
|
2014-10-18 14:19:38 +00:00
|
|
|
#endif
|
2010-01-23 19:44:49 +00:00
|
|
|
CountWaveTracks();
|
|
|
|
|
|
|
|
// Note: Init may read parameters from preferences
|
|
|
|
if (!Init())
|
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
|
|
|
return false;
|
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
|
|
|
// Prompting will be bypassed when applying an effect that has already
|
|
|
|
// been configured, e.g. repeating the last effect on a different selection.
|
2015-04-26 21:41:05 +00:00
|
|
|
if (shouldPrompt && IsInteractive() && !PromptUser(parent))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return false;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool returnVal = true;
|
|
|
|
bool skipFlag = CheckWhetherSkipEffect();
|
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
|
|
|
if (skipFlag == false)
|
|
|
|
{
|
2016-02-01 01:39:24 +00:00
|
|
|
ProgressDialog progress(GetName(),
|
|
|
|
wxString::Format(_("Applying %s..."), GetName().c_str()),
|
|
|
|
pdlgHideStopButton);
|
|
|
|
SetProgress sp(mProgress, &progress);
|
2010-01-23 19:44:49 +00:00
|
|
|
returnVal = Process();
|
|
|
|
}
|
|
|
|
|
|
|
|
End();
|
|
|
|
|
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
|
|
|
if (mOutputTracks)
|
|
|
|
{
|
2010-01-23 19:44:49 +00:00
|
|
|
delete mOutputTracks;
|
|
|
|
mOutputTracks = NULL;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (returnVal)
|
|
|
|
{
|
2014-10-05 17:10:09 +00:00
|
|
|
selectedRegion->setTimes(mT0, mT1);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
return returnVal;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
// All legacy effects should have this overridden
|
|
|
|
bool Effect::Init()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
// Remove this method once NoiseReduction gets migrated
|
|
|
|
bool Effect::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
|
|
|
{
|
2015-04-26 21:41:05 +00:00
|
|
|
return ShowInterface(parent, IsBatchProcessing());
|
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
|
|
|
int Effect::GetPass()
|
|
|
|
{
|
|
|
|
return mPass;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::InitPass1()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::InitPass2()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
bool Effect::Process()
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
CopyInputTracks(Track::All);
|
|
|
|
bool bGoodResult = true;
|
|
|
|
|
2015-08-16 05:15:55 +00:00
|
|
|
// It's possible that the number of channels the effect expects changed based on
|
|
|
|
// the parameters (the Audacity Reverb effect does when the stereo width is 0).
|
|
|
|
mNumAudioIn = GetAudioInCount();
|
|
|
|
mNumAudioOut = GetAudioOutCount();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mPass = 1;
|
|
|
|
if (InitPass1())
|
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
|
|
|
bGoodResult = ProcessPass();
|
|
|
|
mPass = 2;
|
|
|
|
if (bGoodResult && InitPass2())
|
|
|
|
{
|
|
|
|
bGoodResult = ProcessPass();
|
|
|
|
}
|
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
|
|
|
ReplaceProcessedTracks(bGoodResult);
|
2014-11-07 09:54:04 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
return bGoodResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::ProcessPass()
|
|
|
|
{
|
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
|
|
|
bool bGoodResult = true;
|
2015-04-17 03:53:42 +00:00
|
|
|
bool isGenerator = GetType() == EffectTypeGenerate;
|
|
|
|
bool editClipCanMove;
|
|
|
|
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove, true);
|
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
|
|
|
|
|
|
|
mInBuffer = NULL;
|
|
|
|
mOutBuffer = NULL;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
ChannelName map[3];
|
|
|
|
|
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 prevBufferSize = 0;
|
|
|
|
mBufferSize = 0;
|
|
|
|
mBlockSize = 0;
|
|
|
|
|
|
|
|
TrackListIterator iter(mOutputTracks);
|
|
|
|
int count = 0;
|
|
|
|
bool clear = false;
|
2014-11-07 09:54:04 +00:00
|
|
|
Track* t = iter.First();
|
|
|
|
|
|
|
|
for (t = iter.First(); t; t = iter.Next())
|
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-11-07 09:54:04 +00:00
|
|
|
if (t->GetKind() != Track::Wave || !t->GetSelected())
|
|
|
|
{
|
|
|
|
if (t->IsSyncLockSelected())
|
|
|
|
{
|
|
|
|
t->SyncLockAdjust(mT1, mT0 + mDuration);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
WaveTrack *left = (WaveTrack *)t;
|
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 *right;
|
|
|
|
sampleCount len;
|
|
|
|
sampleCount leftStart;
|
|
|
|
sampleCount rightStart;
|
|
|
|
|
2014-11-07 09:54:04 +00:00
|
|
|
if (!isGenerator)
|
|
|
|
{
|
|
|
|
GetSamples(left, &leftStart, &len);
|
2015-04-17 03:53:42 +00:00
|
|
|
mSampleCnt = len;
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
leftStart = 0;
|
2015-04-17 03:53:42 +00:00
|
|
|
mSampleCnt = left->TimeToLongSamples(mDuration);
|
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
|
|
|
|
|
|
|
mNumChannels = 1;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
if (left->GetChannel() == Track::LeftChannel)
|
|
|
|
{
|
|
|
|
map[0] = ChannelNameFrontLeft;
|
|
|
|
}
|
|
|
|
else if (left->GetChannel() == Track::RightChannel)
|
|
|
|
{
|
|
|
|
map[0] = ChannelNameFrontRight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
map[0] = ChannelNameMono;
|
|
|
|
}
|
|
|
|
map[1] = ChannelNameEOL;
|
|
|
|
|
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
|
|
|
right = NULL;
|
|
|
|
rightStart = 0;
|
|
|
|
if (left->GetLinked() && mNumAudioIn > 1)
|
|
|
|
{
|
|
|
|
right = (WaveTrack *) iter.Next();
|
2014-11-07 09:54:04 +00:00
|
|
|
if (!isGenerator)
|
|
|
|
{
|
|
|
|
GetSamples(right, &rightStart, &len);
|
|
|
|
}
|
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
|
|
|
clear = false;
|
|
|
|
mNumChannels = 2;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
if (right->GetChannel() == Track::LeftChannel)
|
|
|
|
{
|
|
|
|
map[1] = ChannelNameFrontLeft;
|
|
|
|
}
|
|
|
|
else if (right->GetChannel() == Track::RightChannel)
|
|
|
|
{
|
|
|
|
map[1] = ChannelNameFrontRight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
map[1] = ChannelNameMono;
|
|
|
|
}
|
|
|
|
map[2] = ChannelNameEOL;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// Let the client know the sample rate
|
2015-04-17 03:53:42 +00:00
|
|
|
SetSampleRate(left->GetRate());
|
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
|
|
|
|
|
|
|
// Get the block size the client wants to use
|
|
|
|
sampleCount max = left->GetMaxBlockSize() * 2;
|
2015-04-17 03:53:42 +00:00
|
|
|
mBlockSize = SetBlockSize(max);
|
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
|
|
|
|
|
|
|
// Calculate the buffer size to be at least the max rounded up to the clients
|
|
|
|
// selected block size.
|
|
|
|
prevBufferSize = mBufferSize;
|
|
|
|
mBufferSize = ((max + (mBlockSize - 1)) / mBlockSize) * mBlockSize;
|
|
|
|
|
|
|
|
// If the buffer size has changed, then (re)allocate the buffers
|
|
|
|
if (prevBufferSize != mBufferSize)
|
|
|
|
{
|
|
|
|
// Get rid of any previous buffers
|
|
|
|
if (mInBuffer)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
if (mInBuffer[i])
|
|
|
|
{
|
|
|
|
delete [] mInBuffer[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete [] mInBuffer;
|
|
|
|
delete [] mInBufPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always create the number of input buffers the client expects even if we don't have
|
|
|
|
// the same number of channels.
|
|
|
|
mInBufPos = new float *[mNumAudioIn];
|
|
|
|
mInBuffer = new float *[mNumAudioIn];
|
|
|
|
for (int i = 0; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
mInBuffer[i] = new float[mBufferSize];
|
|
|
|
}
|
|
|
|
|
|
|
|
// We won't be using more than the first 2 buffers, so clear the rest (if any)
|
|
|
|
for (int i = 2; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < mBufferSize; j++)
|
|
|
|
{
|
|
|
|
mInBuffer[i][j] = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get rid of any previous buffers
|
|
|
|
if (mOutBuffer)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
if (mOutBuffer[i])
|
|
|
|
{
|
|
|
|
delete [] mOutBuffer[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete [] mOutBuffer;
|
|
|
|
delete [] mOutBufPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always create the number of output buffers the client expects even if we don't have
|
|
|
|
// the same number of channels.
|
|
|
|
mOutBufPos = new float *[mNumAudioOut];
|
|
|
|
mOutBuffer = new float *[mNumAudioOut];
|
|
|
|
for (int i = 0; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
// Output buffers get an extra mBlockSize worth to give extra room if
|
|
|
|
// the plugin adds latency
|
|
|
|
mOutBuffer[i] = new float[mBufferSize + mBlockSize];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// (Re)Set the input buffer positions
|
|
|
|
for (int i = 0; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
mInBufPos[i] = mInBuffer[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// (Re)Set the output buffer positions
|
|
|
|
for (int i = 0; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
mOutBufPos[i] = mOutBuffer[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear unused input buffers
|
|
|
|
if (!right && !clear && mNumAudioIn > 1)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < mBufferSize; j++)
|
|
|
|
{
|
|
|
|
mInBuffer[1][j] = 0.0;
|
|
|
|
}
|
|
|
|
clear = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Go process the track(s)
|
2015-04-17 03:53:42 +00:00
|
|
|
bGoodResult = ProcessTrack(count, map, left, right, leftStart, rightStart, len);
|
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
|
|
|
if (!bGoodResult)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mOutBuffer)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
delete [] mOutBuffer[i];
|
|
|
|
}
|
|
|
|
delete [] mOutBuffer;
|
|
|
|
delete [] mOutBufPos;
|
|
|
|
mOutBuffer = NULL;
|
|
|
|
mOutBufPos = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mInBuffer)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
delete [] mInBuffer[i];
|
|
|
|
}
|
|
|
|
delete [] mInBuffer;
|
|
|
|
delete [] mInBufPos;
|
|
|
|
mInBuffer = NULL;
|
|
|
|
mInBufPos = NULL;
|
|
|
|
}
|
|
|
|
|
2015-05-05 01:52:25 +00:00
|
|
|
if (bGoodResult && GetType() == EffectTypeGenerate)
|
|
|
|
{
|
|
|
|
mT1 = mT0 + mDuration;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
return bGoodResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::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)
|
|
|
|
{
|
|
|
|
bool rc = true;
|
|
|
|
|
|
|
|
// Give the plugin a chance to initialize
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!ProcessInitialize(len, map))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
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 each input block of samples, we pass it to the effect along with a
|
|
|
|
// variable output location. This output location is simply a pointer into a
|
|
|
|
// much larger buffer. This reduces the number of calls required to add the
|
|
|
|
// samples to the output track.
|
|
|
|
//
|
|
|
|
// Upon return from the effect, the output samples are "moved to the left" by
|
2014-10-29 03:46:53 +00:00
|
|
|
// the number of samples in the current latency setting, effectively removing any
|
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
|
|
|
// delay introduced by the effect.
|
|
|
|
//
|
2014-10-29 03:46:53 +00:00
|
|
|
// At the same time the total number of delayed samples are gathered and when
|
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
|
|
|
// there is no further input data to process, the loop continues to call the
|
|
|
|
// effect with an empty input buffer until the effect has had a chance to
|
|
|
|
// return all of the remaining delayed samples.
|
|
|
|
sampleCount inLeftPos = leftStart;
|
|
|
|
sampleCount inRightPos = rightStart;
|
|
|
|
sampleCount outLeftPos = leftStart;
|
|
|
|
sampleCount outRightPos = rightStart;
|
|
|
|
|
|
|
|
sampleCount inputRemaining = len;
|
|
|
|
sampleCount delayRemaining = 0;
|
|
|
|
sampleCount curBlockSize = 0;
|
|
|
|
sampleCount curDelay = 0;
|
|
|
|
|
|
|
|
sampleCount inputBufferCnt = 0;
|
|
|
|
sampleCount outputBufferCnt = 0;
|
|
|
|
bool cleared = false;
|
|
|
|
|
2015-01-11 22:52:08 +00:00
|
|
|
int chans = wxMin(mNumAudioOut, mNumChannels);
|
|
|
|
|
2016-03-02 19:59:31 +00:00
|
|
|
std::unique_ptr<WaveTrack> genLeft, genRight;
|
2014-11-07 09:54:04 +00:00
|
|
|
sampleCount genLength = 0;
|
2015-04-17 03:53:42 +00:00
|
|
|
bool isGenerator = GetType() == EffectTypeGenerate;
|
|
|
|
bool isProcessor = GetType() == EffectTypeProcess;
|
2014-11-07 09:54:04 +00:00
|
|
|
if (isGenerator)
|
|
|
|
{
|
2015-05-28 16:31:07 +00:00
|
|
|
double genDur;
|
|
|
|
if (mIsPreview) {
|
|
|
|
gPrefs->Read(wxT("/AudioIO/EffectsPreviewLen"), &genDur, 6.0);
|
|
|
|
genDur = wxMin(mDuration, CalcPreviewInputLength(genDur));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
genDur = mDuration;
|
|
|
|
}
|
|
|
|
|
|
|
|
genLength = left->GetRate() * genDur;
|
2014-11-07 09:54:04 +00:00
|
|
|
delayRemaining = genLength;
|
|
|
|
cleared = true;
|
|
|
|
|
|
|
|
// Create temporary tracks
|
|
|
|
genLeft = mFactory->NewWaveTrack(left->GetSampleFormat(), left->GetRate());
|
|
|
|
if (right)
|
|
|
|
{
|
|
|
|
genRight = mFactory->NewWaveTrack(right->GetSampleFormat(), right->GetRate());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
// Call the effect until we run out of input or delayed samples
|
|
|
|
while (inputRemaining || delayRemaining)
|
|
|
|
{
|
|
|
|
// Still working on the input samples
|
|
|
|
if (inputRemaining)
|
|
|
|
{
|
|
|
|
// Need to refill the input buffers
|
|
|
|
if (inputBufferCnt == 0)
|
|
|
|
{
|
|
|
|
// Calculate the number of samples to get
|
|
|
|
inputBufferCnt = mBufferSize;
|
|
|
|
if (inputBufferCnt > inputRemaining)
|
|
|
|
{
|
|
|
|
inputBufferCnt = inputRemaining;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill the input buffers
|
|
|
|
left->Get((samplePtr) mInBuffer[0], floatSample, inLeftPos, inputBufferCnt);
|
|
|
|
if (right)
|
|
|
|
{
|
|
|
|
right->Get((samplePtr) mInBuffer[1], floatSample, inRightPos, inputBufferCnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset the input buffer positions
|
|
|
|
for (int i = 0; i < mNumChannels; i++)
|
|
|
|
{
|
|
|
|
mInBufPos[i] = mInBuffer[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the number of samples to process
|
|
|
|
curBlockSize = mBlockSize;
|
|
|
|
if (curBlockSize > inputRemaining)
|
|
|
|
{
|
|
|
|
// We've reached the last block...set current block size to what's left
|
|
|
|
curBlockSize = inputRemaining;
|
|
|
|
inputRemaining = 0;
|
|
|
|
|
|
|
|
// Clear the remainder of the buffers so that a full block can be passed
|
|
|
|
// to the effect
|
|
|
|
sampleCount cnt = mBlockSize - curBlockSize;
|
|
|
|
for (int i = 0; i < mNumChannels; i++)
|
|
|
|
{
|
|
|
|
for (int j = 0 ; j < cnt; j++)
|
|
|
|
{
|
|
|
|
mInBufPos[i][j + curBlockSize] = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Might be able to use up some of the delayed samples
|
|
|
|
if (delayRemaining)
|
|
|
|
{
|
|
|
|
// Don't use more than needed
|
|
|
|
if (delayRemaining < cnt)
|
|
|
|
{
|
|
|
|
cnt = delayRemaining;
|
|
|
|
}
|
|
|
|
delayRemaining -= cnt;
|
|
|
|
curBlockSize += cnt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// We've exhausted the input samples and are now working on the delay
|
|
|
|
else if (delayRemaining)
|
|
|
|
{
|
|
|
|
// Calculate the number of samples to process
|
|
|
|
curBlockSize = mBlockSize;
|
|
|
|
if (curBlockSize > delayRemaining)
|
|
|
|
{
|
|
|
|
curBlockSize = delayRemaining;
|
|
|
|
}
|
|
|
|
delayRemaining -= curBlockSize;
|
|
|
|
|
|
|
|
// From this point on, we only want to feed zeros to the plugin
|
|
|
|
if (!cleared)
|
2015-04-17 03:53:42 +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
|
|
|
// Reset the input buffer positions
|
|
|
|
for (int i = 0; i < mNumChannels; i++)
|
|
|
|
{
|
|
|
|
mInBufPos[i] = mInBuffer[i];
|
|
|
|
|
|
|
|
// And clear
|
|
|
|
for (int j = 0; j < mBlockSize; j++)
|
|
|
|
{
|
|
|
|
mInBuffer[i][j] = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cleared = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally call the plugin to process the block
|
2015-04-17 03:53:42 +00:00
|
|
|
sampleCount processed;
|
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
|
|
|
try
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
processed = ProcessBlock(mInBufPos, mOutBufPos, curBlockSize);
|
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
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
wxASSERT(processed == curBlockSize);
|
2016-02-26 19:41:17 +00:00
|
|
|
wxUnusedVar(processed);
|
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
|
|
|
|
|
|
|
// Bump to next input buffer position
|
|
|
|
if (inputRemaining)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < mNumChannels; i++)
|
|
|
|
{
|
|
|
|
mInBufPos[i] += curBlockSize;
|
|
|
|
}
|
|
|
|
inputRemaining -= curBlockSize;
|
|
|
|
inputBufferCnt -= curBlockSize;
|
|
|
|
}
|
|
|
|
|
2015-01-11 22:52:08 +00:00
|
|
|
// "ls" and "rs" serve as the input sample index for the left and
|
|
|
|
// right channels when processing the input samples. If we flip
|
|
|
|
// over to processing delayed samples, they simply become counters
|
|
|
|
// for the progress display.
|
|
|
|
inLeftPos += curBlockSize;
|
|
|
|
inRightPos += curBlockSize;
|
|
|
|
|
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
|
|
|
// Get the current number of delayed samples and accumulate
|
2014-11-14 03:03:17 +00:00
|
|
|
if (isProcessor)
|
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
|
|
|
sampleCount delay = GetLatency();
|
2014-11-07 09:54:04 +00:00
|
|
|
curDelay += delay;
|
|
|
|
delayRemaining += delay;
|
|
|
|
|
|
|
|
// If the plugin has delayed the output by more samples than our current
|
|
|
|
// block size, then we leave the output pointers alone. This effectively
|
|
|
|
// removes those delayed samples from the output buffer.
|
|
|
|
if (curDelay >= curBlockSize)
|
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-11-07 09:54:04 +00:00
|
|
|
curDelay -= curBlockSize;
|
|
|
|
curBlockSize = 0;
|
|
|
|
}
|
|
|
|
// We have some delayed samples, at the beginning of the output samples,
|
|
|
|
// so overlay them by shifting the remaining output samples.
|
|
|
|
else if (curDelay > 0)
|
|
|
|
{
|
|
|
|
curBlockSize -= curDelay;
|
2015-01-11 22:52:08 +00:00
|
|
|
for (int i = 0; i < chans; i++)
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
2015-01-11 22:52:08 +00:00
|
|
|
memmove(mOutBufPos[i], mOutBufPos[i] + curDelay, sizeof(float) * curBlockSize);
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
curDelay = 0;
|
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-01-11 22:52:08 +00:00
|
|
|
// Adjust the number of samples in the output buffers
|
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
|
|
|
outputBufferCnt += curBlockSize;
|
|
|
|
|
2015-01-11 22:52:08 +00:00
|
|
|
// Still have room in the output buffers
|
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
|
|
|
if (outputBufferCnt < mBufferSize)
|
|
|
|
{
|
|
|
|
// Bump to next output buffer position
|
2015-01-11 22:52:08 +00:00
|
|
|
for (int i = 0; i < chans; i++)
|
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
|
|
|
{
|
|
|
|
mOutBufPos[i] += curBlockSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Output buffers have filled
|
|
|
|
else
|
|
|
|
{
|
2014-11-14 03:03:17 +00:00
|
|
|
if (isProcessor)
|
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-11-07 09:54:04 +00:00
|
|
|
// Write them out
|
|
|
|
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
|
|
|
|
if (right)
|
|
|
|
{
|
2015-05-16 15:53:04 +00:00
|
|
|
if (chans >= 2)
|
|
|
|
{
|
|
|
|
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
right->Set((samplePtr) mOutBuffer[0], floatSample, outRightPos, outputBufferCnt);
|
|
|
|
}
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
else if (isGenerator)
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
|
|
|
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
|
|
|
|
if (genRight)
|
|
|
|
{
|
|
|
|
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// Reset the output buffer positions
|
2015-01-11 22:52:08 +00:00
|
|
|
for (int i = 0; i < chans; i++)
|
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
|
|
|
{
|
|
|
|
mOutBufPos[i] = mOutBuffer[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bump to the next track position
|
|
|
|
outLeftPos += outputBufferCnt;
|
|
|
|
outRightPos += outputBufferCnt;
|
|
|
|
outputBufferCnt = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mNumChannels > 1)
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (TrackGroupProgress(count, (inLeftPos - leftStart) / (double) (isGenerator ? genLength : len)))
|
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
|
|
|
{
|
|
|
|
rc = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (TrackProgress(count, (inLeftPos - leftStart) / (double) (isGenerator ? genLength : len)))
|
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
|
|
|
{
|
|
|
|
rc = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put any remaining output
|
|
|
|
if (outputBufferCnt)
|
|
|
|
{
|
2014-11-14 03:03:17 +00:00
|
|
|
if (isProcessor)
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
|
|
|
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
|
|
|
|
if (right)
|
|
|
|
{
|
2015-05-16 15:53:04 +00:00
|
|
|
if (chans >= 2)
|
|
|
|
{
|
|
|
|
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
right->Set((samplePtr) mOutBuffer[0], floatSample, outRightPos, outputBufferCnt);
|
|
|
|
}
|
2014-11-07 09:54:04 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
else if (isGenerator)
|
2014-11-07 09:54:04 +00:00
|
|
|
{
|
|
|
|
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
|
|
|
|
if (genRight)
|
|
|
|
{
|
|
|
|
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isGenerator)
|
|
|
|
{
|
2015-05-28 16:31:07 +00:00
|
|
|
AudacityProject *p = GetActiveProject();
|
2016-02-01 01:39:24 +00:00
|
|
|
StepTimeWarper warper(mT0 + genLength, genLength - (mT1 - mT0));
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2014-11-07 09:54:04 +00:00
|
|
|
// Transfer the data from the temporary tracks to the actual ones
|
|
|
|
genLeft->Flush();
|
2016-02-13 15:43:16 +00:00
|
|
|
// mT1 gives us the NEW selection. We want to replace up to GetSel1().
|
2016-03-02 19:59:31 +00:00
|
|
|
left->ClearAndPaste(mT0, p->GetSel1(), genLeft.get(), true, true, &warper);
|
2014-11-07 09:54:04 +00:00
|
|
|
|
|
|
|
if (genRight)
|
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-11-07 09:54:04 +00:00
|
|
|
genRight->Flush();
|
2016-03-02 19:59:31 +00:00
|
|
|
right->ClearAndPaste(mT0, mT1, genRight.get(), true, true, &warper);
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allow the plugin to cleanup
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!ProcessFinalize())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
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
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::End()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void Effect::PopulateOrExchange(ShuttleGui & WXUNUSED(S))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::TransferDataToWindow()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::TransferDataFromWindow()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::EnableApply(bool enable)
|
|
|
|
{
|
|
|
|
// May be called during initialization, so try to find the dialog
|
|
|
|
wxWindow *dlg = mUIDialog;
|
|
|
|
if (!dlg && mUIParent)
|
|
|
|
{
|
|
|
|
dlg = wxGetTopLevelParent(mUIParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dlg)
|
|
|
|
{
|
|
|
|
wxWindow *apply = dlg->FindWindow(wxID_APPLY);
|
|
|
|
|
|
|
|
// Don't allow focus to get trapped
|
|
|
|
if (!enable)
|
|
|
|
{
|
|
|
|
wxWindow *focus = dlg->FindFocus();
|
|
|
|
if (focus == apply)
|
|
|
|
{
|
|
|
|
dlg->FindWindow(wxID_CLOSE)->SetFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
apply->Enable(enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
EnablePreview(enable);
|
|
|
|
|
|
|
|
return enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Effect::EnablePreview(bool enable)
|
|
|
|
{
|
|
|
|
// May be called during initialization, so try to find the dialog
|
|
|
|
wxWindow *dlg = mUIDialog;
|
|
|
|
if (!dlg && mUIParent)
|
|
|
|
{
|
|
|
|
dlg = wxGetTopLevelParent(mUIParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dlg)
|
|
|
|
{
|
|
|
|
wxWindow *play = dlg->FindWindow(kPlayID);
|
|
|
|
if (play)
|
|
|
|
{
|
|
|
|
wxWindow *rewind = dlg->FindWindow(kRewindID);
|
|
|
|
wxWindow *ffwd = dlg->FindWindow(kFFwdID);
|
|
|
|
|
|
|
|
// Don't allow focus to get trapped
|
|
|
|
if (!enable)
|
|
|
|
{
|
|
|
|
wxWindow *focus = dlg->FindFocus();
|
|
|
|
if (focus && (focus == play || focus == rewind || focus == ffwd))
|
|
|
|
{
|
|
|
|
dlg->FindWindow(wxID_CLOSE)->SetFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
play->Enable(enable);
|
|
|
|
if (SupportsRealtime())
|
|
|
|
{
|
|
|
|
rewind->Enable(enable);
|
|
|
|
ffwd->Enable(enable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return enable;
|
|
|
|
}
|
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
void Effect::EnableDebug(bool enable)
|
|
|
|
{
|
|
|
|
mUIDebug = enable;
|
|
|
|
}
|
|
|
|
|
2015-05-15 11:47:51 +00:00
|
|
|
void Effect::SetLinearEffectFlag(bool linearEffectFlag)
|
|
|
|
{
|
|
|
|
mIsLinearEffect = linearEffectFlag;
|
|
|
|
}
|
|
|
|
|
2015-05-28 16:31:07 +00:00
|
|
|
void Effect::SetPreviewFullSelectionFlag(bool previewDurationFlag)
|
|
|
|
{
|
|
|
|
mPreviewFullSelection = previewDurationFlag;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-15 15:57:29 +00:00
|
|
|
void Effect::IncludeNotSelectedPreviewTracks(bool includeNotSelected)
|
|
|
|
{
|
|
|
|
mPreviewWithNotSelected = includeNotSelected;
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
bool Effect::TotalProgress(double frac)
|
|
|
|
{
|
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
|
|
|
int updateResult = (mProgress ?
|
|
|
|
mProgress->Update(frac) :
|
|
|
|
eProgressSuccess);
|
2010-09-02 02:40:17 +00:00
|
|
|
return (updateResult != eProgressSuccess);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 02:17:19 +00:00
|
|
|
bool Effect::TrackProgress(int whichTrack, double frac, const wxString &msg)
|
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
|
|
|
int updateResult = (mProgress ?
|
|
|
|
mProgress->Update(whichTrack + frac, (double) mNumTracks, msg) :
|
|
|
|
eProgressSuccess);
|
2010-09-02 02:40:17 +00:00
|
|
|
return (updateResult != eProgressSuccess);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 02:17:19 +00:00
|
|
|
bool Effect::TrackGroupProgress(int whichGroup, double frac, const wxString &msg)
|
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
|
|
|
int updateResult = (mProgress ?
|
2015-08-12 13:19:01 +00:00
|
|
|
mProgress->Update(whichGroup + frac, (double) mNumGroups, msg) :
|
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
|
|
|
eProgressSuccess);
|
2010-09-02 02:40:17 +00:00
|
|
|
return (updateResult != eProgressSuccess);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::GetSamples(WaveTrack *track, sampleCount *start, sampleCount *len)
|
|
|
|
{
|
|
|
|
double trackStart = track->GetStartTime();
|
|
|
|
double trackEnd = track->GetEndTime();
|
|
|
|
double t0 = mT0 < trackStart ? trackStart : mT0;
|
|
|
|
double t1 = mT1 > trackEnd ? trackEnd : mT1;
|
|
|
|
|
2014-11-07 09:54:04 +00:00
|
|
|
#if 0
|
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
|
|
|
if (GetType() & INSERT_EFFECT) {
|
2014-11-07 09:54:04 +00:00
|
|
|
t1 = t0 + mDuration;
|
2010-01-23 19:44:49 +00:00
|
|
|
if (mT0 == mT1) {
|
|
|
|
// Not really part of the calculation, but convenient to put here
|
2011-11-18 03:47:43 +00:00
|
|
|
bool bResult = track->InsertSilence(t0, t1);
|
|
|
|
wxASSERT(bResult); // TO DO: Actually handle this.
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-07 09:54:04 +00:00
|
|
|
#endif
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (t1 > t0) {
|
|
|
|
*start = track->TimeToLongSamples(t0);
|
|
|
|
sampleCount end = track->TimeToLongSamples(t1);
|
|
|
|
*len = (sampleCount)(end - *start);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*start = 0;
|
|
|
|
*len = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::SetTimeWarper(TimeWarper *warper)
|
|
|
|
{
|
|
|
|
if (mWarper != NULL)
|
|
|
|
{
|
|
|
|
delete mWarper;
|
|
|
|
mWarper = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxASSERT(warper != NULL);
|
|
|
|
mWarper = warper;
|
|
|
|
}
|
|
|
|
|
|
|
|
TimeWarper *Effect::GetTimeWarper()
|
|
|
|
{
|
|
|
|
wxASSERT(mWarper != NULL);
|
|
|
|
return mWarper;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// private methods
|
|
|
|
//
|
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).
|
|
|
|
// Copy the group tracks that have tracks selected
|
2015-07-03 04:20:21 +00:00
|
|
|
void Effect::CopyInputTracks()
|
|
|
|
{
|
|
|
|
CopyInputTracks(Track::Wave);
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
void Effect::CopyInputTracks(int trackType)
|
|
|
|
{
|
|
|
|
// Reset map
|
|
|
|
mIMap.Clear();
|
|
|
|
mOMap.Clear();
|
|
|
|
|
2016-03-13 14:34:44 +00:00
|
|
|
mOutputTracks = new TrackList();
|
2010-01-23 19:44:49 +00:00
|
|
|
mOutputTracksType = trackType;
|
|
|
|
|
|
|
|
//iterate over tracks of type trackType (All types if Track::All)
|
|
|
|
TrackListOfKindIterator aIt(trackType, mTracks);
|
|
|
|
t2bHash added;
|
|
|
|
|
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 (Track *aTrack = aIt.First(); aTrack; aTrack = aIt.Next())
|
|
|
|
{
|
2010-08-11 22:47:26 +00:00
|
|
|
// Include selected tracks, plus sync-lock selected tracks for Track::All.
|
2010-02-16 20:50:38 +00:00
|
|
|
if (aTrack->GetSelected() ||
|
2010-08-11 22:47:26 +00:00
|
|
|
(trackType == Track::All && aTrack->IsSyncLockSelected()))
|
2010-02-16 20:50:38 +00:00
|
|
|
{
|
2016-03-13 15:08:21 +00:00
|
|
|
Track *o = mOutputTracks->Add(aTrack->Duplicate());
|
2010-01-23 19:44:49 +00:00
|
|
|
mIMap.Add(aTrack);
|
|
|
|
mOMap.Add(o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-13 15:08:21 +00:00
|
|
|
Track *Effect::AddToOutputTracks(std::unique_ptr<Track> &&t)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
mIMap.Add(NULL);
|
2016-03-13 15:08:21 +00:00
|
|
|
mOMap.Add(t.get());
|
|
|
|
return mOutputTracks->Add(std::move(t));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2016-02-27 19:24:57 +00:00
|
|
|
Effect::AddedAnalysisTrack::AddedAnalysisTrack(Effect *pEffect, const wxString &name)
|
|
|
|
: mpEffect(pEffect)
|
|
|
|
{
|
2016-03-02 19:59:31 +00:00
|
|
|
LabelTrack::Holder pTrack{ pEffect->mFactory->NewLabelTrack() };
|
2016-02-27 19:24:57 +00:00
|
|
|
mpTrack = pTrack.get();
|
|
|
|
if (!name.empty())
|
|
|
|
pTrack->SetName(name);
|
2016-03-13 15:08:21 +00:00
|
|
|
pEffect->mTracks->Add(std::move(pTrack));
|
2016-02-27 19:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Effect::AddedAnalysisTrack::AddedAnalysisTrack(AddedAnalysisTrack &&that)
|
|
|
|
{
|
|
|
|
mpEffect = that.mpEffect;
|
|
|
|
mpTrack = that.mpTrack;
|
|
|
|
that.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::AddedAnalysisTrack::Commit()
|
|
|
|
{
|
|
|
|
mpEffect = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Effect::AddedAnalysisTrack::~AddedAnalysisTrack()
|
|
|
|
{
|
|
|
|
if (mpEffect) {
|
|
|
|
// not committed -- DELETE the label track
|
2016-03-01 21:28:59 +00:00
|
|
|
mpEffect->mTracks->Remove(mpTrack);
|
2016-02-27 19:24:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-07 06:29:26 +00:00
|
|
|
auto Effect::AddAnalysisTrack(const wxString &name) -> std::shared_ptr<AddedAnalysisTrack>
|
2016-02-27 19:24:57 +00:00
|
|
|
{
|
2016-03-07 06:29:26 +00:00
|
|
|
return std::shared_ptr<AddedAnalysisTrack>
|
|
|
|
{ safenew AddedAnalysisTrack{ this, name } };
|
2016-02-27 19:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack
|
|
|
|
(Effect *pEffect, const LabelTrack *pOrigTrack, const wxString &name)
|
|
|
|
: mpEffect(pEffect)
|
|
|
|
{
|
|
|
|
// copy LabelTrack here, so it can be undone on cancel
|
2016-03-02 20:36:44 +00:00
|
|
|
auto newTrack = pOrigTrack->Copy(pOrigTrack->GetStartTime(), pOrigTrack->GetEndTime());
|
2016-02-27 19:24:57 +00:00
|
|
|
|
2016-03-02 20:36:44 +00:00
|
|
|
mpTrack = static_cast<LabelTrack*>(newTrack.get());
|
2016-02-27 19:24:57 +00:00
|
|
|
|
|
|
|
// Why doesn't LabelTrack::Copy complete the job? :
|
|
|
|
mpTrack->SetOffset(pOrigTrack->GetStartTime());
|
|
|
|
if (!name.empty())
|
|
|
|
mpTrack->SetName(name);
|
|
|
|
|
2016-03-01 00:54:21 +00:00
|
|
|
// mpOrigTrack came from mTracks which we own but expose as const to subclasses
|
|
|
|
// So it's okay that we cast it back to const
|
2016-03-13 15:08:21 +00:00
|
|
|
mpOrigTrack =
|
|
|
|
pEffect->mTracks->Replace(const_cast<LabelTrack*>(pOrigTrack),
|
|
|
|
#ifdef __AUDACITY_OLD_STD__
|
|
|
|
std::shared_ptr<Track>(newTrack.release())
|
|
|
|
#else
|
|
|
|
std::move(newTrack)
|
|
|
|
#endif
|
|
|
|
);
|
2016-02-27 19:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack(ModifiedAnalysisTrack &&that)
|
|
|
|
{
|
|
|
|
mpEffect = that.mpEffect;
|
|
|
|
mpTrack = that.mpTrack;
|
2016-03-13 15:08:21 +00:00
|
|
|
mpOrigTrack = std::move(that.mpOrigTrack);
|
2016-02-27 19:24:57 +00:00
|
|
|
that.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::ModifiedAnalysisTrack::Commit()
|
|
|
|
{
|
|
|
|
mpEffect = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Effect::ModifiedAnalysisTrack::~ModifiedAnalysisTrack()
|
|
|
|
{
|
|
|
|
if (mpEffect) {
|
|
|
|
// not committed -- DELETE the label track
|
2016-03-01 00:54:21 +00:00
|
|
|
// mpOrigTrack came from mTracks which we own but expose as const to subclasses
|
|
|
|
// So it's okay that we cast it back to const
|
2016-03-13 15:08:21 +00:00
|
|
|
mpEffect->mTracks->Replace(mpTrack, std::move(mpOrigTrack));
|
2016-02-27 19:24:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Effect::ModifyAnalysisTrack
|
|
|
|
(const LabelTrack *pOrigTrack, const wxString &name) -> ModifiedAnalysisTrack
|
|
|
|
{
|
|
|
|
return{ this, pOrigTrack, name };
|
|
|
|
}
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// If bGoodResult, replace mTracks tracks with successfully processed mOutputTracks copies.
|
2016-02-14 23:50:45 +00:00
|
|
|
// Else clear and DELETE mOutputTracks copies.
|
2010-01-23 19:44:49 +00:00
|
|
|
void Effect::ReplaceProcessedTracks(const bool bGoodResult)
|
|
|
|
{
|
|
|
|
wxASSERT(mOutputTracks != NULL); // Make sure we at least did the CopyInputTracks().
|
|
|
|
|
|
|
|
if (!bGoodResult) {
|
|
|
|
// Processing failed or was cancelled so throw away the processed tracks.
|
2016-03-13 14:34:44 +00:00
|
|
|
mOutputTracks->Clear();
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Reset map
|
|
|
|
mIMap.Clear();
|
|
|
|
mOMap.Clear();
|
|
|
|
|
|
|
|
//TODO:undo the non-gui ODTask transfer
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-03-02 06:39:56 +00:00
|
|
|
auto iterOut = mOutputTracks->begin(), iterEnd = mOutputTracks->end();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
size_t cnt = mOMap.GetCount();
|
|
|
|
size_t i = 0;
|
|
|
|
|
2016-03-02 06:39:56 +00:00
|
|
|
for (; iterOut != iterEnd; ++i) {
|
2016-03-13 15:08:21 +00:00
|
|
|
ListOfTracks::value_type o = std::move(*iterOut);
|
2010-01-23 19:44:49 +00:00
|
|
|
// If tracks were removed from mOutputTracks, then there will be
|
|
|
|
// tracks in the map that must be removed from mTracks.
|
2016-03-13 15:08:21 +00:00
|
|
|
while (i < cnt && mOMap[i] != o.get()) {
|
2010-01-23 19:44:49 +00:00
|
|
|
Track *t = (Track *) mIMap[i];
|
|
|
|
if (t) {
|
2016-03-01 21:28:59 +00:00
|
|
|
mTracks->Remove(t);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This should never happen
|
|
|
|
wxASSERT(i < cnt);
|
|
|
|
|
2016-02-14 23:50:45 +00:00
|
|
|
// Remove the track from the output list...don't DELETE it
|
2016-03-02 06:39:56 +00:00
|
|
|
iterOut = mOutputTracks->erase(iterOut);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
Track *t = (Track *) mIMap[i];
|
|
|
|
if (t == NULL)
|
|
|
|
{
|
2016-02-13 15:43:16 +00:00
|
|
|
// This track is a NEW addition to output tracks; add it to mTracks
|
2016-03-13 15:08:21 +00:00
|
|
|
mTracks->Add(std::move(o));
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-02-13 15:43:16 +00:00
|
|
|
// Replace mTracks entry with the NEW track
|
2016-03-13 15:08:21 +00:00
|
|
|
WaveTrack *newTrack = static_cast<WaveTrack*>(o.get());
|
|
|
|
mTracks->Replace(t, std::move(o));
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-02-13 15:43:16 +00:00
|
|
|
// Swap the wavecache track the ondemand task uses, since now the NEW
|
2010-01-23 19:44:49 +00:00
|
|
|
// one will be kept in the project
|
|
|
|
if (ODManager::IsInstanceCreated()) {
|
|
|
|
ODManager::Instance()->ReplaceWaveTrack((WaveTrack *)t,
|
2016-03-13 15:08:21 +00:00
|
|
|
newTrack);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If tracks were removed from mOutputTracks, then there may be tracks
|
|
|
|
// left at the end of the map that must be removed from mTracks.
|
|
|
|
while (i < cnt) {
|
|
|
|
Track *t = (Track *) mIMap[i];
|
|
|
|
if (t) {
|
2016-03-01 21:28:59 +00:00
|
|
|
mTracks->Remove((Track *)mIMap[i]);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset map
|
|
|
|
mIMap.Clear();
|
|
|
|
mOMap.Clear();
|
|
|
|
|
|
|
|
// Make sure we processed everything
|
2016-03-02 06:39:56 +00:00
|
|
|
wxASSERT(mOutputTracks->empty());
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// The output list is no longer needed
|
|
|
|
delete mOutputTracks;
|
|
|
|
mOutputTracks = NULL;
|
|
|
|
mOutputTracksType = Track::None;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Effect::CountWaveTracks()
|
|
|
|
{
|
|
|
|
mNumTracks = 0;
|
|
|
|
mNumGroups = 0;
|
|
|
|
|
|
|
|
TrackListOfKindIterator iter(Track::Wave, mTracks);
|
|
|
|
Track *t = iter.First();
|
|
|
|
|
|
|
|
while(t) {
|
|
|
|
if (!t->GetSelected()) {
|
|
|
|
t = iter.Next();
|
|
|
|
continue;
|
|
|
|
}
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
if (t->GetKind() == Track::Wave) {
|
|
|
|
mNumTracks++;
|
|
|
|
if (!t->GetLinked())
|
|
|
|
mNumGroups++;
|
|
|
|
}
|
|
|
|
t = iter.Next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-15 00:24:43 +00:00
|
|
|
double Effect::CalcPreviewInputLength(double previewLength)
|
|
|
|
{
|
|
|
|
return previewLength;
|
|
|
|
}
|
|
|
|
|
2015-01-02 05:24:43 +00:00
|
|
|
// RealtimeAddProcessor and RealtimeProcess use the same method of
|
|
|
|
// determining the current processor index, so updates to one should
|
|
|
|
// be reflected in the other.
|
|
|
|
bool Effect::RealtimeAddProcessor(int group, int chans, float rate)
|
|
|
|
{
|
|
|
|
int ichans = chans;
|
|
|
|
int ochans = chans;
|
|
|
|
int gchans = chans;
|
|
|
|
|
|
|
|
// Reset processor index
|
|
|
|
if (group == 0)
|
|
|
|
{
|
|
|
|
mCurrentProcessor = 0;
|
|
|
|
mGroupProcessor.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remember the processor starting index
|
|
|
|
mGroupProcessor.Add(mCurrentProcessor);
|
|
|
|
|
|
|
|
// Call the client until we run out of input or output channels
|
|
|
|
while (ichans > 0 && ochans > 0)
|
|
|
|
{
|
|
|
|
// If we don't have enough input channels to accomodate the client's
|
|
|
|
// requirements, then we replicate the input channels until the
|
|
|
|
// client's needs are met.
|
|
|
|
if (ichans < mNumAudioIn)
|
|
|
|
{
|
|
|
|
// All input channels have been consumed
|
|
|
|
ichans = 0;
|
|
|
|
}
|
|
|
|
// Otherwise fullfil the client's needs with as many input channels as possible.
|
|
|
|
// After calling the client with this set, we will loop back up to process more
|
|
|
|
// of the input/output channels.
|
|
|
|
else if (ichans >= mNumAudioIn)
|
|
|
|
{
|
|
|
|
gchans = mNumAudioIn;
|
|
|
|
ichans -= gchans;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't have enough output channels to accomodate the client's
|
|
|
|
// requirements, then we provide all of the output channels and fulfill
|
|
|
|
// the client's needs with dummy buffers. These will just get tossed.
|
|
|
|
if (ochans < mNumAudioOut)
|
|
|
|
{
|
|
|
|
// All output channels have been consumed
|
|
|
|
ochans = 0;
|
|
|
|
}
|
|
|
|
// Otherwise fullfil the client's needs with as many output channels as possible.
|
|
|
|
// After calling the client with this set, we will loop back up to process more
|
|
|
|
// of the input/output channels.
|
|
|
|
else if (ochans >= mNumAudioOut)
|
|
|
|
{
|
|
|
|
ochans -= mNumAudioOut;
|
|
|
|
}
|
|
|
|
|
2016-02-13 15:43:16 +00:00
|
|
|
// Add a NEW processor
|
2015-08-01 12:03:02 +00:00
|
|
|
RealtimeAddProcessor(gchans, rate);
|
2015-01-02 05:24:43 +00:00
|
|
|
|
|
|
|
// Bump to next processor
|
|
|
|
mCurrentProcessor++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// RealtimeAddProcessor and RealtimeProcess use the same method of
|
|
|
|
// determining the current processor group, so updates to one should
|
|
|
|
// be reflected in the other.
|
2014-11-03 06:48:54 +00:00
|
|
|
sampleCount Effect::RealtimeProcess(int group,
|
|
|
|
int chans,
|
|
|
|
float **inbuf,
|
|
|
|
float **outbuf,
|
|
|
|
sampleCount numSamples)
|
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-11-03 06:48:54 +00:00
|
|
|
//
|
|
|
|
// The caller passes the number of channels to process and specifies
|
|
|
|
// the number of input and output buffers. There will always be the
|
|
|
|
// same number of output buffers as there are input buffers.
|
|
|
|
//
|
|
|
|
// Effects always require a certain number of input and output buffers,
|
|
|
|
// so if the number of channels we're curently processing are different
|
2014-12-13 18:24:11 +00:00
|
|
|
// than what the effect expects, then we use a few methods of satisfying
|
2014-11-03 06:48:54 +00:00
|
|
|
// the effects requirements.
|
|
|
|
float **clientIn = (float **) alloca(mNumAudioIn * sizeof(float *));
|
|
|
|
float **clientOut = (float **) alloca(mNumAudioOut * sizeof(float *));
|
|
|
|
float *dummybuf = (float *) alloca(numSamples * sizeof(float));
|
|
|
|
sampleCount len = 0;
|
|
|
|
int ichans = chans;
|
|
|
|
int ochans = chans;
|
|
|
|
int gchans = chans;
|
|
|
|
int indx = 0;
|
|
|
|
int ondx = 0;
|
|
|
|
|
2015-01-02 05:24:43 +00:00
|
|
|
int processor = mGroupProcessor[group];
|
2014-11-03 22:47:55 +00:00
|
|
|
|
2014-11-03 06:48:54 +00:00
|
|
|
// Call the client until we run out of input or output channels
|
|
|
|
while (ichans > 0 && ochans > 0)
|
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-11-03 06:48:54 +00:00
|
|
|
// If we don't have enough input channels to accomodate the client's
|
|
|
|
// requirements, then we replicate the input channels until the
|
|
|
|
// client's needs are met.
|
|
|
|
if (ichans < mNumAudioIn)
|
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-11-03 06:48:54 +00:00
|
|
|
for (int i = 0; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
if (indx == ichans)
|
|
|
|
{
|
|
|
|
indx = 0;
|
|
|
|
}
|
|
|
|
clientIn[i] = inbuf[indx++];
|
|
|
|
}
|
|
|
|
|
|
|
|
// All input channels have been consumed
|
|
|
|
ichans = 0;
|
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-11-03 06:48:54 +00:00
|
|
|
// Otherwise fullfil the client's needs with as many input channels as possible.
|
|
|
|
// After calling the client with this set, we will loop back up to process more
|
|
|
|
// of the input/output channels.
|
|
|
|
else if (ichans >= mNumAudioIn)
|
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-11-03 06:48:54 +00:00
|
|
|
gchans = 0;
|
|
|
|
for (int i = 0; i < mNumAudioIn; i++, ichans--, gchans++)
|
|
|
|
{
|
|
|
|
clientIn[i] = inbuf[indx++];
|
|
|
|
}
|
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-11-03 06:48:54 +00:00
|
|
|
// If we don't have enough output channels to accomodate the client's
|
|
|
|
// requirements, then we provide all of the output channels and fulfill
|
|
|
|
// the client's needs with dummy buffers. These will just get tossed.
|
|
|
|
if (ochans < mNumAudioOut)
|
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-11-03 06:48:54 +00:00
|
|
|
for (int i = 0; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
if (i < ochans)
|
|
|
|
{
|
|
|
|
clientOut[i] = outbuf[i];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clientOut[i] = dummybuf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// All output channels have been consumed
|
|
|
|
ochans = 0;
|
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-11-03 06:48:54 +00:00
|
|
|
// Otherwise fullfil the client's needs with as many output channels as possible.
|
|
|
|
// After calling the client with this set, we will loop back up to process more
|
|
|
|
// of the input/output channels.
|
|
|
|
else if (ochans >= mNumAudioOut)
|
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-11-03 06:48:54 +00:00
|
|
|
for (int i = 0; i < mNumAudioOut; i++, ochans--)
|
|
|
|
{
|
|
|
|
clientOut[i] = outbuf[ondx++];
|
|
|
|
}
|
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-11-03 06:48:54 +00:00
|
|
|
|
|
|
|
// Finally call the plugin to process the block
|
2014-11-25 08:08:15 +00:00
|
|
|
len = 0;
|
2015-01-02 05:24:43 +00:00
|
|
|
for (sampleCount block = 0; block < numSamples; block += mBlockSize)
|
2014-11-25 08:08:15 +00:00
|
|
|
{
|
2015-01-02 05:24:43 +00:00
|
|
|
sampleCount cnt = (block + mBlockSize > numSamples ? numSamples - block : mBlockSize);
|
2015-08-01 12:03:02 +00:00
|
|
|
len += RealtimeProcess(processor, clientIn, clientOut, cnt);
|
2014-11-25 08:08:15 +00:00
|
|
|
|
|
|
|
for (int i = 0 ; i < mNumAudioIn; i++)
|
|
|
|
{
|
|
|
|
clientIn[i] += cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0 ; i < mNumAudioOut; i++)
|
|
|
|
{
|
|
|
|
clientOut[i] += cnt;
|
|
|
|
}
|
|
|
|
}
|
2015-01-02 05:24:43 +00:00
|
|
|
|
|
|
|
// Bump to next processor
|
|
|
|
processor++;
|
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-11-03 06:48:54 +00:00
|
|
|
return len;
|
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
|
|
|
bool Effect::IsRealtimeActive()
|
2015-01-02 05:24:43 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return mRealtimeSuspendCount == 0;
|
2015-01-02 05:24:43 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool Effect::IsHidden()
|
2014-12-13 18:24:11 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return false;
|
2014-12-13 18:24:11 +00:00
|
|
|
}
|
|
|
|
|
2013-05-02 23:41:27 +00:00
|
|
|
void Effect::Preview(bool dryOnly)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-05-28 16:31:07 +00:00
|
|
|
if (mNumTracks == 0) { // nothing to preview
|
2013-05-19 05:56:42 +00:00
|
|
|
return;
|
2015-05-28 16:31:07 +00:00
|
|
|
}
|
2013-05-19 05:56:42 +00:00
|
|
|
|
2015-05-28 16:31:07 +00:00
|
|
|
if (gAudioIO->IsBusy()) {
|
2010-01-23 19:44:49 +00:00
|
|
|
return;
|
2015-05-28 16:31:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
wxWindow *FocusDialog = wxWindow::FindFocus();
|
|
|
|
|
|
|
|
double previewDuration;
|
|
|
|
bool isNyquist = (GetFamily().IsSameAs(NYQUISTEFFECTS_FAMILY))? true : false;
|
|
|
|
bool isGenerator = GetType() == EffectTypeGenerate;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Mix a few seconds of audio from all of the tracks
|
2015-05-28 16:31:07 +00:00
|
|
|
double previewLen;
|
|
|
|
gPrefs->Read(wxT("/AudioIO/EffectsPreviewLen"), &previewLen, 6.0);
|
2013-02-15 00:24:43 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
double rate = mProjectRate;
|
2015-05-28 16:31:07 +00:00
|
|
|
|
|
|
|
if (isNyquist && isGenerator) {
|
|
|
|
previewDuration = CalcPreviewInputLength(previewLen);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
previewDuration = wxMin(mDuration, CalcPreviewInputLength(previewLen));
|
|
|
|
}
|
|
|
|
|
|
|
|
double t1 = mT0 + previewDuration;
|
|
|
|
|
|
|
|
if ((t1 > mT1) && !(isNyquist && isGenerator)) {
|
2015-05-15 11:47:51 +00:00
|
|
|
t1 = mT1;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-05-28 16:31:07 +00:00
|
|
|
|
|
|
|
if (t1 <= mT0)
|
2015-05-15 11:47:51 +00:00
|
|
|
return;
|
|
|
|
|
2015-05-16 08:00:47 +00:00
|
|
|
bool success = true;
|
2015-05-28 16:31:07 +00:00
|
|
|
double oldT0 = mT0;
|
|
|
|
double oldT1 = mT1;
|
|
|
|
// Most effects should stop at t1.
|
|
|
|
if (!mPreviewFullSelection)
|
|
|
|
mT1 = t1;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Save the original track list
|
|
|
|
TrackList *saveTracks = mTracks;
|
|
|
|
|
2016-02-13 15:43:16 +00:00
|
|
|
// Build NEW tracklist from rendering tracks
|
2010-01-23 19:44:49 +00:00
|
|
|
mTracks = new TrackList();
|
2015-05-15 11:47:51 +00:00
|
|
|
|
2015-05-28 16:31:07 +00:00
|
|
|
// Linear Effect preview optimised by pre-mixing to one track.
|
|
|
|
// Generators need to generate per track.
|
|
|
|
if (mIsLinearEffect && !isGenerator) {
|
2016-03-31 03:24:39 +00:00
|
|
|
WaveTrack::Holder mixLeft, mixRight;
|
|
|
|
MixAndRender(saveTracks, mFactory, rate, floatSample, mT0, t1, mixLeft, mixRight);
|
2016-03-13 07:14:46 +00:00
|
|
|
if (!mixLeft) {
|
2015-05-15 11:47:51 +00:00
|
|
|
delete mTracks;
|
|
|
|
mTracks = saveTracks;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-06-03 19:55:52 +00:00
|
|
|
mixLeft->Offset(-mixLeft->GetStartTime());
|
2015-05-28 16:31:07 +00:00
|
|
|
mixLeft->InsertSilence(0.0, mT0);
|
2015-05-15 11:47:51 +00:00
|
|
|
mixLeft->SetSelected(true);
|
|
|
|
mixLeft->SetDisplay(WaveTrack::NoDisplay);
|
2016-03-13 15:08:21 +00:00
|
|
|
mTracks->Add(std::move(mixLeft));
|
2015-05-15 11:47:51 +00:00
|
|
|
if (mixRight) {
|
2015-06-03 19:55:52 +00:00
|
|
|
mixRight->Offset(-mixRight->GetStartTime());
|
2015-05-28 16:31:07 +00:00
|
|
|
mixRight->InsertSilence(0.0, mT0);
|
2015-05-15 11:47:51 +00:00
|
|
|
mixRight->SetSelected(true);
|
2016-03-13 15:08:21 +00:00
|
|
|
mTracks->Add(std::move(mixRight));
|
2015-05-15 11:47:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
TrackListOfKindIterator iter(Track::Wave, saveTracks);
|
|
|
|
WaveTrack *src = (WaveTrack *) iter.First();
|
|
|
|
while (src)
|
|
|
|
{
|
2015-05-15 15:57:29 +00:00
|
|
|
if (src->GetSelected() || mPreviewWithNotSelected) {
|
2016-03-02 20:36:44 +00:00
|
|
|
auto dest = src->Copy(mT0, t1);
|
2015-05-28 16:31:07 +00:00
|
|
|
dest->InsertSilence(0.0, mT0);
|
2015-05-15 15:57:29 +00:00
|
|
|
dest->SetSelected(src->GetSelected());
|
2016-03-02 20:36:44 +00:00
|
|
|
static_cast<WaveTrack*>(dest.get())->SetDisplay(WaveTrack::NoDisplay);
|
2016-03-13 15:08:21 +00:00
|
|
|
mTracks->Add(std::move(dest));
|
2015-05-15 15:57:29 +00:00
|
|
|
}
|
2015-05-15 11:47:51 +00:00
|
|
|
src = (WaveTrack *) iter.Next();
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update track/group counts
|
|
|
|
CountWaveTracks();
|
|
|
|
|
|
|
|
// Apply effect
|
2013-05-02 23:41:27 +00:00
|
|
|
if (!dryOnly) {
|
2016-02-01 01:39:24 +00:00
|
|
|
ProgressDialog progress(GetName(),
|
|
|
|
_("Preparing preview"),
|
|
|
|
pdlgHideCancelButton); // Have only "Stop" button.
|
|
|
|
SetProgress sp(mProgress, &progress);
|
2015-05-28 16:31:07 +00:00
|
|
|
mIsPreview = true;
|
2015-05-16 08:00:47 +00:00
|
|
|
success = Process();
|
2015-05-28 16:31:07 +00:00
|
|
|
mIsPreview = false;
|
2013-05-02 23:41:27 +00:00
|
|
|
}
|
2014-10-06 21:53:58 +00:00
|
|
|
|
2015-05-16 08:00:47 +00:00
|
|
|
if (success)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
WaveTrackArray playbackTracks;
|
|
|
|
WaveTrackArray recordingTracks;
|
|
|
|
|
2015-05-15 11:47:51 +00:00
|
|
|
SelectedTrackListOfKindIterator iter(Track::Wave, mTracks);
|
|
|
|
WaveTrack *src = (WaveTrack *) iter.First();
|
2015-05-28 16:31:07 +00:00
|
|
|
while (src) {
|
2016-02-26 23:10:45 +00:00
|
|
|
playbackTracks.push_back(src);
|
2015-05-15 11:47:51 +00:00
|
|
|
src = (WaveTrack *) iter.Next();
|
|
|
|
}
|
2016-01-02 09:00:40 +00:00
|
|
|
// Some effects (Paulstretch) may need to generate more
|
|
|
|
// than previewLen, so take the min.
|
|
|
|
t1 = std::min(mT0 + previewLen, mT1);
|
2013-02-15 00:24:43 +00:00
|
|
|
|
2010-09-18 21:02:36 +00:00
|
|
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
|
|
|
NoteTrackArray empty;
|
|
|
|
#endif
|
2010-01-23 19:44:49 +00:00
|
|
|
// Start audio playing
|
|
|
|
int token =
|
2014-06-03 20:30:19 +00:00
|
|
|
gAudioIO->StartStream(playbackTracks, recordingTracks,
|
2010-01-23 19:44:49 +00:00
|
|
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
2010-09-18 21:02:36 +00:00
|
|
|
empty,
|
2010-01-23 19:44:49 +00:00
|
|
|
#endif
|
2015-05-28 16:31:07 +00:00
|
|
|
rate, mT0, t1);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
if (token) {
|
|
|
|
int previewing = eProgressSuccess;
|
2015-05-27 13:50:00 +00:00
|
|
|
// The progress dialog must be deleted before stopping the stream
|
|
|
|
// to allow events to flow to the app during StopStream processing.
|
|
|
|
// The progress dialog blocks these events.
|
2016-02-01 01:39:24 +00:00
|
|
|
{
|
|
|
|
ProgressDialog progress
|
|
|
|
(GetName(), _("Previewing"), pdlgHideCancelButton);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
while (gAudioIO->IsStreamActive(token) && previewing == eProgressSuccess) {
|
|
|
|
::wxMilliSleep(100);
|
|
|
|
previewing = progress.Update(gAudioIO->GetStreamTime() - mT0, t1 - mT0);
|
|
|
|
}
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
2015-05-27 13:50:00 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
gAudioIO->StopStream();
|
|
|
|
|
|
|
|
while (gAudioIO->IsBusy()) {
|
|
|
|
::wxMilliSleep(100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2014-07-21 21:37:53 +00:00
|
|
|
wxMessageBox(_("Error while opening sound device. Please check the playback device settings and the project sample rate."),
|
2015-05-15 11:47:51 +00:00
|
|
|
_("Error"), wxOK | wxICON_EXCLAMATION, FocusDialog);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FocusDialog) {
|
|
|
|
FocusDialog->SetFocus();
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
delete mOutputTracks;
|
|
|
|
mOutputTracks = NULL;
|
|
|
|
|
2016-03-13 14:34:44 +00:00
|
|
|
mTracks->Clear();
|
2015-04-17 03:53:42 +00:00
|
|
|
delete mTracks;
|
|
|
|
|
|
|
|
mTracks = saveTracks;
|
2015-05-28 16:31:07 +00:00
|
|
|
mT0 = oldT0;
|
|
|
|
mT1 = oldT1;
|
|
|
|
|
2015-05-15 11:47:51 +00:00
|
|
|
// Effect is already inited; we call Process, End, and then Init
|
|
|
|
// again, so the state is exactly the way it was before Preview
|
|
|
|
// was called.
|
|
|
|
if (!dryOnly) {
|
|
|
|
End();
|
|
|
|
Init();
|
|
|
|
}
|
2014-11-03 06:48:54 +00:00
|
|
|
}
|
|
|
|
|
2014-12-12 08:53:28 +00:00
|
|
|
BEGIN_EVENT_TABLE(EffectDialog, wxDialog)
|
|
|
|
EVT_BUTTON(wxID_OK, EffectDialog::OnOk)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
EffectDialog::EffectDialog(wxWindow * parent,
|
|
|
|
const wxString & title,
|
|
|
|
int type,
|
2013-05-02 23:41:27 +00:00
|
|
|
int flags,
|
|
|
|
int additionalButtons)
|
2010-01-23 19:44:49 +00:00
|
|
|
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, flags)
|
|
|
|
{
|
|
|
|
mType = type;
|
2013-05-02 23:41:27 +00:00
|
|
|
mAdditionalButtons = additionalButtons;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectDialog::Init()
|
|
|
|
{
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
S.SetBorder(5);
|
|
|
|
S.StartVerticalLay(true);
|
|
|
|
{
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
|
|
|
|
long buttons = eOkButton;
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mType != EffectTypeAnalyze)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2015-05-04 16:06:27 +00:00
|
|
|
buttons |= eCancelButton;
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mType == EffectTypeProcess)
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
buttons |= ePreviewButton;
|
|
|
|
}
|
|
|
|
}
|
2013-05-02 23:41:27 +00:00
|
|
|
S.AddStandardButtons(buttons|mAdditionalButtons);
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
|
|
|
|
Layout();
|
|
|
|
Fit();
|
|
|
|
SetMinSize(GetSize());
|
|
|
|
Center();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This is a virtual function which will be overridden to
|
|
|
|
/// provide the actual parameters that we want for each
|
|
|
|
/// kind of dialog.
|
2013-08-25 21:51:26 +00:00
|
|
|
void EffectDialog::PopulateOrExchange(ShuttleGui & WXUNUSED(S))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectDialog::TransferDataToWindow()
|
|
|
|
{
|
|
|
|
ShuttleGui S(this, eIsSettingToDialog);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectDialog::TransferDataFromWindow()
|
|
|
|
{
|
|
|
|
ShuttleGui S(this, eIsGettingFromDialog);
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectDialog::Validate()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt))
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
|
2014-12-12 08:53:28 +00:00
|
|
|
{
|
|
|
|
// On wxGTK (wx2.8.12), the default action is still executed even if
|
|
|
|
// the button is disabled. This appears to affect all wxDialogs, not
|
|
|
|
// just our Effects dialogs. So, this is a only temporary workaround
|
|
|
|
// for legacy effects that disable the OK button. Hopefully this has
|
|
|
|
// been corrected in wx3.
|
2015-05-15 23:50:08 +00:00
|
|
|
if (FindWindow(wxID_OK)->IsEnabled() && Validate() && TransferDataFromWindow())
|
2014-12-12 08:53:28 +00:00
|
|
|
{
|
|
|
|
EndModal(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-11-16 06:52:36 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// EffectPanel
|
|
|
|
//
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-02-24 06:06:39 +00:00
|
|
|
class EffectPanel final : public wxPanel
|
2014-11-16 06:52:36 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
EffectPanel(wxWindow *parent)
|
2015-04-17 03:53:42 +00:00
|
|
|
: wxPanel(parent)
|
2014-11-16 06:52:36 +00:00
|
|
|
{
|
2015-04-20 04:03:54 +00:00
|
|
|
// This fools NVDA into not saying "Panel" when the dialog gets focus
|
2015-04-20 17:33:03 +00:00
|
|
|
SetName(wxT("\a"));
|
|
|
|
SetLabel(wxT("\a"));
|
2015-04-20 04:03:54 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mAcceptsFocus = true;
|
2014-11-16 06:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~EffectPanel()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// wxWindow implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
2016-02-24 06:06:47 +00:00
|
|
|
bool AcceptsFocus() const override
|
2014-11-16 06:52:36 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
return mAcceptsFocus;
|
|
|
|
}
|
|
|
|
|
2015-11-26 15:21:48 +00:00
|
|
|
// So that wxPanel is not included in Tab traversal, when required - see wxWidgets bug 15581
|
2016-02-24 06:06:47 +00:00
|
|
|
bool AcceptsFocusFromKeyboard() const override
|
2015-11-26 15:21:48 +00:00
|
|
|
{
|
|
|
|
return mAcceptsFocus;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// ============================================================================
|
|
|
|
// EffectPanel implementation
|
|
|
|
// ============================================================================
|
|
|
|
void SetAccept(bool accept)
|
|
|
|
{
|
|
|
|
mAcceptsFocus = accept;
|
2014-11-16 06:52:36 +00:00
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool mAcceptsFocus;
|
2014-11-16 06:52:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// EffectUIHost
|
|
|
|
//
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
#include "../../images/Effect.h"
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
BEGIN_EVENT_TABLE(EffectUIHost, wxDialog)
|
2015-04-29 08:26:47 +00:00
|
|
|
EVT_INIT_DIALOG(EffectUIHost::OnInitDialog)
|
2015-04-17 03:53:42 +00:00
|
|
|
EVT_ERASE_BACKGROUND(EffectUIHost::OnErase)
|
|
|
|
EVT_PAINT(EffectUIHost::OnPaint)
|
2014-11-14 03:03:17 +00:00
|
|
|
EVT_CLOSE(EffectUIHost::OnClose)
|
2014-12-02 08:55:02 +00:00
|
|
|
EVT_BUTTON(wxID_APPLY, EffectUIHost::OnApply)
|
2014-11-14 03:03:17 +00:00
|
|
|
EVT_BUTTON(wxID_CANCEL, EffectUIHost::OnCancel)
|
2015-04-22 20:55:58 +00:00
|
|
|
EVT_BUTTON(eDebugID, EffectUIHost::OnDebug)
|
2014-12-02 08:55:02 +00:00
|
|
|
EVT_BUTTON(kMenuID, EffectUIHost::OnMenu)
|
2014-12-20 18:22:44 +00:00
|
|
|
EVT_CHECKBOX(kEnableID, EffectUIHost::OnEnable)
|
2014-12-02 08:55:02 +00:00
|
|
|
EVT_BUTTON(kPlayID, EffectUIHost::OnPlay)
|
|
|
|
EVT_BUTTON(kRewindID, EffectUIHost::OnRewind)
|
|
|
|
EVT_BUTTON(kFFwdID, EffectUIHost::OnFFwd)
|
2014-11-14 03:03:17 +00:00
|
|
|
EVT_MENU(kSaveAsID, EffectUIHost::OnSaveAs)
|
|
|
|
EVT_MENU(kImportID, EffectUIHost::OnImport)
|
|
|
|
EVT_MENU(kExportID, EffectUIHost::OnExport)
|
|
|
|
EVT_MENU(kOptionsID, EffectUIHost::OnOptions)
|
|
|
|
EVT_MENU(kDefaultsID, EffectUIHost::OnDefaults)
|
|
|
|
EVT_MENU_RANGE(kUserPresetsID, kUserPresetsID + 999, EffectUIHost::OnUserPreset)
|
|
|
|
EVT_MENU_RANGE(kDeletePresetID, kDeletePresetID + 999, EffectUIHost::OnDeletePreset)
|
|
|
|
EVT_MENU_RANGE(kFactoryPresetsID, kFactoryPresetsID + 999, EffectUIHost::OnFactoryPreset)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
EffectUIHost::EffectUIHost(wxWindow *parent,
|
2014-11-27 12:22:41 +00:00
|
|
|
Effect *effect,
|
2014-11-14 03:03:17 +00:00
|
|
|
EffectUIClientInterface *client)
|
2014-11-27 12:22:41 +00:00
|
|
|
: wxDialog(parent, wxID_ANY, effect->GetName(),
|
2015-04-17 03:53:42 +00:00
|
|
|
wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-07-12 00:33:04 +00:00
|
|
|
#if defined(__WXMAC__)
|
|
|
|
// Make sure the effect window actually floats above the main window
|
|
|
|
[[((NSView *)GetHandle()) window] setLevel:NSFloatingWindowLevel];
|
|
|
|
#endif
|
|
|
|
|
2014-11-27 12:22:41 +00:00
|
|
|
SetName(effect->GetName());
|
2014-11-14 03:03:17 +00:00
|
|
|
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
|
|
|
|
|
|
|
mParent = parent;
|
2014-11-27 12:22:41 +00:00
|
|
|
mEffect = effect;
|
2014-11-14 03:03:17 +00:00
|
|
|
mClient = client;
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
mProject = GetActiveProject();
|
|
|
|
|
2014-11-27 12:22:41 +00:00
|
|
|
mInitialized = false;
|
2015-04-17 03:53:42 +00:00
|
|
|
mSupportsRealtime = false;
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
mDisableTransport = false;
|
|
|
|
|
2014-12-20 18:22:44 +00:00
|
|
|
mEnabled = true;
|
2014-12-19 16:38:56 +00:00
|
|
|
|
2014-12-16 05:49:51 +00:00
|
|
|
mPlayPos = 0.0;
|
2014-12-13 18:24:11 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mClient->SetHostUI(this);
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EffectUIHost::~EffectUIHost()
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
CleanupRealtime();
|
|
|
|
|
|
|
|
if (mClient)
|
2014-11-27 12:22:41 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mClient->CloseUI();
|
|
|
|
mClient = NULL;
|
|
|
|
}
|
|
|
|
}
|
2015-01-06 18:01:04 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// ============================================================================
|
|
|
|
// wxWindow implementation
|
|
|
|
// ============================================================================
|
2015-01-06 18:01:04 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
bool EffectUIHost::TransferDataToWindow()
|
|
|
|
{
|
|
|
|
return mEffect->TransferDataToWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectUIHost::TransferDataFromWindow()
|
|
|
|
{
|
|
|
|
return mEffect->TransferDataFromWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// wxDialog implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
int EffectUIHost::ShowModal()
|
|
|
|
{
|
2015-05-04 16:06:27 +00:00
|
|
|
#if defined(__WXMSW__)
|
|
|
|
// Swap the Close and Apply buttons
|
|
|
|
wxSizer *sz = mApplyBtn->GetContainingSizer();
|
2016-02-13 23:06:49 +00:00
|
|
|
wxASSERT(mApplyBtn->GetParent()); // To justify safenew
|
|
|
|
wxButton *apply = safenew wxButton(mApplyBtn->GetParent(), wxID_APPLY);
|
2015-05-04 16:06:27 +00:00
|
|
|
sz->Replace(mCloseBtn, apply);
|
|
|
|
sz->Replace(mApplyBtn, mCloseBtn);
|
2015-05-17 16:10:16 +00:00
|
|
|
sz->Layout();
|
2015-05-04 16:06:27 +00:00
|
|
|
delete mApplyBtn;
|
|
|
|
mApplyBtn = apply;
|
|
|
|
mApplyBtn->SetDefault();
|
|
|
|
mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK, 0));
|
|
|
|
mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL, 0));
|
|
|
|
#else
|
2015-04-27 18:16:08 +00:00
|
|
|
mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK));
|
2015-05-04 16:06:27 +00:00
|
|
|
mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Layout();
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
return wxDialog::ShowModal();
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-11-16 06:52:36 +00:00
|
|
|
// ============================================================================
|
|
|
|
// EffectUIHost implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
bool EffectUIHost::Initialize()
|
|
|
|
{
|
2016-02-14 07:54:25 +00:00
|
|
|
EffectPanel *w = safenew EffectPanel(this);
|
2016-02-18 19:53:43 +00:00
|
|
|
{
|
|
|
|
auto vs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
|
|
|
{
|
|
|
|
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
// Try to give the window a sensible default/minimum size
|
|
|
|
w->SetMinSize(wxSize(wxMax(600, mParent->GetSize().GetWidth() * 2 / 3),
|
|
|
|
mParent->GetSize().GetHeight() / 2));
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
mDisableTransport = !gAudioIO->IsAvailable(mProject);
|
|
|
|
mPlaying = gAudioIO->IsStreamActive(); // not exactly right, but will suffice
|
|
|
|
mCapturing = gAudioIO->IsStreamActive() && gAudioIO->GetNumCaptureChannels() > 0;
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
if (!mClient->PopulateUI(w))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
hs->Add(w, 1, wxEXPAND);
|
|
|
|
vs->Add(hs.release(), 1, wxEXPAND);
|
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
wxPanel *buttonPanel = safenew wxPanel(this, wxID_ANY);
|
|
|
|
wxPanel *const bar = safenew wxPanel(buttonPanel, wxID_ANY);
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
// This fools NVDA into not saying "Panel" when the dialog gets focus
|
|
|
|
bar->SetName(wxT("\a"));
|
|
|
|
bar->SetLabel(wxT("\a"));
|
2015-04-20 15:05:53 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
{
|
|
|
|
auto bs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
mSupportsRealtime = mEffect->SupportsRealtime();
|
|
|
|
mIsGUI = mClient->IsGraphicalUI();
|
|
|
|
mIsBatch = mEffect->IsBatchProcessing();
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
wxBitmapButton *bb;
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
int margin = 0;
|
2014-12-16 22:35:29 +00:00
|
|
|
|
|
|
|
#if defined(__WXMAC__)
|
2016-02-18 19:53:43 +00:00
|
|
|
margin = 3; // I'm sure it's needed because of the order things are created...
|
2014-12-16 22:35:29 +00:00
|
|
|
#endif
|
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
if (!mIsGUI)
|
2016-02-18 19:50:52 +00:00
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
2016-02-18 19:53:43 +00:00
|
|
|
mMenuBtn = safenew wxButton(bar, kMenuID, _("&Manage"));
|
|
|
|
bs->Add(mMenuBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
2016-02-18 19:50:52 +00:00
|
|
|
}
|
2016-02-18 19:53:43 +00:00
|
|
|
else
|
2016-02-18 19:50:52 +00:00
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
2016-02-18 19:53:43 +00:00
|
|
|
mMenuBtn = safenew wxBitmapButton(bar, kMenuID, CreateBitmap(effect_menu_xpm, true, false));
|
2014-12-19 09:05:32 +00:00
|
|
|
#if defined(__WXMAC__)
|
2016-02-18 19:53:43 +00:00
|
|
|
mMenuBtn->SetName(_("&Manage"));
|
2014-12-19 09:05:32 +00:00
|
|
|
#else
|
2016-02-18 19:53:43 +00:00
|
|
|
mMenuBtn->SetLabel(_("&Manage"));
|
2014-12-19 09:05:32 +00:00
|
|
|
#endif
|
2016-02-18 19:53:43 +00:00
|
|
|
bs->Add(mMenuBtn);
|
2016-02-18 19:50:52 +00:00
|
|
|
}
|
2016-02-18 19:53:43 +00:00
|
|
|
mMenuBtn->SetToolTip(_("Manage presets and options"));
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
bs->Add(5, 5);
|
|
|
|
|
|
|
|
if (!mIsBatch)
|
2015-04-26 21:41:05 +00:00
|
|
|
{
|
2016-02-18 19:53:43 +00:00
|
|
|
if (!mIsGUI)
|
|
|
|
{
|
|
|
|
if (mSupportsRealtime)
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
mPlayToggleBtn = safenew wxButton(bar, kPlayID, _("Start &Playback"));
|
|
|
|
mPlayToggleBtn->SetToolTip(_("Start and stop playback"));
|
|
|
|
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
|
|
|
}
|
|
|
|
else if (mEffect->GetType() != EffectTypeAnalyze)
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
mPlayToggleBtn = safenew wxButton(bar, kPlayID, _("&Preview"));
|
|
|
|
mPlayToggleBtn->SetToolTip(_("Preview effect"));
|
|
|
|
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mPlayBM = CreateBitmap(effect_play_xpm, true, false);
|
|
|
|
mPlayDisabledBM = CreateBitmap(effect_play_disabled_xpm, true, false);
|
|
|
|
mStopBM = CreateBitmap(effect_stop_xpm, true, false);
|
|
|
|
mStopDisabledBM = CreateBitmap(effect_stop_disabled_xpm, true, false);
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
bb = safenew wxBitmapButton(bar, kPlayID, mPlayBM);
|
|
|
|
bb->SetBitmapDisabled(mPlayDisabledBM);
|
|
|
|
mPlayBtn = bb;
|
|
|
|
bs->Add(mPlayBtn);
|
|
|
|
if (!mSupportsRealtime)
|
|
|
|
{
|
|
|
|
mPlayBtn->SetToolTip(_("Preview effect"));
|
2014-12-19 09:05:32 +00:00
|
|
|
#if defined(__WXMAC__)
|
2016-02-18 19:53:43 +00:00
|
|
|
mPlayBtn->SetName(_("Preview effect"));
|
2014-12-19 09:05:32 +00:00
|
|
|
#else
|
2016-02-18 19:53:43 +00:00
|
|
|
mPlayBtn->SetLabel(_("&Preview effect"));
|
2014-12-19 09:05:32 +00:00
|
|
|
#endif
|
2016-02-18 19:53:43 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
if (mSupportsRealtime)
|
|
|
|
{
|
|
|
|
if (!mIsGUI)
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
mRewindBtn = safenew wxButton(bar, kRewindID, _("Skip &Backward"));
|
|
|
|
bs->Add(mRewindBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
bb = safenew wxBitmapButton(bar, kRewindID, CreateBitmap(effect_rewind_xpm, true, true));
|
|
|
|
bb->SetBitmapDisabled(CreateBitmap(effect_rewind_disabled_xpm, true, true));
|
|
|
|
mRewindBtn = bb;
|
|
|
|
#if defined(__WXMAC__)
|
|
|
|
mRewindBtn->SetName(_("Skip &Backward"));
|
|
|
|
#else
|
|
|
|
mRewindBtn->SetLabel(_("Skip &Backward"));
|
|
|
|
#endif
|
|
|
|
bs->Add(mRewindBtn);
|
|
|
|
}
|
|
|
|
mRewindBtn->SetToolTip(_("Skip backward"));
|
|
|
|
|
|
|
|
if (!mIsGUI)
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
mFFwdBtn = safenew wxButton(bar, kFFwdID, _("Skip &Forward"));
|
|
|
|
bs->Add(mFFwdBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxASSERT(bar); // To justify safenew
|
|
|
|
bb = safenew wxBitmapButton(bar, kFFwdID, CreateBitmap(effect_ffwd_xpm, true, true));
|
|
|
|
bb->SetBitmapDisabled(CreateBitmap(effect_ffwd_disabled_xpm, true, true));
|
|
|
|
mFFwdBtn = bb;
|
2016-02-18 07:54:50 +00:00
|
|
|
#if defined(__WXMAC__)
|
2016-02-18 19:53:43 +00:00
|
|
|
mFFwdBtn->SetName(_("Skip &Foreward"));
|
2016-02-18 07:54:50 +00:00
|
|
|
#else
|
2016-02-18 19:53:43 +00:00
|
|
|
mFFwdBtn->SetLabel(_("Skip &Foreward"));
|
2016-02-18 07:54:50 +00:00
|
|
|
#endif
|
2016-02-18 19:53:43 +00:00
|
|
|
bs->Add(mFFwdBtn);
|
|
|
|
}
|
|
|
|
mFFwdBtn->SetToolTip(_("Skip forward"));
|
|
|
|
|
|
|
|
bs->Add(5, 5);
|
|
|
|
|
|
|
|
mEnableCb = safenew wxCheckBox(bar, kEnableID, _("&Enable"));
|
|
|
|
mEnableCb->SetValue(mEnabled);
|
|
|
|
mEnableCb->SetName(_("Enable"));
|
|
|
|
bs->Add(mEnableCb, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
|
|
|
|
}
|
2015-04-26 21:41:05 +00:00
|
|
|
}
|
2014-12-20 18:22:44 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
bar->SetSizerAndFit(bs.release());
|
|
|
|
}
|
2014-12-20 18:22:44 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
long buttons = eApplyButton + eCloseButton;
|
|
|
|
if (mEffect->mUIDebug)
|
|
|
|
{
|
|
|
|
buttons += eDebugButton;
|
2015-04-26 21:41:05 +00:00
|
|
|
}
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
buttonPanel->SetSizer(CreateStdButtonSizer(buttonPanel, buttons, bar).release());
|
|
|
|
vs->Add(buttonPanel, 0, wxEXPAND);
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2016-02-18 19:53:43 +00:00
|
|
|
SetSizer(vs.release());
|
2015-04-26 21:41:05 +00:00
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
Layout();
|
|
|
|
Fit();
|
|
|
|
Center();
|
|
|
|
|
2015-05-15 23:50:08 +00:00
|
|
|
mApplyBtn = (wxButton *) FindWindow(wxID_APPLY);
|
|
|
|
mCloseBtn = (wxButton *) FindWindow(wxID_CANCEL);
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
UpdateControls();
|
|
|
|
|
|
|
|
w->SetAccept(!mIsGUI);
|
2015-05-15 23:50:08 +00:00
|
|
|
(!mIsGUI ? w : FindWindow(wxID_APPLY))->SetFocus();
|
2014-11-25 08:08:15 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
LoadUserPresets();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
InitializeRealtime();
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2015-06-30 16:25:32 +00:00
|
|
|
SetMinSize(GetSize());
|
2015-04-17 03:53:42 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2015-04-29 08:26:47 +00:00
|
|
|
void EffectUIHost::OnInitDialog(wxInitDialogEvent & evt)
|
|
|
|
{
|
|
|
|
// Do default handling
|
|
|
|
wxDialog::OnInitDialog(evt);
|
|
|
|
|
|
|
|
#if wxCHECK_VERSION(3, 0, 0)
|
2015-05-16 20:40:29 +00:00
|
|
|
//#warning "check to see if this still needed in wx3"
|
2015-04-29 08:26:47 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Pure hackage coming down the pike...
|
|
|
|
//
|
|
|
|
// I have no idea why, but if a wxTextCtrl is the first control in the
|
|
|
|
// panel, then its contents will not be automatically selected when the
|
|
|
|
// dialog is displayed.
|
|
|
|
//
|
|
|
|
// So, we do the selection manually.
|
|
|
|
wxTextCtrl *focused = wxDynamicCast(FindFocus(), wxTextCtrl);
|
|
|
|
if (focused)
|
|
|
|
{
|
|
|
|
focused->SelectAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectUIHost::OnErase(wxEraseEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
// Ignore it
|
|
|
|
}
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
void EffectUIHost::OnPaint(wxPaintEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
wxPaintDC dc(this);
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
dc.Clear();
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnClose(wxCloseEvent & WXUNUSED(evt))
|
|
|
|
{
|
2016-04-23 12:49:11 +00:00
|
|
|
DoCancel();
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
CleanupRealtime();
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2014-11-16 06:52:36 +00:00
|
|
|
Hide();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
mClient->CloseUI();
|
|
|
|
mClient = NULL;
|
2015-04-17 03:53:42 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
Destroy();
|
|
|
|
}
|
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
void EffectUIHost::OnApply(wxCommandEvent & evt)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
// On wxGTK (wx2.8.12), the default action is still executed even if
|
|
|
|
// the button is disabled. This appears to affect all wxDialogs, not
|
|
|
|
// just our Effects dialogs. So, this is a only temporary workaround
|
|
|
|
// for legacy effects that disable the OK button. Hopefully this has
|
|
|
|
// been corrected in wx3.
|
2015-05-15 23:50:08 +00:00
|
|
|
if (!FindWindow(wxID_APPLY)->IsEnabled())
|
2015-04-17 03:53:42 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-05-17 06:02:52 +00:00
|
|
|
// Honor the "select all if none" preference...a little hackish, but whatcha gonna do...
|
2015-04-26 21:41:05 +00:00
|
|
|
if (!mIsBatch && mEffect->GetType() != EffectTypeGenerate && mProject->mViewInfo.selectedRegion.isPoint())
|
2014-12-16 05:49:51 +00:00
|
|
|
{
|
2016-05-06 00:02:13 +00:00
|
|
|
auto flags = AlwaysEnabledFlag;
|
2015-05-17 06:02:52 +00:00
|
|
|
bool allowed = mProject->TryToMakeActionAllowed(flags,
|
|
|
|
WaveTracksSelectedFlag | TimeSelectedFlag,
|
|
|
|
WaveTracksSelectedFlag | TimeSelectedFlag);
|
|
|
|
if (!allowed)
|
|
|
|
{
|
|
|
|
wxMessageBox(_("You must select audio in the project window."));
|
|
|
|
return;
|
|
|
|
}
|
2014-12-16 05:49:51 +00:00
|
|
|
}
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
if (!mClient->ValidateUI())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
// This will take care of calling TransferDataFromWindow()
|
|
|
|
if (!mEffect->SaveUserPreset(mEffect->GetCurrentSettingsGroup()))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-11-27 12:22:41 +00:00
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
mEffect->mUIResultID = evt.GetId();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
if (IsModal())
|
|
|
|
{
|
2016-04-24 14:30:46 +00:00
|
|
|
mDismissed = true;
|
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
EndModal(true);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
|
|
|
Close();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-05-04 17:15:54 +00:00
|
|
|
// Progress dialog no longer yields, so this "shouldn't" be necessary (yet to be proven
|
|
|
|
// for sure), but it is a nice visual cue that something is going on.
|
|
|
|
mApplyBtn->Disable();
|
2015-05-04 16:06:27 +00:00
|
|
|
|
2014-11-27 12:22:41 +00:00
|
|
|
mEffect->Apply();
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2015-05-04 16:06:27 +00:00
|
|
|
mApplyBtn->Enable();
|
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-23 12:49:11 +00:00
|
|
|
void EffectUIHost::DoCancel()
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2016-04-24 14:30:46 +00:00
|
|
|
if (!mDismissed) {
|
2016-04-23 12:49:11 +00:00
|
|
|
mEffect->mUIResultID = wxID_CANCEL;
|
2015-04-22 20:55:58 +00:00
|
|
|
|
2016-04-23 12:49:11 +00:00
|
|
|
if (IsModal())
|
|
|
|
EndModal(false);
|
|
|
|
else
|
|
|
|
Hide();
|
2014-11-19 06:58:44 +00:00
|
|
|
|
2016-04-24 14:30:46 +00:00
|
|
|
mDismissed = true;
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
2016-04-23 12:49:11 +00:00
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2016-04-23 12:49:11 +00:00
|
|
|
void EffectUIHost::OnCancel(wxCommandEvent & evt)
|
|
|
|
{
|
|
|
|
DoCancel();
|
2014-11-16 06:52:36 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
Close();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-22 20:55:58 +00:00
|
|
|
void EffectUIHost::OnDebug(wxCommandEvent & evt)
|
|
|
|
{
|
|
|
|
OnApply(evt);
|
|
|
|
|
|
|
|
mEffect->mUIResultID = evt.GetId();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-15 21:54:23 +00:00
|
|
|
void EffectUIHost::OnMenu(wxCommandEvent & WXUNUSED(evt))
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2016-02-01 01:39:24 +00:00
|
|
|
wxMenu menu;
|
2014-12-02 08:55:02 +00:00
|
|
|
wxMenu *sub;
|
|
|
|
|
|
|
|
LoadUserPresets();
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
if (mUserPresets.GetCount() == 0)
|
|
|
|
{
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(kUserPresetsDummyID, _("User Presets"))->Enable(false);
|
2014-12-04 06:10:27 +00:00
|
|
|
}
|
|
|
|
else
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
sub = new wxMenu();
|
|
|
|
for (size_t i = 0, cnt = mUserPresets.GetCount(); i < cnt; i++)
|
|
|
|
{
|
|
|
|
sub->Append(kUserPresetsID + i, mUserPresets[i]);
|
|
|
|
}
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(0, _("User Presets"), sub);
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(kSaveAsID, _("Save Preset..."));
|
2015-05-20 02:13:20 +00:00
|
|
|
|
|
|
|
if (mUserPresets.GetCount() == 0)
|
|
|
|
{
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(kDeletePresetDummyID, _("Delete Preset"))->Enable(false);
|
2015-05-20 02:13:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sub = new wxMenu();
|
|
|
|
for (size_t i = 0, cnt = mUserPresets.GetCount(); i < cnt; i++)
|
|
|
|
{
|
|
|
|
sub->Append(kDeletePresetID + i, mUserPresets[i]);
|
|
|
|
}
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(0, _("Delete Preset"), sub);
|
2015-05-20 02:13:20 +00:00
|
|
|
}
|
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.AppendSeparator();
|
2015-05-20 02:13:20 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
wxArrayString factory = mEffect->GetFactoryPresets();
|
2014-12-02 08:55:02 +00:00
|
|
|
|
|
|
|
sub = new wxMenu();
|
|
|
|
sub->Append(kDefaultsID, _("Defaults"));
|
|
|
|
if (factory.GetCount() > 0)
|
|
|
|
{
|
|
|
|
sub->AppendSeparator();
|
|
|
|
for (size_t i = 0, cnt = factory.GetCount(); i < cnt; i++)
|
|
|
|
{
|
|
|
|
wxString label = factory[i];
|
|
|
|
if (label.IsEmpty())
|
|
|
|
{
|
|
|
|
label = _("None");
|
|
|
|
}
|
|
|
|
|
|
|
|
sub->Append(kFactoryPresetsID + i, label);
|
|
|
|
}
|
|
|
|
}
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(0, _("Factory Presets"), sub);
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.AppendSeparator();
|
|
|
|
menu.Append(kImportID, _("Import..."))->Enable(mClient->CanExportPresets());
|
|
|
|
menu.Append(kExportID, _("Export..."))->Enable(mClient->CanExportPresets());
|
|
|
|
menu.AppendSeparator();
|
|
|
|
menu.Append(kOptionsID, _("Options..."))->Enable(mClient->HasOptions());
|
|
|
|
menu.AppendSeparator();
|
2014-12-02 08:55:02 +00:00
|
|
|
|
|
|
|
sub = new wxMenu();
|
|
|
|
|
|
|
|
sub->Append(kDummyID, wxString::Format(_("Type: %s"), mEffect->GetFamily().c_str()));
|
|
|
|
sub->Append(kDummyID, wxString::Format(_("Name: %s"), mEffect->GetName().c_str()));
|
|
|
|
sub->Append(kDummyID, wxString::Format(_("Version: %s"), mEffect->GetVersion().c_str()));
|
|
|
|
sub->Append(kDummyID, wxString::Format(_("Vendor: %s"), mEffect->GetVendor().c_str()));
|
|
|
|
sub->Append(kDummyID, wxString::Format(_("Description: %s"), mEffect->GetDescription().c_str()));
|
|
|
|
|
2016-02-01 01:39:24 +00:00
|
|
|
menu.Append(0, _("About"), sub);
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2015-05-24 09:47:24 +00:00
|
|
|
wxWindow *btn = FindWindow(kMenuID);
|
|
|
|
wxRect r = btn->GetRect();
|
2016-02-01 01:39:24 +00:00
|
|
|
btn->PopupMenu(&menu, r.GetLeft(), r.GetBottom());
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
2014-12-19 06:57:22 +00:00
|
|
|
void EffectUIHost::OnEnable(wxCommandEvent & WXUNUSED(evt))
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2014-12-20 18:22:44 +00:00
|
|
|
mEnabled = mEnableCb->GetValue();
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2014-12-20 18:22:44 +00:00
|
|
|
if (mEnabled)
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2014-12-20 18:22:44 +00:00
|
|
|
mEffect->RealtimeResume();
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-12-20 18:22:44 +00:00
|
|
|
mEffect->RealtimeSuspend();
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UpdateControls();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnPlay(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!mSupportsRealtime)
|
|
|
|
{
|
|
|
|
if (!mClient->ValidateUI() || !mEffect->TransferDataFromWindow())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mEffect->Preview(false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
if (mPlaying)
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
mPlayPos = gAudioIO->GetStreamTime();
|
2014-12-19 16:38:56 +00:00
|
|
|
mProject->GetControlToolBar()->StopPlaying();
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-12-19 16:38:56 +00:00
|
|
|
if (mProject->IsPlayRegionLocked())
|
2014-12-16 05:49:51 +00:00
|
|
|
{
|
|
|
|
double t0, t1;
|
2014-12-19 16:38:56 +00:00
|
|
|
mProject->GetPlayRegion(&t0, &t1);
|
2014-12-16 05:49:51 +00:00
|
|
|
mRegion.setTimes(t0, t1);
|
|
|
|
mPlayPos = mRegion.t0();
|
|
|
|
}
|
2014-12-19 16:38:56 +00:00
|
|
|
else if (mProject->mViewInfo.selectedRegion.t0() != mRegion.t0() ||
|
|
|
|
mProject->mViewInfo.selectedRegion.t1() != mRegion.t1())
|
2014-12-04 06:10:27 +00:00
|
|
|
{
|
2014-12-19 16:38:56 +00:00
|
|
|
mRegion = mProject->mViewInfo.selectedRegion;
|
2014-12-04 06:10:27 +00:00
|
|
|
mPlayPos = mRegion.t0();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mPlayPos > mRegion.t1())
|
|
|
|
{
|
|
|
|
mPlayPos = mRegion.t1();
|
|
|
|
}
|
|
|
|
|
2015-04-14 18:52:22 +00:00
|
|
|
mProject->GetControlToolBar()->PlayPlayRegion
|
|
|
|
(SelectedRegion(mPlayPos, mRegion.t1()),
|
2016-04-18 21:50:17 +00:00
|
|
|
mProject->GetDefaultPlayOptions(), PlayMode::normalPlay);
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnRewind(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
if (mPlaying)
|
|
|
|
{
|
|
|
|
double seek;
|
|
|
|
gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
|
|
|
|
|
|
|
|
double pos = gAudioIO->GetStreamTime();
|
|
|
|
if (pos - seek < mRegion.t0())
|
|
|
|
{
|
|
|
|
seek = pos - mRegion.t0();
|
|
|
|
}
|
|
|
|
|
|
|
|
gAudioIO->SeekStream(-seek);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mPlayPos = mRegion.t0();
|
|
|
|
}
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnFFwd(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
if (mPlaying)
|
|
|
|
{
|
|
|
|
double seek;
|
|
|
|
gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
|
|
|
|
|
|
|
|
double pos = gAudioIO->GetStreamTime();
|
|
|
|
if (mRegion.t0() < mRegion.t1() && pos + seek > mRegion.t1())
|
|
|
|
{
|
|
|
|
seek = mRegion.t1() - pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
gAudioIO->SeekStream(seek);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// It allows to play past end of selection...probably useless
|
|
|
|
mPlayPos = mRegion.t1();
|
|
|
|
}
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnPlayback(wxCommandEvent & evt)
|
|
|
|
{
|
2014-12-17 19:16:08 +00:00
|
|
|
evt.Skip();
|
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
if (evt.GetInt() != 0)
|
|
|
|
{
|
|
|
|
if (evt.GetEventObject() != mProject)
|
|
|
|
{
|
|
|
|
mDisableTransport = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mPlaying = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mDisableTransport = false;
|
|
|
|
mPlaying = false;
|
|
|
|
}
|
2014-12-04 06:10:27 +00:00
|
|
|
|
|
|
|
if (mPlaying)
|
|
|
|
{
|
2014-12-19 16:38:56 +00:00
|
|
|
mRegion = mProject->mViewInfo.selectedRegion;
|
2014-12-04 06:10:27 +00:00
|
|
|
mPlayPos = mRegion.t0();
|
|
|
|
}
|
|
|
|
|
2014-12-02 08:55:02 +00:00
|
|
|
UpdateControls();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnCapture(wxCommandEvent & evt)
|
|
|
|
{
|
2014-12-17 19:16:08 +00:00
|
|
|
evt.Skip();
|
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
if (evt.GetInt() != 0)
|
|
|
|
{
|
|
|
|
if (evt.GetEventObject() != mProject)
|
|
|
|
{
|
|
|
|
mDisableTransport = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mCapturing = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mDisableTransport = false;
|
|
|
|
mCapturing = false;
|
|
|
|
}
|
|
|
|
|
2014-12-02 08:55:02 +00:00
|
|
|
UpdateControls();
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::OnUserPreset(wxCommandEvent & evt)
|
2014-12-02 08:55:02 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
int preset = evt.GetId() - kUserPresetsID;
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
mEffect->LoadUserPreset(mEffect->GetUserPresetsGroup(mUserPresets[preset]));
|
2014-12-02 08:55:02 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
return;
|
2014-12-02 08:55:02 +00:00
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::OnFactoryPreset(wxCommandEvent & evt)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mEffect->LoadFactoryPreset(evt.GetId() - kFactoryPresetsID);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::OnDeletePreset(wxCommandEvent & evt)
|
|
|
|
{
|
|
|
|
wxString preset = mUserPresets[evt.GetId() - kDeletePresetID];
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
int res = wxMessageBox(wxString::Format(_("Are you sure you want to delete \"%s\"?"), preset.c_str()),
|
|
|
|
_("Delete Preset"),
|
|
|
|
wxICON_QUESTION | wxYES_NO);
|
|
|
|
if (res == wxYES)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
mEffect->RemovePrivateConfigSubgroup(mEffect->GetUserPresetsGroup(preset));
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
LoadUserPresets();
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
return;
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnSaveAs(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
wxTextCtrl *text;
|
|
|
|
wxString name;
|
|
|
|
wxDialog dlg(this, wxID_ANY, wxString(_("Save Preset")));
|
2014-11-29 01:22:41 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
ShuttleGui S(&dlg, eIsCreating);
|
|
|
|
|
|
|
|
S.StartPanel();
|
|
|
|
{
|
2015-05-17 05:19:35 +00:00
|
|
|
S.StartVerticalLay(1);
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
|
|
|
S.StartHorizontalLay(wxALIGN_LEFT, 0);
|
|
|
|
{
|
|
|
|
text = S.AddTextBox(_("Preset name:"), name, 30);
|
|
|
|
}
|
|
|
|
S.EndHorizontalLay();
|
2015-05-17 05:19:35 +00:00
|
|
|
S.SetBorder(10);
|
2014-11-14 03:03:17 +00:00
|
|
|
S.AddStandardButtons();
|
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
}
|
|
|
|
S.EndPanel();
|
2015-05-17 05:19:35 +00:00
|
|
|
|
2014-11-14 03:03:17 +00:00
|
|
|
dlg.SetSize(dlg.GetSizer()->GetMinSize());
|
|
|
|
dlg.Center();
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
int rc = dlg.ShowModal();
|
|
|
|
|
|
|
|
if (rc != wxID_OK)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = text->GetValue();
|
2015-05-17 05:19:35 +00:00
|
|
|
if (name.IsEmpty())
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-05-17 05:19:35 +00:00
|
|
|
wxMessageDialog md(this,
|
|
|
|
_("You must specify a name"),
|
|
|
|
_("Save Preset"));
|
|
|
|
md.Center();
|
|
|
|
md.ShowModal();
|
|
|
|
continue;
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
2015-05-17 05:19:35 +00:00
|
|
|
if (mUserPresets.Index(name) != wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
wxMessageDialog md(this,
|
|
|
|
_("Preset already exists.\n\nReplace?"),
|
|
|
|
_("Save Preset"),
|
|
|
|
wxYES_NO | wxCANCEL | wxICON_EXCLAMATION);
|
|
|
|
md.Center();
|
|
|
|
int choice = md.ShowModal();
|
|
|
|
if (choice == wxID_CANCEL)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (choice == wxID_NO)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mEffect->SaveUserPreset(mEffect->GetUserPresetsGroup(name));
|
|
|
|
LoadUserPresets();
|
|
|
|
|
|
|
|
break;
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnImport(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
mClient->ImportPresets();
|
|
|
|
|
|
|
|
LoadUserPresets();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::OnExport(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
mClient->ExportPresets();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::OnOptions(wxCommandEvent & WXUNUSED(evt))
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
mClient->ShowOptions();
|
2014-11-14 03:03:17 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::OnDefaults(wxCommandEvent & WXUNUSED(evt))
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mEffect->LoadFactoryDefaults();
|
2014-11-14 03:03:17 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
wxBitmap EffectUIHost::CreateBitmap(const char *xpm[], bool up, bool pusher)
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2014-12-04 06:10:27 +00:00
|
|
|
wxMemoryDC dc;
|
|
|
|
wxBitmap pic(xpm);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6);
|
|
|
|
dc.SelectObject(mod);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
#if !defined(__WXMAC__)
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
#if defined(__WXGTK__)
|
|
|
|
wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BACKGROUND);
|
|
|
|
#elif defined(__WXMSW__)
|
|
|
|
wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
|
|
|
|
#endif
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
dc.SetBackground(wxBrush(newColour));
|
|
|
|
dc.Clear();
|
|
|
|
#endif
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
int offset = 3;
|
|
|
|
if (pusher)
|
|
|
|
{
|
|
|
|
if (!up)
|
|
|
|
{
|
|
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
dc.DrawBitmap(pic, offset, offset, true);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
dc.SelectObject(wxNullBitmap);
|
|
|
|
|
|
|
|
return mod;
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
void EffectUIHost::UpdateControls()
|
2014-11-14 03:03:17 +00:00
|
|
|
{
|
2015-04-26 21:41:05 +00:00
|
|
|
if (mIsBatch)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-19 16:38:56 +00:00
|
|
|
if (mCapturing || mDisableTransport)
|
|
|
|
{
|
|
|
|
// Don't allow focus to get trapped
|
|
|
|
wxWindow *focus = FindFocus();
|
2014-12-20 18:22:44 +00:00
|
|
|
if (focus == mRewindBtn || focus == mFFwdBtn || focus == mPlayBtn || focus == mEnableCb)
|
2014-12-19 16:38:56 +00:00
|
|
|
{
|
|
|
|
mCloseBtn->SetFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:10:27 +00:00
|
|
|
mApplyBtn->Enable(!mCapturing);
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mEffect->GetType() != EffectTypeAnalyze)
|
|
|
|
{
|
|
|
|
(!mIsGUI ? mPlayToggleBtn : mPlayBtn)->Enable(!(mCapturing || mDisableTransport));
|
|
|
|
}
|
2014-12-16 21:41:58 +00:00
|
|
|
|
2015-04-17 03:53:42 +00:00
|
|
|
if (mSupportsRealtime)
|
2014-12-15 09:18:42 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
mRewindBtn->Enable(!(mCapturing || mDisableTransport));
|
|
|
|
mFFwdBtn->Enable(!(mCapturing || mDisableTransport));
|
|
|
|
mEnableCb->Enable(!(mCapturing || mDisableTransport));
|
|
|
|
|
|
|
|
wxBitmapButton *bb;
|
|
|
|
|
|
|
|
if (mPlaying)
|
2014-12-16 21:41:58 +00:00
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!mIsGUI)
|
|
|
|
{
|
|
|
|
/* i18n-hint: The access key "&P" should be the same in
|
|
|
|
"Stop &Playback" and "Start &Playback" */
|
|
|
|
mPlayToggleBtn->SetLabel(_("Stop &Playback"));
|
|
|
|
mPlayToggleBtn->Refresh();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bb = (wxBitmapButton *) mPlayBtn;
|
|
|
|
bb->SetBitmapLabel(mStopBM);
|
|
|
|
bb->SetBitmapDisabled(mStopDisabledBM);
|
|
|
|
bb->SetToolTip(_("Stop"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#if defined(__WXMAC__)
|
2015-04-17 03:53:42 +00:00
|
|
|
bb->SetName(_("Stop &Playback"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#else
|
2015-04-17 03:53:42 +00:00
|
|
|
bb->SetLabel(_("Stop &Playback"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#endif
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
2014-12-16 21:41:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-04-17 03:53:42 +00:00
|
|
|
if (!mIsGUI)
|
|
|
|
{
|
|
|
|
/* i18n-hint: The access key "&P" should be the same in
|
|
|
|
"Stop &Playback" and "Start &Playback" */
|
|
|
|
mPlayToggleBtn->SetLabel(_("Start &Playback"));
|
|
|
|
mPlayToggleBtn->Refresh();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bb = (wxBitmapButton *) mPlayBtn;
|
|
|
|
bb->SetBitmapLabel(mPlayBM);
|
|
|
|
bb->SetBitmapDisabled(mPlayDisabledBM);
|
|
|
|
bb->SetToolTip(_("Play"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#if defined(__WXMAC__)
|
2015-04-17 03:53:42 +00:00
|
|
|
bb->SetName(_("Start &Playback"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#else
|
2015-04-17 03:53:42 +00:00
|
|
|
bb->SetLabel(_("Start &Playback"));
|
2014-12-19 06:57:22 +00:00
|
|
|
#endif
|
2015-04-17 03:53:42 +00:00
|
|
|
}
|
2014-12-16 21:41:58 +00:00
|
|
|
}
|
2014-12-14 16:28:19 +00:00
|
|
|
}
|
2014-11-14 03:03:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::LoadUserPresets()
|
|
|
|
{
|
|
|
|
mUserPresets.Clear();
|
|
|
|
|
2014-11-27 12:22:41 +00:00
|
|
|
mEffect->GetPrivateConfigSubgroups(mEffect->GetUserPresetsGroup(wxEmptyString), mUserPresets);
|
2014-11-14 03:03:17 +00:00
|
|
|
|
|
|
|
mUserPresets.Sort();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2015-04-17 03:53:42 +00:00
|
|
|
|
|
|
|
void EffectUIHost::InitializeRealtime()
|
|
|
|
{
|
|
|
|
if (mSupportsRealtime && !mInitialized)
|
|
|
|
{
|
|
|
|
EffectManager::Get().RealtimeAddEffect(mEffect);
|
|
|
|
|
|
|
|
wxTheApp->Connect(EVT_AUDIOIO_PLAYBACK,
|
|
|
|
wxCommandEventHandler(EffectUIHost::OnPlayback),
|
|
|
|
NULL,
|
|
|
|
this);
|
|
|
|
|
|
|
|
wxTheApp->Connect(EVT_AUDIOIO_CAPTURE,
|
|
|
|
wxCommandEventHandler(EffectUIHost::OnCapture),
|
|
|
|
NULL,
|
|
|
|
this);
|
|
|
|
|
|
|
|
mInitialized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectUIHost::CleanupRealtime()
|
|
|
|
{
|
|
|
|
if (mSupportsRealtime && mInitialized)
|
|
|
|
{
|
|
|
|
wxTheApp->Disconnect(EVT_AUDIOIO_PLAYBACK,
|
|
|
|
wxCommandEventHandler(EffectUIHost::OnPlayback),
|
|
|
|
NULL,
|
|
|
|
this);
|
|
|
|
|
|
|
|
wxTheApp->Disconnect(EVT_AUDIOIO_CAPTURE,
|
|
|
|
wxCommandEventHandler(EffectUIHost::OnCapture),
|
|
|
|
NULL,
|
|
|
|
this);
|
|
|
|
|
|
|
|
EffectManager::Get().RealtimeRemoveEffect(mEffect);
|
|
|
|
|
|
|
|
mInitialized = false;
|
|
|
|
}
|
2015-04-26 21:41:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// EffectPresetsDialog
|
|
|
|
//
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
ID_Type = 10000
|
|
|
|
};
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(EffectPresetsDialog, wxDialog)
|
|
|
|
EVT_CHOICE(ID_Type, EffectPresetsDialog::OnType)
|
|
|
|
EVT_LISTBOX_DCLICK(wxID_ANY, EffectPresetsDialog::OnOk)
|
|
|
|
EVT_BUTTON(wxID_OK, EffectPresetsDialog::OnOk)
|
|
|
|
EVT_BUTTON(wxID_CANCEL, EffectPresetsDialog::OnCancel)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
EffectPresetsDialog::EffectPresetsDialog(wxWindow *parent, Effect *effect)
|
|
|
|
: wxDialog(parent, wxID_ANY, wxString(_("Select Preset")))
|
|
|
|
{
|
|
|
|
ShuttleGui S(this, eIsCreating);
|
|
|
|
S.StartVerticalLay();
|
|
|
|
{
|
|
|
|
S.StartTwoColumn();
|
|
|
|
S.SetStretchyCol(1);
|
|
|
|
{
|
|
|
|
wxArrayString empty;
|
|
|
|
|
|
|
|
S.AddPrompt(_("Type:"));
|
|
|
|
mType = S.Id(ID_Type).AddChoice(wxT(""), wxT(""), &empty);
|
|
|
|
mType->SetSelection(0);
|
|
|
|
|
|
|
|
S.AddPrompt(_("&Preset:"));
|
|
|
|
mPresets = S.AddListBox(&empty, wxLB_SINGLE | wxLB_NEEDED_SB );
|
|
|
|
}
|
|
|
|
S.EndTwoColumn();
|
|
|
|
|
|
|
|
S.AddStandardButtons();
|
|
|
|
}
|
|
|
|
S.EndVerticalLay();
|
|
|
|
|
|
|
|
mUserPresets = effect->GetUserPresets();
|
|
|
|
mFactoryPresets = effect->GetFactoryPresets();
|
|
|
|
|
|
|
|
if (mUserPresets.GetCount() > 0)
|
|
|
|
{
|
|
|
|
mType->Append(_("User Presets"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mFactoryPresets.GetCount() > 0)
|
|
|
|
{
|
|
|
|
mType->Append(_("Factory Presets"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (effect->HasCurrentSettings())
|
|
|
|
{
|
|
|
|
mType->Append(_("Current Settings"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (effect->HasFactoryDefaults())
|
|
|
|
{
|
|
|
|
mType->Append(_("Factory Defaults"));
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
EffectPresetsDialog::~EffectPresetsDialog()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-04-27 10:02:56 +00:00
|
|
|
wxString EffectPresetsDialog::GetSelected() const
|
|
|
|
{
|
|
|
|
return mSelection;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectPresetsDialog::SetSelected(const wxString & parms)
|
|
|
|
{
|
|
|
|
wxString preset = parms;
|
|
|
|
if (preset.StartsWith(Effect::kUserPresetIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(Effect::kUserPresetIdent, wxEmptyString, false);
|
|
|
|
SetPrefix(_("User Presets"), preset);
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(Effect::kFactoryPresetIdent))
|
|
|
|
{
|
|
|
|
preset.Replace(Effect::kFactoryPresetIdent, wxEmptyString, false);
|
|
|
|
SetPrefix(_("Factory Presets"), preset);
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(Effect::kCurrentSettingsIdent))
|
|
|
|
{
|
|
|
|
SetPrefix(_("Current Settings"), wxEmptyString);
|
|
|
|
}
|
|
|
|
else if (preset.StartsWith(Effect::kFactoryDefaultsIdent))
|
|
|
|
{
|
|
|
|
SetPrefix(_("Factory Defaults"), wxEmptyString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectPresetsDialog::SetPrefix(const wxString & type, const wxString & prefix)
|
|
|
|
{
|
|
|
|
mType->SetStringSelection(type);
|
|
|
|
|
|
|
|
if (type.IsSameAs(_("User Presets")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Append(mUserPresets);
|
|
|
|
mPresets->Enable(true);
|
|
|
|
mPresets->SetStringSelection(prefix);
|
|
|
|
if (mPresets->GetSelection() == wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
mPresets->SetSelection(0);
|
|
|
|
}
|
|
|
|
mSelection = Effect::kUserPresetIdent + mPresets->GetStringSelection();
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Factory Presets")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
for (size_t i = 0, cnt = mFactoryPresets.GetCount(); i < cnt; i++)
|
|
|
|
{
|
|
|
|
wxString label = mFactoryPresets[i];
|
|
|
|
if (label.IsEmpty())
|
|
|
|
{
|
|
|
|
label = _("None");
|
|
|
|
}
|
|
|
|
mPresets->Append(label);
|
|
|
|
}
|
|
|
|
mPresets->Enable(true);
|
|
|
|
mPresets->SetStringSelection(prefix);
|
|
|
|
if (mPresets->GetSelection() == wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
mPresets->SetSelection(0);
|
|
|
|
}
|
|
|
|
mSelection = Effect::kFactoryPresetIdent + mPresets->GetStringSelection();
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Current Settings")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Enable(false);
|
|
|
|
mSelection = Effect::kCurrentSettingsIdent;
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Factory Defaults")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Enable(false);
|
|
|
|
mSelection = Effect::kFactoryDefaultsIdent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-26 21:41:05 +00:00
|
|
|
void EffectPresetsDialog::UpdateUI()
|
|
|
|
{
|
|
|
|
int selected = mType->GetSelection();
|
|
|
|
if (selected == wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
selected = 0;
|
|
|
|
mType->SetSelection(selected);
|
|
|
|
}
|
|
|
|
wxString type = mType->GetString(selected);
|
|
|
|
|
|
|
|
if (type.IsSameAs(_("User Presets")))
|
|
|
|
{
|
|
|
|
selected = mPresets->GetSelection();
|
|
|
|
if (selected == wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
selected = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Append(mUserPresets);
|
|
|
|
mPresets->Enable(true);
|
|
|
|
mPresets->SetSelection(selected);
|
|
|
|
mSelection = Effect::kUserPresetIdent + mPresets->GetString(selected);
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Factory Presets")))
|
|
|
|
{
|
|
|
|
selected = mPresets->GetSelection();
|
|
|
|
if (selected == wxNOT_FOUND)
|
|
|
|
{
|
|
|
|
selected = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPresets->Clear();
|
|
|
|
for (size_t i = 0, cnt = mFactoryPresets.GetCount(); i < cnt; i++)
|
|
|
|
{
|
|
|
|
wxString label = mFactoryPresets[i];
|
|
|
|
if (label.IsEmpty())
|
|
|
|
{
|
|
|
|
label = _("None");
|
|
|
|
}
|
|
|
|
mPresets->Append(label);
|
|
|
|
}
|
|
|
|
mPresets->Enable(true);
|
|
|
|
mPresets->SetSelection(selected);
|
|
|
|
mSelection = Effect::kFactoryPresetIdent + mPresets->GetString(selected);
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Current Settings")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Enable(false);
|
|
|
|
mSelection = Effect::kCurrentSettingsIdent;
|
|
|
|
}
|
|
|
|
else if (type.IsSameAs(_("Factory Defaults")))
|
|
|
|
{
|
|
|
|
mPresets->Clear();
|
|
|
|
mPresets->Enable(false);
|
|
|
|
mSelection = Effect::kFactoryDefaultsIdent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectPresetsDialog::OnType(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
UpdateUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectPresetsDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
UpdateUI();
|
|
|
|
|
|
|
|
EndModal(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectPresetsDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
|
|
|
|
{
|
|
|
|
mSelection = wxEmptyString;
|
|
|
|
|
|
|
|
EndModal(false);
|
|
|
|
}
|