mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
More effect changes to new format and realtime preview
Main effect host processing extended to support generate effects and sync locked tracks. Ladspa updated to utilize new generate support. I'll address Analyze plugins when I get to the SBSMS ones. Shared and private config changes are flushed immediately. Cancel button restored to VST and Ladspa dialogs. This also restores the ESC button functionality. Current parameters saved with Apply or Ok clicked...not when Audacity ends. Ladspa and VST effects with that reports no input and no outputs are now ignored. Ladspa effects providing a latency value is now handled. Ladspa generator effects now use the TimeTextCtrl for specifying duration.
This commit is contained in:
parent
ed1338cdec
commit
7bb4b7c941
@ -86,9 +86,9 @@ class EffectHostInterface : public EffectIdentInterface,
|
||||
public:
|
||||
virtual ~EffectHostInterface() {};
|
||||
|
||||
// Both of these are pretty much hacks until everything has been converted and
|
||||
// it's decided if the client will display the interface or if that'll be done
|
||||
// by the host.
|
||||
virtual double GetDuration() = 0;
|
||||
virtual bool SetDuration(double seconds) = 0;
|
||||
|
||||
virtual bool Apply() = 0;
|
||||
virtual void Preview() = 0;
|
||||
};
|
||||
|
@ -2006,7 +2006,6 @@ PluginDescriptor & PluginManager::CreatePlugin(IdentInterface *ident, PluginType
|
||||
|
||||
// This will either create a new entry or replace an existing entry
|
||||
mPlugins[plug.GetID()] = plug;
|
||||
PluginDescriptor &p = mPlugins[plug.GetID()];
|
||||
return mPlugins[plug.GetID()];
|
||||
}
|
||||
|
||||
@ -2116,6 +2115,10 @@ bool PluginManager::SetConfig(const wxString & key, const wxString & value)
|
||||
{
|
||||
wxString wxval = value.c_str();
|
||||
result = mConfig->Write(key, wxval);
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2128,6 +2131,10 @@ bool PluginManager::SetConfig(const wxString & key, const int & value)
|
||||
if (mConfig && !key.empty())
|
||||
{
|
||||
result = mConfig->Write(key, value);
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2140,6 +2147,10 @@ bool PluginManager::SetConfig(const wxString & key, const bool & value)
|
||||
if (mConfig && !key.empty())
|
||||
{
|
||||
result = mConfig->Write(key, value);
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2152,6 +2163,10 @@ bool PluginManager::SetConfig(const wxString & key, const float & value)
|
||||
if (mConfig && !key.empty())
|
||||
{
|
||||
result = mConfig->Write(key, value);
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2164,6 +2179,10 @@ bool PluginManager::SetConfig(const wxString & key, const double & value)
|
||||
if (mConfig && !key.empty())
|
||||
{
|
||||
result = mConfig->Write(key, value);
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2176,6 +2195,10 @@ bool PluginManager::SetConfig(const wxString & key, const sampleCount & value)
|
||||
if (mConfig && !key.empty())
|
||||
{
|
||||
result = mConfig->Write(key, wxString::Format(wxT("%d"), (int) value));
|
||||
if (result)
|
||||
{
|
||||
result = mConfig->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -75,7 +75,7 @@ Effect::Effect()
|
||||
mTracks = NULL;
|
||||
mOutputTracks = NULL;
|
||||
mOutputTracksType = Track::None;
|
||||
mLength = 0;
|
||||
mDuration = 0.0;
|
||||
mNumTracks = 0;
|
||||
mNumGroups = 0;
|
||||
mProgress = NULL;
|
||||
@ -246,8 +246,33 @@ bool Effect::IsInteractive()
|
||||
|
||||
// EffectHostInterface implementation
|
||||
|
||||
double Effect::GetDuration()
|
||||
{
|
||||
if (mT1 > mT0)
|
||||
{
|
||||
return mT1 - mT0;
|
||||
}
|
||||
|
||||
if (mClient->GetType() == EffectTypeGenerate)
|
||||
{
|
||||
return sDefaultGenerateLen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Effect::SetDuration(double seconds)
|
||||
{
|
||||
mDuration = seconds;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Effect::Apply()
|
||||
{
|
||||
// This is absolute hackage...but easy
|
||||
//
|
||||
// It should callback to the EffectManager to kick off the processing
|
||||
GetActiveProject()->OnEffect(GetID(), true);
|
||||
|
||||
return true;
|
||||
@ -384,18 +409,20 @@ bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, cons
|
||||
|
||||
bool Effect::Startup(EffectClientInterface *client)
|
||||
{
|
||||
// Need to set host now so client startup can use our services
|
||||
client->SetHost(this);
|
||||
|
||||
// Bail if the client startup fails
|
||||
if (!client->Startup())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let destructor know we need to be shutdown
|
||||
mClient = client;
|
||||
|
||||
// Need to set host now so client startup can use our services
|
||||
mClient->SetHost(this);
|
||||
|
||||
// Bail if the client startup fails
|
||||
if (!mClient->Startup())
|
||||
{
|
||||
mClient = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
mNumAudioIn = mClient->GetAudioInCount();
|
||||
mNumAudioOut = mClient->GetAudioOutCount();
|
||||
|
||||
@ -416,6 +443,8 @@ bool Effect::Startup(EffectClientInterface *client)
|
||||
}
|
||||
|
||||
SetEffectFlags(flags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// All legacy effects should have this overridden
|
||||
@ -588,7 +617,9 @@ bool Effect::Process()
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyInputTracks();
|
||||
bool isGenerator = mClient->GetType() == EffectTypeGenerate;
|
||||
|
||||
CopyInputTracks(Track::All);
|
||||
bool bGoodResult = true;
|
||||
|
||||
mInBuffer = NULL;
|
||||
@ -601,15 +632,34 @@ bool Effect::Process()
|
||||
TrackListIterator iter(mOutputTracks);
|
||||
int count = 0;
|
||||
bool clear = false;
|
||||
WaveTrack *left = (WaveTrack *) iter.First();
|
||||
while (left)
|
||||
Track* t = iter.First();
|
||||
|
||||
for (t = iter.First(); t; t = iter.Next())
|
||||
{
|
||||
if (t->GetKind() != Track::Wave || !t->GetSelected())
|
||||
{
|
||||
if (t->IsSyncLockSelected())
|
||||
{
|
||||
t->SyncLockAdjust(mT1, mT0 + mDuration);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
WaveTrack *left = (WaveTrack *)t;
|
||||
WaveTrack *right;
|
||||
sampleCount len;
|
||||
sampleCount leftStart;
|
||||
sampleCount rightStart;
|
||||
|
||||
if (!isGenerator)
|
||||
{
|
||||
GetSamples(left, &leftStart, &len);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
leftStart = 0;
|
||||
}
|
||||
|
||||
mNumChannels = 1;
|
||||
|
||||
@ -618,7 +668,10 @@ bool Effect::Process()
|
||||
if (left->GetLinked() && mNumAudioIn > 1)
|
||||
{
|
||||
right = (WaveTrack *) iter.Next();
|
||||
if (!isGenerator)
|
||||
{
|
||||
GetSamples(right, &rightStart, &len);
|
||||
}
|
||||
clear = false;
|
||||
mNumChannels = 2;
|
||||
}
|
||||
@ -725,7 +778,6 @@ bool Effect::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
left = (WaveTrack *) iter.Next();
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -797,6 +849,24 @@ bool Effect::ProcessTrack(int count,
|
||||
sampleCount outputBufferCnt = 0;
|
||||
bool cleared = false;
|
||||
|
||||
WaveTrack *genLeft = NULL;
|
||||
WaveTrack *genRight = NULL;
|
||||
sampleCount genLength = 0;
|
||||
bool isGenerator = mClient->GetType() == EffectTypeGenerate;
|
||||
if (isGenerator)
|
||||
{
|
||||
genLength = left->GetRate() * mDuration;
|
||||
delayRemaining = genLength;
|
||||
cleared = true;
|
||||
|
||||
// Create temporary tracks
|
||||
genLeft = mFactory->NewWaveTrack(left->GetSampleFormat(), left->GetRate());
|
||||
if (right)
|
||||
{
|
||||
genRight = mFactory->NewWaveTrack(right->GetSampleFormat(), right->GetRate());
|
||||
}
|
||||
}
|
||||
|
||||
// Call the effect until we run out of input or delayed samples
|
||||
while (inputRemaining || delayRemaining)
|
||||
{
|
||||
@ -910,6 +980,8 @@ bool Effect::ProcessTrack(int count,
|
||||
}
|
||||
|
||||
// Get the current number of delayed samples and accumulate
|
||||
if (!isGenerator)
|
||||
{
|
||||
sampleCount delay = mClient->GetLatency();
|
||||
curDelay += delay;
|
||||
delayRemaining += delay;
|
||||
@ -933,6 +1005,7 @@ bool Effect::ProcessTrack(int count,
|
||||
}
|
||||
curDelay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
outputBufferCnt += curBlockSize;
|
||||
@ -948,6 +1021,8 @@ bool Effect::ProcessTrack(int count,
|
||||
}
|
||||
// Output buffers have filled
|
||||
else
|
||||
{
|
||||
if (!isGenerator)
|
||||
{
|
||||
// Write them out
|
||||
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
|
||||
@ -955,6 +1030,15 @@ bool Effect::ProcessTrack(int count,
|
||||
{
|
||||
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
|
||||
if (genRight)
|
||||
{
|
||||
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the output buffer positions
|
||||
for (int i = 0; i < mNumChannels; i++)
|
||||
@ -995,6 +1079,8 @@ bool Effect::ProcessTrack(int count,
|
||||
|
||||
// Put any remaining output
|
||||
if (outputBufferCnt)
|
||||
{
|
||||
if (!isGenerator)
|
||||
{
|
||||
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
|
||||
if (right)
|
||||
@ -1002,6 +1088,31 @@ bool Effect::ProcessTrack(int count,
|
||||
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
|
||||
if (genRight)
|
||||
{
|
||||
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isGenerator)
|
||||
{
|
||||
// Transfer the data from the temporary tracks to the actual ones
|
||||
genLeft->Flush();
|
||||
SetTimeWarper(new StepTimeWarper(mT0 + genLength, genLength - (mT1 - mT0)));
|
||||
left->ClearAndPaste(mT0, mT1, genLeft, true, true, GetTimeWarper());
|
||||
delete genLeft;
|
||||
|
||||
if (genRight)
|
||||
{
|
||||
genRight->Flush();
|
||||
right->ClearAndPaste(mT0, mT1, genRight, true, true, GetTimeWarper());
|
||||
delete genRight;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the plugin to cleanup
|
||||
mClient->ProcessFinalize();
|
||||
@ -1044,14 +1155,16 @@ void Effect::GetSamples(WaveTrack *track, sampleCount *start, sampleCount *len)
|
||||
double t0 = mT0 < trackStart ? trackStart : mT0;
|
||||
double t1 = mT1 > trackEnd ? trackEnd : mT1;
|
||||
|
||||
#if 0
|
||||
if (GetType() & INSERT_EFFECT) {
|
||||
t1 = t0 + mLength;
|
||||
t1 = t0 + mDuration;
|
||||
if (mT0 == mT1) {
|
||||
// Not really part of the calculation, but convenient to put here
|
||||
bool bResult = track->InsertSilence(t0, t1);
|
||||
wxASSERT(bResult); // TO DO: Actually handle this.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (t1 > t0) {
|
||||
*start = track->TimeToLongSamples(t0);
|
||||
|
@ -96,6 +96,9 @@ class AUDACITY_DLL_API Effect : public EffectHostInterface
|
||||
|
||||
// EffectHostInterface implementation
|
||||
|
||||
virtual double GetDuration();
|
||||
virtual bool SetDuration(double duration);
|
||||
|
||||
virtual bool Apply();
|
||||
virtual void Preview();
|
||||
|
||||
@ -351,7 +354,7 @@ class AUDACITY_DLL_API Effect : public EffectHostInterface
|
||||
protected:
|
||||
static double sDefaultGenerateLen;
|
||||
int mFlags;
|
||||
double mLength;
|
||||
double mDuration;
|
||||
|
||||
// type of the tracks on mOutputTracks
|
||||
int mOutputTracksType;
|
||||
|
@ -764,14 +764,10 @@ private:
|
||||
|
||||
void OnSlider(wxCommandEvent & evt);
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
void OnApply(wxCommandEvent & evt);
|
||||
#else
|
||||
void OnOk(wxCommandEvent & evt);
|
||||
void OnCancel(wxCommandEvent & evt);
|
||||
void OnPreview(wxCommandEvent & evt);
|
||||
#endif
|
||||
|
||||
void OnDefaults(wxCommandEvent & evt);
|
||||
void OnClose(wxCloseEvent & evt);
|
||||
|
||||
@ -858,14 +854,10 @@ enum
|
||||
BEGIN_EVENT_TABLE(VSTEffectDialog, wxDialog)
|
||||
EVT_CLOSE(VSTEffectDialog::OnClose)
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
EVT_BUTTON(wxID_APPLY, VSTEffectDialog::OnApply)
|
||||
#else
|
||||
EVT_BUTTON(wxID_OK, VSTEffectDialog::OnOk)
|
||||
EVT_BUTTON(wxID_CANCEL, VSTEffectDialog::OnCancel)
|
||||
EVT_BUTTON(ID_EFFECT_PREVIEW, VSTEffectDialog::OnPreview)
|
||||
#endif
|
||||
|
||||
EVT_BUTTON(ePreviewID, VSTEffectDialog::OnPreview)
|
||||
EVT_BUTTON(eDefaultsID, VSTEffectDialog::OnDefaults)
|
||||
|
||||
EVT_COMBOBOX(ID_VST_PROGRAM, VSTEffectDialog::OnProgram)
|
||||
@ -1511,7 +1503,7 @@ void VSTEffectDialog::BuildFancy()
|
||||
|
||||
// Add the standard button bar at the bottom
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
vs->Add(CreateStdButtonSizer(this, eApplyButton | eDefaultsButton), 0, wxEXPAND);
|
||||
vs->Add(CreateStdButtonSizer(this, eApplyButton | eCancelButton | eDefaultsButton), 0, wxEXPAND);
|
||||
#else
|
||||
vs->Add(CreateStdButtonSizer(this, ePreviewButton | eDefaultsButton |eCancelButton | eOkButton), 0, wxEXPAND);
|
||||
#endif
|
||||
@ -1561,11 +1553,14 @@ void VSTEffectDialog::BuildPlain()
|
||||
vSizer->Add(sw, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
// Add the standard button bar at the bottom
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
vSizer->Add(CreateStdButtonSizer(this, eApplyButton | eDefaultsButton), 0, wxEXPAND);
|
||||
#else
|
||||
vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eDefaultsButton|eCancelButton|eOkButton), 0, wxEXPAND);
|
||||
#endif
|
||||
if (mEffect->IsRealtimeCapable())
|
||||
{
|
||||
vSizer->Add(CreateStdButtonSizer(this, eDefaultsButton | eCancelButton | eApplyButton), 0, wxEXPAND);
|
||||
}
|
||||
else
|
||||
{
|
||||
vSizer->Add(CreateStdButtonSizer(this, ePreviewButton | eDefaultsButton | eCancelButton | eOkButton), 0, wxEXPAND);
|
||||
}
|
||||
|
||||
SetSizer(vSizer);
|
||||
|
||||
@ -2586,7 +2581,6 @@ void VSTEffectDialog::OnClose(wxCloseEvent & evt)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
void VSTEffectDialog::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
#if defined(__WXMAC__)
|
||||
@ -2595,9 +2589,11 @@ void VSTEffectDialog::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
Show(false);
|
||||
#endif
|
||||
|
||||
mEffect->SaveParameters(wxT("Current"));
|
||||
|
||||
mEffect->mHost->Apply();
|
||||
}
|
||||
#else
|
||||
|
||||
void VSTEffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
mEffect->mHost->Preview();
|
||||
@ -2611,6 +2607,8 @@ void VSTEffectDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
|
||||
Show(false);
|
||||
#endif
|
||||
|
||||
mEffect->SaveParameters(wxT("Current"));
|
||||
|
||||
if (mGui)
|
||||
{
|
||||
// mEffect->PowerOff();
|
||||
@ -2636,9 +2634,11 @@ void VSTEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
|
||||
// mEffect->callDispatcher(effEditClose, 0, 0, NULL, 0.0);
|
||||
}
|
||||
|
||||
if (IsModal())
|
||||
{
|
||||
EndModal(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void VSTEffectDialog::OnDefaults(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
@ -3229,6 +3229,11 @@ wxString VSTEffect::GetDescription()
|
||||
|
||||
EffectType VSTEffect::GetType()
|
||||
{
|
||||
if (mAudioIns == 0 && mAudioOuts == 0 && mMidiIns == 0 && mMidiOuts == 0)
|
||||
{
|
||||
return EffectTypeNone;
|
||||
}
|
||||
|
||||
if (mAudioIns == 0 && mMidiIns == 0)
|
||||
{
|
||||
return EffectTypeGenerate;
|
||||
|
@ -141,7 +141,7 @@ void LadspaEffectsModule::Terminate()
|
||||
return;
|
||||
}
|
||||
|
||||
bool LadspaEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
|
||||
bool LadspaEffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -310,7 +310,7 @@ bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm, const wxSt
|
||||
int index = 0;
|
||||
LADSPA_Descriptor_Function mainFn = NULL;
|
||||
wxDynamicLibrary lib;
|
||||
if (lib.Load(path, wxDL_LAZY)) {
|
||||
if (lib.Load(path, wxDL_NOW)) {
|
||||
wxLogNull logNo;
|
||||
|
||||
mainFn = (LADSPA_Descriptor_Function) lib.GetSymbol(wxT("ladspa_descriptor"));
|
||||
@ -369,12 +369,15 @@ LadspaEffect::LadspaEffect(const wxString & path, int index)
|
||||
mAudioIns = 0;
|
||||
mAudioOuts = 0;
|
||||
mNumInputControls = 0;
|
||||
mSampleRate = 44100;
|
||||
|
||||
mInputPorts = NULL;
|
||||
mOutputPorts = NULL;
|
||||
mInputControls = NULL;
|
||||
mOutputControls = NULL;
|
||||
|
||||
mLatencyPort = -1;
|
||||
|
||||
mDlg = NULL;
|
||||
}
|
||||
|
||||
@ -442,6 +445,11 @@ wxString LadspaEffect::GetDescription()
|
||||
//
|
||||
EffectType LadspaEffect::GetType()
|
||||
{
|
||||
if (mAudioIns == 0 && mAudioOuts == 0)
|
||||
{
|
||||
return EffectTypeNone;
|
||||
}
|
||||
|
||||
if (mAudioIns == 0)
|
||||
{
|
||||
return EffectTypeGenerate;
|
||||
@ -477,7 +485,7 @@ bool LadspaEffect::IsLegacy()
|
||||
|
||||
bool LadspaEffect::IsRealtimeCapable()
|
||||
{
|
||||
return true;
|
||||
return GetType() == EffectTypeProcess;
|
||||
}
|
||||
|
||||
//
|
||||
@ -503,6 +511,7 @@ bool LadspaEffect::Startup()
|
||||
for (unsigned long p = 0; p < mData->PortCount; p++)
|
||||
{
|
||||
LADSPA_PortDescriptor d = mData->PortDescriptors[p];
|
||||
// Collect the audio ports
|
||||
if (LADSPA_IS_PORT_AUDIO(d))
|
||||
{
|
||||
if (LADSPA_IS_PORT_INPUT(d))
|
||||
@ -514,8 +523,8 @@ bool LadspaEffect::Startup()
|
||||
mOutputPorts[mAudioOuts++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d))
|
||||
// Determine the port's default value
|
||||
else if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d))
|
||||
{
|
||||
mInteractive = true;
|
||||
|
||||
@ -585,6 +594,16 @@ bool LadspaEffect::Startup()
|
||||
mNumInputControls++;
|
||||
mInputControls[p] = val;
|
||||
}
|
||||
// Ladspa effects have a convention of providing latency on an output
|
||||
// control port whose name is "latency".
|
||||
else if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_OUTPUT(d))
|
||||
{
|
||||
if (strcmp(mData->PortNames[p], "latency") == 0)
|
||||
{
|
||||
mLatencyPort = p;
|
||||
mOutputControls[p] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mHost will be null during registration
|
||||
@ -609,12 +628,6 @@ bool LadspaEffect::Startup()
|
||||
|
||||
bool LadspaEffect::Shutdown()
|
||||
{
|
||||
// mHost will be null during registration
|
||||
if (mHost)
|
||||
{
|
||||
SaveParameters(wxT("Current"));
|
||||
}
|
||||
|
||||
if (mInputPorts)
|
||||
{
|
||||
delete [] mInputPorts;
|
||||
@ -686,8 +699,12 @@ sampleCount LadspaEffect::GetBlockSize(sampleCount maxBlockSize)
|
||||
|
||||
sampleCount LadspaEffect::GetLatency()
|
||||
{
|
||||
// Ladspa effects have a convention of providing latency on an output
|
||||
// control port name "latency".
|
||||
if (mLatencyPort >= 0 && !mLatencyDone)
|
||||
{
|
||||
mLatencyDone = true;
|
||||
return mOutputControls[mLatencyPort] * 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -707,9 +724,15 @@ bool LadspaEffect::ProcessInitialize()
|
||||
if (!mReady)
|
||||
{
|
||||
mMaster = InitInstance(mSampleRate);
|
||||
if (!mMaster)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mReady = true;
|
||||
}
|
||||
|
||||
mLatencyDone = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -797,6 +820,11 @@ sampleCount LadspaEffect::RealtimeProcess(int group,
|
||||
bool LadspaEffect::RealtimeAddProcessor(int numChannels, float sampleRate)
|
||||
{
|
||||
LADSPA_Handle slave = InitInstance(sampleRate);
|
||||
if (!slave)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mSlaves.Add(slave);
|
||||
mSlaveChannels.Add(numChannels);
|
||||
|
||||
@ -809,7 +837,12 @@ bool LadspaEffect::ShowInterface(void *parent)
|
||||
return false;
|
||||
}
|
||||
|
||||
double length = 0; //mT1 > mT0 ? mT1 - mT0 : sDefaultGenerateLen;
|
||||
double length = 0;
|
||||
|
||||
if (!IsRealtimeCapable())
|
||||
{
|
||||
length = mHost->GetDuration();
|
||||
}
|
||||
|
||||
if (!mDlg)
|
||||
{
|
||||
@ -817,18 +850,23 @@ bool LadspaEffect::ShowInterface(void *parent)
|
||||
mDlg->CentreOnParent();
|
||||
}
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
if (IsRealtimeCapable())
|
||||
{
|
||||
mDlg->Show(!mDlg->IsShown());
|
||||
|
||||
return true;
|
||||
#else
|
||||
}
|
||||
|
||||
mDlg->ShowModal();
|
||||
bool ret = mDlg->GetReturnCode() != 0;
|
||||
if (ret)
|
||||
{
|
||||
mHost->SetDuration(mDlg->GetLength());
|
||||
}
|
||||
mDlg->Destroy();
|
||||
mDlg = NULL;
|
||||
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@ -842,7 +880,7 @@ bool LadspaEffect::Load()
|
||||
}
|
||||
|
||||
LADSPA_Descriptor_Function mainFn = NULL;
|
||||
if (mLib.Load(mPath, wxDL_LAZY))
|
||||
if (mLib.Load(mPath, wxDL_NOW))
|
||||
{
|
||||
wxLogNull logNo;
|
||||
|
||||
@ -908,6 +946,10 @@ LADSPA_Handle LadspaEffect::InitInstance(float sampleRate)
|
||||
{
|
||||
/* Instantiate the plugin */
|
||||
LADSPA_Handle handle = mData->instantiate(mData, sampleRate);
|
||||
if (!handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned long p = 0; p < mData->PortCount; p++)
|
||||
{
|
||||
@ -958,14 +1000,14 @@ class Slider:public wxSlider
|
||||
{
|
||||
};
|
||||
|
||||
void OnSetFocus(wxFocusEvent &event)
|
||||
void OnSetFocus(wxFocusEvent & evt)
|
||||
{
|
||||
wxScrolledWindow *p = (wxScrolledWindow *) GetParent();
|
||||
wxRect r = GetRect();
|
||||
wxRect rv = p->GetRect();
|
||||
rv.y = 0;
|
||||
|
||||
event.Skip();
|
||||
evt.Skip();
|
||||
|
||||
int y;
|
||||
int yppu;
|
||||
@ -1008,14 +1050,14 @@ class TextCtrl:public wxTextCtrl
|
||||
{
|
||||
};
|
||||
|
||||
void OnSetFocus(wxFocusEvent &event)
|
||||
void OnSetFocus(wxFocusEvent & evt)
|
||||
{
|
||||
wxScrolledWindow *p = (wxScrolledWindow *) GetParent();
|
||||
wxRect r = GetRect();
|
||||
wxRect rv = p->GetRect();
|
||||
rv.y = 0;
|
||||
|
||||
event.Skip();
|
||||
evt.Skip();
|
||||
|
||||
int y;
|
||||
int yppu;
|
||||
@ -1047,13 +1089,11 @@ END_EVENT_TABLE()
|
||||
const int LADSPA_SECONDS_ID = 13101;
|
||||
|
||||
BEGIN_EVENT_TABLE(LadspaEffectDialog, wxDialog)
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
EVT_BUTTON(wxID_APPLY, LadspaEffectDialog::OnApply)
|
||||
#else
|
||||
EVT_BUTTON(wxID_OK, LadspaEffectDialog::OnOK)
|
||||
EVT_BUTTON(wxID_CANCEL, LadspaEffectDialog::OnCancel)
|
||||
EVT_BUTTON(ID_EFFECT_PREVIEW, LadspaEffectDialog::OnPreview)
|
||||
#endif
|
||||
EVT_BUTTON(ePreviewID, LadspaEffectDialog::OnPreview)
|
||||
EVT_BUTTON(eDefaultsID, LadspaEffectDialog::OnDefaults)
|
||||
EVT_SLIDER(wxID_ANY, LadspaEffectDialog::OnSlider)
|
||||
EVT_TEXT(wxID_ANY, LadspaEffectDialog::OnTextCtrl)
|
||||
EVT_CHECKBOX(wxID_ANY, LadspaEffectDialog::OnCheckBox)
|
||||
@ -1070,17 +1110,16 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
:wxDialog(parent, -1, LAT1CTOWX(data->Name),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||
effect(eff)
|
||||
mEffect(eff)
|
||||
{
|
||||
mLength = length;
|
||||
numParams = 0;
|
||||
mNumParams = 0;
|
||||
mData = data;
|
||||
mInputControls = inputControls;
|
||||
sampleRate = sampleRate;
|
||||
mSampleRate = sampleRate;
|
||||
#ifdef __WXMSW__
|
||||
// On Windows, for some reason, wxWidgets calls OnTextCtrl during creation
|
||||
// of the text control, and LadspaEffectDialog::OnTextCtrl calls HandleText,
|
||||
// which assumes all the fields have been initialized.
|
||||
// which assumes all the mFields have been initialized.
|
||||
// This can give us a bad pointer crash, so manipulate inSlider to
|
||||
// no-op HandleText during creation.
|
||||
inSlider = true;
|
||||
@ -1089,19 +1128,19 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
#endif
|
||||
inText = false;
|
||||
|
||||
toggles = new wxCheckBox*[mData->PortCount];
|
||||
sliders = new wxSlider*[mData->PortCount];
|
||||
fields = new wxTextCtrl*[mData->PortCount];
|
||||
labels = new wxStaticText*[mData->PortCount];
|
||||
ports = new unsigned long [mData->PortCount];
|
||||
mToggles = new wxCheckBox*[mData->PortCount];
|
||||
mSliders = new wxSlider*[mData->PortCount];
|
||||
mFields = new wxTextCtrl*[mData->PortCount];
|
||||
mLabels = new wxStaticText*[mData->PortCount];
|
||||
mPorts = new unsigned long [mData->PortCount];
|
||||
|
||||
unsigned long p;
|
||||
for(p=0; p<mData->PortCount; p++) {
|
||||
LADSPA_PortDescriptor d = mData->PortDescriptors[p];
|
||||
if (LADSPA_IS_PORT_CONTROL(d) &&
|
||||
LADSPA_IS_PORT_INPUT(d)) {
|
||||
ports[numParams] = p;
|
||||
numParams++;
|
||||
mPorts[mNumParams] = p;
|
||||
mNumParams++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1141,11 +1180,12 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
vSizer->Add(w, 1, wxEXPAND|wxALL, 5);
|
||||
|
||||
// Preview, OK, & Cancel buttons
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
vSizer->Add(CreateStdButtonSizer(this, eApplyButton | eDefaultsButton), 0, wxEXPAND);
|
||||
#else
|
||||
vSizer->Add(CreateStdButtonSizer(this, ePreviewButton | eDefaultsButton |eCancelButton | eOkButton), 0, wxEXPAND);
|
||||
#endif
|
||||
if (mEffect->IsRealtimeCapable()) {
|
||||
vSizer->Add(CreateStdButtonSizer(this, eApplyButton | eCancelButton | eDefaultsButton), 0, wxEXPAND);
|
||||
}
|
||||
else {
|
||||
vSizer->Add(CreateStdButtonSizer(this, ePreviewButton | eDefaultsButton | eCancelButton | eOkButton), 0, wxEXPAND);
|
||||
}
|
||||
|
||||
SetSizer(vSizer);
|
||||
|
||||
@ -1156,36 +1196,26 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
new wxFlexGridSizer(5, 0, 0);
|
||||
gridSizer->AddGrowableCol(3);
|
||||
|
||||
for (p = 0; p < numParams; p++) {
|
||||
wxString labelText = LAT1CTOWX(mData->PortNames[ports[p]]);
|
||||
for (p = 0; p < mNumParams; p++) {
|
||||
wxString labelText = LAT1CTOWX(mData->PortNames[mPorts[p]]);
|
||||
item = new wxStaticText(w, 0, labelText + wxT(":"));
|
||||
gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
|
||||
|
||||
wxString fieldText;
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]];
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[mPorts[p]];
|
||||
|
||||
if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) {
|
||||
toggles[p] = new wxCheckBox(w, p, wxT(""));
|
||||
toggles[p]->SetName(labelText);
|
||||
toggles[p]->SetValue(mInputControls[ports[p]] > 0);
|
||||
gridSizer->Add(toggles[p], 0, wxALL, 5);
|
||||
ConnectFocus(toggles[p]);
|
||||
mToggles[p] = new wxCheckBox(w, p, wxT(""));
|
||||
mToggles[p]->SetName(labelText);
|
||||
mToggles[p]->SetValue(mInputControls[mPorts[p]] > 0);
|
||||
gridSizer->Add(mToggles[p], 0, wxALL, 5);
|
||||
ConnectFocus(mToggles[p]);
|
||||
|
||||
gridSizer->Add(1, 1, 0);
|
||||
gridSizer->Add(1, 1, 0);
|
||||
gridSizer->Add(1, 1, 0);
|
||||
}
|
||||
else {
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor))
|
||||
fieldText.Printf(wxT("%d"), (int)(mInputControls[ports[p]] + 0.5));
|
||||
else
|
||||
fieldText = Internat::ToDisplayString(mInputControls[ports[p]]);
|
||||
|
||||
fields[p] = new wxTextCtrl(w, p, fieldText);
|
||||
fields[p]->SetName(labelText);
|
||||
gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
ConnectFocus(fields[p]);
|
||||
|
||||
wxString bound;
|
||||
double lower = 0.0;
|
||||
double upper = 0.0;
|
||||
@ -1202,11 +1232,21 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
hashi = true;
|
||||
}
|
||||
if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) {
|
||||
lower *= sampleRate * 1000;
|
||||
upper *= sampleRate;
|
||||
lower *= mSampleRate;
|
||||
upper *= mSampleRate;
|
||||
forceint = true;
|
||||
}
|
||||
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint)
|
||||
fieldText.Printf(wxT("%d"), (int)(mInputControls[mPorts[p]] + 0.5));
|
||||
else
|
||||
fieldText = Internat::ToDisplayString(mInputControls[mPorts[p]]);
|
||||
|
||||
mFields[p] = new wxTextCtrl(w, p, fieldText);
|
||||
mFields[p]->SetName(labelText);
|
||||
gridSizer->Add(mFields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
ConnectFocus(mFields[p]);
|
||||
|
||||
wxString str;
|
||||
if (haslo) {
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint)
|
||||
@ -1220,14 +1260,14 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
gridSizer->Add(1, 1, 0);
|
||||
}
|
||||
|
||||
sliders[p] =
|
||||
mSliders[p] =
|
||||
new wxSlider(w, p,
|
||||
0, 0, 1000,
|
||||
wxDefaultPosition,
|
||||
wxSize(200, -1));
|
||||
sliders[p]->SetName(labelText);
|
||||
gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5);
|
||||
ConnectFocus(sliders[p]);
|
||||
mSliders[p]->SetName(labelText);
|
||||
gridSizer->Add(mSliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5);
|
||||
ConnectFocus(mSliders[p]);
|
||||
|
||||
if (hashi) {
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint)
|
||||
@ -1244,11 +1284,19 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
}
|
||||
|
||||
// Now add the length control
|
||||
if (effect->GetType() == EffectTypeGenerate) {
|
||||
item = new wxStaticText(w, 0, _("Length (seconds)"));
|
||||
gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
mSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length));
|
||||
mSeconds->SetName(_("Length (seconds)"));
|
||||
if (mEffect->GetType() == EffectTypeGenerate) {
|
||||
item = new wxStaticText(w, 0, _("Length (seconds):"));
|
||||
gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
|
||||
mSeconds = new TimeTextCtrl(w,
|
||||
wxID_ANY,
|
||||
_("hh:mm:ss + milliseconds"),
|
||||
length,
|
||||
mSampleRate,
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
true);
|
||||
mSeconds->SetName(_("Duration"));
|
||||
mSeconds->EnableMenu();
|
||||
gridSizer->Add(mSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
gridSizer->Add(1, 1, 0);
|
||||
gridSizer->Add(1, 1, 0);
|
||||
@ -1256,10 +1304,11 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
ConnectFocus(mSeconds);
|
||||
}
|
||||
|
||||
// Set all of the sliders based on the value in the
|
||||
// text fields
|
||||
// Set all of the mSliders based on the value in the
|
||||
// text mFields
|
||||
inSlider = false; // Now we're ready for HandleText to actually do something.
|
||||
HandleText();
|
||||
mEffect->LoadParameters(wxT("Current"));
|
||||
// HandleText();
|
||||
|
||||
paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5);
|
||||
w->SetSizer(paramSizer);
|
||||
@ -1271,23 +1320,23 @@ LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff,
|
||||
|
||||
LadspaEffectDialog::~LadspaEffectDialog()
|
||||
{
|
||||
delete[]toggles;
|
||||
delete[]sliders;
|
||||
delete[]fields;
|
||||
delete[]labels;
|
||||
delete[]ports;
|
||||
delete[]mToggles;
|
||||
delete[]mSliders;
|
||||
delete[]mFields;
|
||||
delete[]mLabels;
|
||||
delete[]mPorts;
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnCheckBox(wxCommandEvent &event)
|
||||
void LadspaEffectDialog::OnCheckBox(wxCommandEvent & evt)
|
||||
{
|
||||
int p = event.GetId();
|
||||
int p = evt.GetId();
|
||||
|
||||
mInputControls[ports[p]] = toggles[p]->GetValue();
|
||||
mInputControls[mPorts[p]] = mToggles[p]->GetValue();
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnSlider(wxCommandEvent &event)
|
||||
void LadspaEffectDialog::OnSlider(wxCommandEvent & evt)
|
||||
{
|
||||
int p = event.GetId();
|
||||
int p = evt.GetId();
|
||||
|
||||
// if we don't add the following three lines, changing
|
||||
// the value of the slider will change the text, which
|
||||
@ -1303,20 +1352,20 @@ void LadspaEffectDialog::OnSlider(wxCommandEvent &event)
|
||||
float range;
|
||||
bool forceint = false;
|
||||
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]];
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[mPorts[p]];
|
||||
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor))
|
||||
lower = hint.LowerBound;
|
||||
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor))
|
||||
upper = hint.UpperBound;
|
||||
if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) {
|
||||
lower *= sampleRate;
|
||||
upper *= sampleRate;
|
||||
lower *= mSampleRate;
|
||||
upper *= mSampleRate;
|
||||
forceint = true;
|
||||
}
|
||||
|
||||
range = upper - lower;
|
||||
|
||||
val = (sliders[p]->GetValue() / 1000.0) * range + lower;
|
||||
val = (mSliders[p]->GetValue() / 1000.0) * range + lower;
|
||||
|
||||
wxString str;
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint)
|
||||
@ -1324,14 +1373,14 @@ void LadspaEffectDialog::OnSlider(wxCommandEvent &event)
|
||||
else
|
||||
str = Internat::ToDisplayString(val);
|
||||
|
||||
fields[p]->SetValue(str);
|
||||
mFields[p]->SetValue(str);
|
||||
|
||||
mInputControls[ports[p]] = val;
|
||||
mInputControls[mPorts[p]] = val;
|
||||
|
||||
inSlider = false;
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnTextCtrl(wxCommandEvent & WXUNUSED(event))
|
||||
void LadspaEffectDialog::OnTextCtrl(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
HandleText();
|
||||
}
|
||||
@ -1346,19 +1395,19 @@ void LadspaEffectDialog::HandleText()
|
||||
if (inSlider)
|
||||
return;
|
||||
inText = true;
|
||||
for (unsigned long p = 0; p < numParams; p++) {
|
||||
for (unsigned long p = 0; p < mNumParams; p++) {
|
||||
double dval;
|
||||
float val;
|
||||
float lower = float(0.0);
|
||||
float upper = float(10.0);
|
||||
float range;
|
||||
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]];
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[mPorts[p]];
|
||||
if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dval = Internat::CompatibleToDouble(fields[p]->GetValue());
|
||||
dval = Internat::CompatibleToDouble(mFields[p]->GetValue());
|
||||
val = dval;
|
||||
|
||||
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor))
|
||||
@ -1366,8 +1415,8 @@ void LadspaEffectDialog::HandleText()
|
||||
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor))
|
||||
upper = hint.UpperBound;
|
||||
if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) {
|
||||
lower *= sampleRate;
|
||||
upper *= sampleRate;
|
||||
lower *= mSampleRate;
|
||||
upper *= mSampleRate;
|
||||
}
|
||||
range = upper - lower;
|
||||
|
||||
@ -1376,15 +1425,14 @@ void LadspaEffectDialog::HandleText()
|
||||
if (val > upper)
|
||||
val = upper;
|
||||
|
||||
mInputControls[ports[p]] = val;
|
||||
mInputControls[mPorts[p]] = val;
|
||||
|
||||
sliders[p]->SetValue((int)(((val-lower)/range) * 1000.0 + 0.5));
|
||||
mSliders[p]->SetValue((int)(((val-lower)/range) * 1000.0 + 0.5));
|
||||
}
|
||||
|
||||
inText = false;
|
||||
}
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
void LadspaEffectDialog::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
#if defined(__WXMAC__)
|
||||
@ -1392,25 +1440,85 @@ void LadspaEffectDialog::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
#else
|
||||
Show(false);
|
||||
#endif
|
||||
mEffect->SaveParameters(wxT("Current"));
|
||||
|
||||
effect->mHost->Apply();
|
||||
mEffect->mHost->Apply();
|
||||
}
|
||||
#else
|
||||
void LadspaEffectDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
void LadspaEffectDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
mEffect->SaveParameters(wxT("Current"));
|
||||
|
||||
EndModal(TRUE);
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
|
||||
void LadspaEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
if (IsModal())
|
||||
{
|
||||
EndModal(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(__WXMAC__)
|
||||
Close();
|
||||
#else
|
||||
Show(false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnPreview(wxCommandEvent & WXUNUSED(event))
|
||||
void LadspaEffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
effect->Preview();
|
||||
mEffect->mHost->Preview();
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::OnDefaults(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
mEffect->LoadParameters(wxT("Default"));
|
||||
RefreshParaemters();
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::RefreshParaemters()
|
||||
{
|
||||
for (unsigned long p = 0; p < mNumParams; p++) {
|
||||
LADSPA_PortRangeHint hint = mData->PortRangeHints[mPorts[p]];
|
||||
|
||||
if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) {
|
||||
mToggles[p]->SetValue(mInputControls[mPorts[p]] > 0);
|
||||
}
|
||||
else {
|
||||
wxString bound;
|
||||
double lower = 0.0;
|
||||
double upper = 0.0;
|
||||
bool haslo = false;
|
||||
bool hashi = false;
|
||||
bool forceint = false;
|
||||
|
||||
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
|
||||
lower = hint.LowerBound;
|
||||
haslo = true;
|
||||
}
|
||||
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
|
||||
upper = hint.UpperBound;
|
||||
hashi = true;
|
||||
}
|
||||
if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) {
|
||||
lower *= mSampleRate;
|
||||
upper *= mSampleRate;
|
||||
forceint = true;
|
||||
}
|
||||
|
||||
wxString fieldText;
|
||||
if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint)
|
||||
fieldText.Printf(wxT("%d"), (int)(mInputControls[mPorts[p]] + 0.5));
|
||||
else
|
||||
fieldText = Internat::ToDisplayString(mInputControls[mPorts[p]]);
|
||||
mFields[p]->ChangeValue(fieldText);
|
||||
}
|
||||
}
|
||||
HandleText();
|
||||
}
|
||||
#endif
|
||||
|
||||
void LadspaEffectDialog::ConnectFocus(wxControl *c)
|
||||
{
|
||||
@ -1424,15 +1532,15 @@ void LadspaEffectDialog::DisconnectFocus(wxControl *c)
|
||||
wxFocusEventHandler(LadspaEffectDialog::ControlSetFocus));
|
||||
}
|
||||
|
||||
void LadspaEffectDialog::ControlSetFocus(wxFocusEvent &event)
|
||||
void LadspaEffectDialog::ControlSetFocus(wxFocusEvent & evt)
|
||||
{
|
||||
wxControl *c = (wxControl *) event.GetEventObject();
|
||||
wxControl *c = (wxControl *) evt.GetEventObject();
|
||||
wxScrolledWindow *p = (wxScrolledWindow *) c->GetParent();
|
||||
wxRect r = c->GetRect();
|
||||
wxRect rv = p->GetRect();
|
||||
rv.y = 0;
|
||||
|
||||
event.Skip();
|
||||
evt.Skip();
|
||||
|
||||
int y;
|
||||
int yppu;
|
||||
@ -1456,9 +1564,9 @@ void LadspaEffectDialog::ControlSetFocus(wxFocusEvent &event)
|
||||
|
||||
double LadspaEffectDialog::GetLength()
|
||||
{
|
||||
if (effect->GetType() == EffectTypeGenerate) {
|
||||
mLength = Internat::CompatibleToDouble(mSeconds->GetValue());
|
||||
if (mEffect->GetType() == EffectTypeGenerate) {
|
||||
return mSeconds->GetTimeValue();
|
||||
}
|
||||
|
||||
return mLength;
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ class wxCheckBox;
|
||||
#include "audacity/ModuleInterface.h"
|
||||
#include "audacity/PluginInterface.h"
|
||||
|
||||
#include "../../widgets/TimeTextCtrl.h"
|
||||
|
||||
#include "ladspa.h"
|
||||
|
||||
#define LADSPAEFFECTS_VERSION wxT("1.0.0.0");
|
||||
@ -126,6 +128,9 @@ private:
|
||||
float *mInputControls;
|
||||
float *mOutputControls;
|
||||
|
||||
int mLatencyPort;
|
||||
bool mLatencyDone;
|
||||
|
||||
// Realtime processing
|
||||
LadspaSlaveArray mSlaves;
|
||||
wxArrayInt mSlaveChannels;
|
||||
@ -185,39 +190,39 @@ class LadspaEffectDialog : public wxDialog
|
||||
|
||||
~LadspaEffectDialog();
|
||||
|
||||
void OnCheckBox(wxCommandEvent & event);
|
||||
void OnSlider(wxCommandEvent & event);
|
||||
void OnTextCtrl(wxCommandEvent & event);
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
void OnApply(wxCommandEvent & evt);
|
||||
#else
|
||||
void OnOk(wxCommandEvent & evt);
|
||||
void OnCancel(wxCommandEvent & evt);
|
||||
void OnPreview(wxCommandEvent & evt);
|
||||
#endif
|
||||
void ControlSetFocus(wxFocusEvent & event);
|
||||
|
||||
double GetLength();
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
private:
|
||||
void OnCheckBox(wxCommandEvent & evt);
|
||||
void OnSlider(wxCommandEvent & evt);
|
||||
void OnTextCtrl(wxCommandEvent & evt);
|
||||
void OnApply(wxCommandEvent & evt);
|
||||
void OnOK(wxCommandEvent & evt);
|
||||
void OnCancel(wxCommandEvent & evt);
|
||||
void OnPreview(wxCommandEvent & evt);
|
||||
void OnDefaults(wxCommandEvent & evt);
|
||||
|
||||
void HandleText();
|
||||
void RefreshParaemters();
|
||||
void ConnectFocus(wxControl *c);
|
||||
void DisconnectFocus(wxControl *c);
|
||||
void ControlSetFocus(wxFocusEvent & evt);
|
||||
|
||||
private:
|
||||
bool inSlider;
|
||||
bool inText;
|
||||
|
||||
double mLength;
|
||||
int sampleRate;
|
||||
int mSampleRate;
|
||||
const LADSPA_Descriptor *mData;
|
||||
wxSlider **sliders;
|
||||
wxTextCtrl **fields;
|
||||
wxStaticText **labels;
|
||||
wxCheckBox **toggles;
|
||||
unsigned long *ports;
|
||||
unsigned long numParams;
|
||||
wxSlider **mSliders;
|
||||
wxTextCtrl **mFields;
|
||||
wxStaticText **mLabels;
|
||||
wxCheckBox **mToggles;
|
||||
unsigned long *mPorts;
|
||||
unsigned long mNumParams;
|
||||
float *mInputControls;
|
||||
LadspaEffect *effect;
|
||||
wxTextCtrl *mSeconds;
|
||||
LadspaEffect *mEffect;
|
||||
TimeTextCtrl *mSeconds;
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ LV2Effect::LV2Effect(const LilvPlugin *data,
|
||||
fInBuffer = NULL;
|
||||
fOutBuffer = NULL;
|
||||
|
||||
mLength = 0;
|
||||
mDuration = 0;
|
||||
|
||||
// Allocate buffers for the port indices and the default control values
|
||||
int numPorts = lilv_plugin_get_num_ports(mData);
|
||||
@ -386,7 +386,7 @@ bool LV2Effect::PromptUser()
|
||||
return false;
|
||||
}
|
||||
|
||||
mLength = dlog.GetLength();
|
||||
mDuration = dlog.GetLength();
|
||||
mNoteLength = dlog.GetNoteLength();
|
||||
mNoteVelocity = dlog.GetNoteVelocity();
|
||||
mNoteKey = dlog.GetNoteKey();
|
||||
|
Loading…
x
Reference in New Issue
Block a user