mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-14 17:14:07 +01:00
Bug 2431 - Mac: Real-time effects - Enable checkbox has no effect
This commit is contained in:
@@ -87,9 +87,13 @@ BlackList[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct CFReleaser
|
struct CFReleaser
|
||||||
{ void operator () (const void *p) const { if (p) CFRelease(p); } };
|
{
|
||||||
template <typename T>
|
void operator () (const void *p) const
|
||||||
using CFunique_ptr = std::unique_ptr<T, CFReleaser>;
|
{
|
||||||
|
if (p) CFRelease(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T> using CFunique_ptr = std::unique_ptr<T, CFReleaser>;
|
||||||
|
|
||||||
// Uncomment to include parameter IDs in the final name. Only needed if it's
|
// Uncomment to include parameter IDs in the final name. Only needed if it's
|
||||||
// discovered that many effects have duplicate names. It could even be done
|
// discovered that many effects have duplicate names. It could even be done
|
||||||
@@ -360,17 +364,21 @@ unsigned AudioUnitEffectsModule::DiscoverPluginsAtPath(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(callback)
|
if (callback)
|
||||||
|
{
|
||||||
callback(this, &effect);
|
callback(this, &effect);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioUnitEffectsModule::IsPluginValid(
|
bool AudioUnitEffectsModule::IsPluginValid(const PluginPath & path, bool bFast)
|
||||||
const PluginPath & path, bool bFast)
|
|
||||||
{
|
{
|
||||||
if( bFast )
|
if (bFast)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
wxString name;
|
wxString name;
|
||||||
return FindAudioUnit(path, name) != NULL;
|
return FindAudioUnit(path, name) != NULL;
|
||||||
}
|
}
|
||||||
@@ -558,13 +566,13 @@ void AudioUnitEffectOptionsDialog::PopulateOrExchange(ShuttleGui & S)
|
|||||||
{
|
{
|
||||||
S.StartStatic(XO("Latency Compensation"));
|
S.StartStatic(XO("Latency Compensation"));
|
||||||
{
|
{
|
||||||
S.AddVariableText( XO(
|
S.AddVariableText(XO(
|
||||||
"As part of their processing, some Audio Unit effects must delay returning "
|
"As part of their processing, some Audio Unit effects must delay returning "
|
||||||
"audio to Audacity. When not compensating for this delay, you will "
|
"audio to Audacity. When not compensating for this delay, you will "
|
||||||
"notice that small silences have been inserted into the audio. "
|
"notice that small silences have been inserted into the audio. "
|
||||||
"Enabling this option will provide that compensation, but it may "
|
"Enabling this option will provide that compensation, but it may "
|
||||||
"not work for all Audio Unit effects."),
|
"not work for all Audio Unit effects."),
|
||||||
false, 0, 650 );
|
false, 0, 650);
|
||||||
|
|
||||||
S.StartHorizontalLay(wxALIGN_LEFT);
|
S.StartHorizontalLay(wxALIGN_LEFT);
|
||||||
{
|
{
|
||||||
@@ -577,7 +585,7 @@ void AudioUnitEffectOptionsDialog::PopulateOrExchange(ShuttleGui & S)
|
|||||||
|
|
||||||
S.StartStatic(XO("User Interface"));
|
S.StartStatic(XO("User Interface"));
|
||||||
{
|
{
|
||||||
S.AddVariableText( XO(
|
S.AddVariableText(XO(
|
||||||
"Select \"Full\" to use the graphical interface if supplied by the Audio Unit."
|
"Select \"Full\" to use the graphical interface if supplied by the Audio Unit."
|
||||||
" Select \"Generic\" to use the system supplied generic interface."
|
" Select \"Generic\" to use the system supplied generic interface."
|
||||||
#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
|
#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
|
||||||
@@ -687,7 +695,7 @@ void AudioUnitEffectImportDialog::PopulateOrExchange(ShuttleGui & S)
|
|||||||
{
|
{
|
||||||
mList = S.Style(wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
mList = S.Style(wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
|
||||||
wxLC_NO_SORT_HEADER)
|
wxLC_NO_SORT_HEADER)
|
||||||
.AddListControlReportMode( { XO("Preset"), XO("Location") } );
|
.AddListControlReportMode({ XO("Preset"), XO("Location") });
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
S.EndStatic();
|
||||||
}
|
}
|
||||||
@@ -764,7 +772,7 @@ TranslatableString AudioUnitEffectImportDialog::Import(
|
|||||||
wxFFile f(fullPath, wxT("r"));
|
wxFFile f(fullPath, wxT("r"));
|
||||||
if (!f.IsOpened())
|
if (!f.IsOpened())
|
||||||
{
|
{
|
||||||
return XO("Couldn't open \"%s\"").Format( fullPath );
|
return XO("Couldn't open \"%s\"").Format(fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load it into the buffer
|
// Load it into the buffer
|
||||||
@@ -772,13 +780,13 @@ TranslatableString AudioUnitEffectImportDialog::Import(
|
|||||||
wxMemoryBuffer buf(len);
|
wxMemoryBuffer buf(len);
|
||||||
if (f.Read(buf.GetData(), len) != len || f.Error())
|
if (f.Read(buf.GetData(), len) != len || f.Error())
|
||||||
{
|
{
|
||||||
return XO("Unable to read the preset from \"%s\"").Format( fullPath );
|
return XO("Unable to read the preset from \"%s\"").Format(fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString parms = wxBase64Encode(buf.GetData(), len);
|
wxString parms = wxBase64Encode(buf.GetData(), len);
|
||||||
if (parms.IsEmpty())
|
if (parms.IsEmpty())
|
||||||
{
|
{
|
||||||
return XO("Failed to encode preset from \"%s\"").Format( fullPath );
|
return XO("Failed to encode preset from \"%s\"").Format(fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// And write it to the config
|
// And write it to the config
|
||||||
@@ -812,7 +820,7 @@ void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & evt)
|
|||||||
if (!msg.empty())
|
if (!msg.empty())
|
||||||
{
|
{
|
||||||
AudacityMessageBox(
|
AudacityMessageBox(
|
||||||
XO("Could not import \"%s\" preset\n\n%s").Format( name, msg ),
|
XO("Could not import \"%s\" preset\n\n%s").Format(name, msg),
|
||||||
XO("Import Audio Unit Presets"),
|
XO("Import Audio Unit Presets"),
|
||||||
wxOK | wxCENTRE,
|
wxOK | wxCENTRE,
|
||||||
this);
|
this);
|
||||||
@@ -854,6 +862,8 @@ AudioUnitEffect::AudioUnitEffect(const PluginPath & path,
|
|||||||
mUnitInitialized = false;
|
mUnitInitialized = false;
|
||||||
|
|
||||||
mEventListenerRef = NULL;
|
mEventListenerRef = NULL;
|
||||||
|
|
||||||
|
mReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioUnitEffect::~AudioUnitEffect()
|
AudioUnitEffect::~AudioUnitEffect()
|
||||||
@@ -1218,7 +1228,7 @@ sampleCount AudioUnitEffect::GetLatency()
|
|||||||
&latency,
|
&latency,
|
||||||
&dataSize);
|
&dataSize);
|
||||||
|
|
||||||
return sampleCount( latency * mSampleRate );
|
return sampleCount(latency * mSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1248,10 +1258,10 @@ bool AudioUnitEffect::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelN
|
|||||||
{
|
{
|
||||||
OSStatus result;
|
OSStatus result;
|
||||||
|
|
||||||
mInputList.reinit( mAudioIns );
|
mInputList.reinit(mAudioIns);
|
||||||
mInputList[0].mNumberBuffers = mAudioIns;
|
mInputList[0].mNumberBuffers = mAudioIns;
|
||||||
|
|
||||||
mOutputList.reinit( mAudioOuts );
|
mOutputList.reinit(mAudioOuts);
|
||||||
mOutputList[0].mNumberBuffers = mAudioOuts;
|
mOutputList[0].mNumberBuffers = mAudioOuts;
|
||||||
|
|
||||||
memset(&mTimeStamp, 0, sizeof(AudioTimeStamp));
|
memset(&mTimeStamp, 0, sizeof(AudioTimeStamp));
|
||||||
@@ -1341,7 +1351,7 @@ size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t b
|
|||||||
bool AudioUnitEffect::RealtimeInitialize()
|
bool AudioUnitEffect::RealtimeInitialize()
|
||||||
{
|
{
|
||||||
mMasterIn.reinit(mAudioIns, mBlockSize, true);
|
mMasterIn.reinit(mAudioIns, mBlockSize, true);
|
||||||
mMasterOut.reinit( mAudioOuts, mBlockSize );
|
mMasterOut.reinit(mAudioOuts, mBlockSize);
|
||||||
return ProcessInitialize(0);
|
return ProcessInitialize(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1349,14 +1359,18 @@ bool AudioUnitEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRat
|
|||||||
{
|
{
|
||||||
auto slave = std::make_unique<AudioUnitEffect>(mPath, mName, mComponent, this);
|
auto slave = std::make_unique<AudioUnitEffect>(mPath, mName, mComponent, this);
|
||||||
if (!slave->SetHost(NULL))
|
if (!slave->SetHost(NULL))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
slave->SetBlockSize(mBlockSize);
|
slave->SetBlockSize(mBlockSize);
|
||||||
slave->SetChannelCount(numChannels);
|
slave->SetChannelCount(numChannels);
|
||||||
slave->SetSampleRate(sampleRate);
|
slave->SetSampleRate(sampleRate);
|
||||||
|
|
||||||
if (!CopyParameters(mUnit, slave->mUnit))
|
if (!CopyParameters(mUnit, slave->mUnit))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto pSlave = slave.get();
|
auto pSlave = slave.get();
|
||||||
mSlaves.push_back(std::move(slave));
|
mSlaves.push_back(std::move(slave));
|
||||||
@@ -1367,7 +1381,9 @@ bool AudioUnitEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRat
|
|||||||
bool AudioUnitEffect::RealtimeFinalize()
|
bool AudioUnitEffect::RealtimeFinalize()
|
||||||
{
|
{
|
||||||
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
|
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
|
||||||
|
{
|
||||||
mSlaves[i]->ProcessFinalize();
|
mSlaves[i]->ProcessFinalize();
|
||||||
|
}
|
||||||
mSlaves.clear();
|
mSlaves.clear();
|
||||||
|
|
||||||
mMasterIn.reset();
|
mMasterIn.reset();
|
||||||
@@ -1378,26 +1394,46 @@ bool AudioUnitEffect::RealtimeFinalize()
|
|||||||
|
|
||||||
bool AudioUnitEffect::RealtimeSuspend()
|
bool AudioUnitEffect::RealtimeSuspend()
|
||||||
{
|
{
|
||||||
|
if (!BypassEffect(true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
|
||||||
|
{
|
||||||
|
if (!mSlaves[i]->BypassEffect(true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioUnitEffect::RealtimeResume()
|
bool AudioUnitEffect::RealtimeResume()
|
||||||
{
|
{
|
||||||
OSStatus result;
|
if (!BypassEffect(false))
|
||||||
|
|
||||||
result = AudioUnitReset(mUnit, kAudioUnitScope_Global, 0);
|
|
||||||
if (result != noErr)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
|
||||||
|
{
|
||||||
|
if (!mSlaves[i]->BypassEffect(false))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioUnitEffect::RealtimeProcessStart()
|
bool AudioUnitEffect::RealtimeProcessStart()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < mAudioIns; i++)
|
for (size_t i = 0; i < mAudioIns; i++)
|
||||||
|
{
|
||||||
memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float));
|
memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
mNumSamples = 0;
|
mNumSamples = 0;
|
||||||
|
|
||||||
@@ -1425,29 +1461,34 @@ size_t AudioUnitEffect::RealtimeProcess(int group,
|
|||||||
|
|
||||||
bool AudioUnitEffect::RealtimeProcessEnd()
|
bool AudioUnitEffect::RealtimeProcessEnd()
|
||||||
{
|
{
|
||||||
ProcessBlock(
|
ProcessBlock(reinterpret_cast<float**>(mMasterIn.get()),
|
||||||
reinterpret_cast<float**>(mMasterIn.get()),
|
reinterpret_cast<float**>(mMasterOut.get()),
|
||||||
reinterpret_cast<float**>(mMasterOut.get()),
|
mNumSamples);
|
||||||
mNumSamples);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioUnitEffect::ShowInterface(
|
bool AudioUnitEffect::ShowInterface(wxWindow &parent,
|
||||||
wxWindow &parent, const EffectDialogFactory &factory, bool forceModal)
|
const EffectDialogFactory &factory,
|
||||||
|
bool forceModal)
|
||||||
{
|
{
|
||||||
if (mDialog)
|
if (mDialog)
|
||||||
{
|
{
|
||||||
if( mDialog->Close(true) )
|
if (mDialog->Close(true))
|
||||||
|
{
|
||||||
mDialog = nullptr;
|
mDialog = nullptr;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mDialog is null
|
// mDialog is null
|
||||||
auto cleanup = valueRestorer( mDialog );
|
auto cleanup = valueRestorer(mDialog);
|
||||||
|
|
||||||
if ( factory )
|
if (factory)
|
||||||
|
{
|
||||||
mDialog = factory(parent, mHost, this);
|
mDialog = factory(parent, mHost, this);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mDialog)
|
if (!mDialog)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1713,7 +1754,7 @@ bool AudioUnitEffect::PopulateUI(ShuttleGui &S)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
auto pControl = Destroy_ptr<AUControl>( safenew AUControl );
|
auto pControl = Destroy_ptr<AUControl>(safenew AUControl);
|
||||||
if (!pControl)
|
if (!pControl)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1856,7 +1897,7 @@ void AudioUnitEffect::ExportPresets()
|
|||||||
if (!msg.empty())
|
if (!msg.empty())
|
||||||
{
|
{
|
||||||
AudacityMessageBox(
|
AudacityMessageBox(
|
||||||
XO("Could not export \"%s\" preset\n\n%s").Format( path, msg ),
|
XO("Could not export \"%s\" preset\n\n%s").Format(path, msg),
|
||||||
XO("Export Audio Unit Presets"),
|
XO("Export Audio Unit Presets"),
|
||||||
wxOK | wxCENTRE,
|
wxOK | wxCENTRE,
|
||||||
mParent);
|
mParent);
|
||||||
@@ -1898,7 +1939,7 @@ void AudioUnitEffect::ImportPresets()
|
|||||||
if (!msg.empty())
|
if (!msg.empty())
|
||||||
{
|
{
|
||||||
AudacityMessageBox(
|
AudacityMessageBox(
|
||||||
XO("Could not import \"%s\" preset\n\n%s").Format( path, msg ),
|
XO("Could not import \"%s\" preset\n\n%s").Format(path, msg),
|
||||||
XO("Import Audio Unit Presets"),
|
XO("Import Audio Unit Presets"),
|
||||||
wxOK | wxCENTRE,
|
wxOK | wxCENTRE,
|
||||||
mParent);
|
mParent);
|
||||||
@@ -2477,7 +2518,7 @@ void AudioUnitEffect::EventListener(const AudioUnitEvent *inEvent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AudioUnitEffect::EventListenerCallback(void *inCallbackRefCon,
|
void AudioUnitEffect::EventListenerCallback(void *inCallbackRefCon,
|
||||||
void *inObject,
|
void *inObject,
|
||||||
@@ -2649,4 +2690,24 @@ void AudioUnitEffect::GetChannelCounts()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioUnitEffect::BypassEffect(bool bypass)
|
||||||
|
{
|
||||||
|
OSStatus result;
|
||||||
|
|
||||||
|
UInt32 value = (bypass ? 1 : 0);
|
||||||
|
|
||||||
|
result = AudioUnitSetProperty(mUnit,
|
||||||
|
kAudioUnitProperty_BypassEffect,
|
||||||
|
kAudioUnitScope_Global,
|
||||||
|
0,
|
||||||
|
&value,
|
||||||
|
sizeof(value));
|
||||||
|
if (result != noErr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -172,6 +172,8 @@ private:
|
|||||||
bool CreatePlain(wxWindow *parent);
|
bool CreatePlain(wxWindow *parent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool BypassEffect(bool bypass);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
PluginPath mPath;
|
PluginPath mPath;
|
||||||
|
|||||||
Reference in New Issue
Block a user