From 782ef138e0f89460b4897d83edb3727a573e9da9 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 6 Jun 2020 14:59:02 -0400 Subject: [PATCH] Bug2431 residual: Restore commit 5e8cfb0... ... as urged by Leland. It is really needed for a more complete fix. This reverts commit 9894abc4f4477dee88022415a919adcfe96e2e80. --- src/effects/audiounits/AudioUnitEffect.cpp | 131 +++++++++++++++------ src/effects/audiounits/AudioUnitEffect.h | 2 + 2 files changed, 97 insertions(+), 36 deletions(-) diff --git a/src/effects/audiounits/AudioUnitEffect.cpp b/src/effects/audiounits/AudioUnitEffect.cpp index eafb2acf1..857cb8efe 100644 --- a/src/effects/audiounits/AudioUnitEffect.cpp +++ b/src/effects/audiounits/AudioUnitEffect.cpp @@ -87,9 +87,13 @@ BlackList[] = }; struct CFReleaser - { void operator () (const void *p) const { if (p) CFRelease(p); } }; -template - using CFunique_ptr = std::unique_ptr; +{ + void operator () (const void *p) const + { + if (p) CFRelease(p); + } +}; +template using CFunique_ptr = std::unique_ptr; // 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 @@ -358,17 +362,21 @@ unsigned AudioUnitEffectsModule::DiscoverPluginsAtPath( return 0; } - if(callback) + if (callback) + { callback(this, &effect); + } return 1; } -bool AudioUnitEffectsModule::IsPluginValid( - const PluginPath & path, bool bFast) +bool AudioUnitEffectsModule::IsPluginValid(const PluginPath & path, bool bFast) { - if( bFast ) + if (bFast) + { return true; + } + wxString name; return FindAudioUnit(path, name) != NULL; } @@ -556,13 +564,13 @@ void AudioUnitEffectOptionsDialog::PopulateOrExchange(ShuttleGui & S) { S.StartStatic(XO("Latency Compensation")); { - S.AddVariableText( XO( + S.AddVariableText(XO( "As part of their processing, some Audio Unit effects must delay returning " "audio to Audacity. When not compensating for this delay, you will " "notice that small silences have been inserted into the audio. " "Enabling this option will provide that compensation, but it may " "not work for all Audio Unit effects."), - false, 0, 650 ); + false, 0, 650); S.StartHorizontalLay(wxALIGN_LEFT); { @@ -575,7 +583,7 @@ void AudioUnitEffectOptionsDialog::PopulateOrExchange(ShuttleGui & S) 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 \"Generic\" to use the system supplied generic interface." #if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT) @@ -685,7 +693,7 @@ void AudioUnitEffectImportDialog::PopulateOrExchange(ShuttleGui & S) { mList = S.Style(wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_NO_SORT_HEADER) - .AddListControlReportMode( { XO("Preset"), XO("Location") } ); + .AddListControlReportMode({ XO("Preset"), XO("Location") }); } S.EndStatic(); } @@ -762,7 +770,7 @@ TranslatableString AudioUnitEffectImportDialog::Import( wxFFile f(fullPath, wxT("r")); if (!f.IsOpened()) { - return XO("Couldn't open \"%s\"").Format( fullPath ); + return XO("Couldn't open \"%s\"").Format(fullPath); } // Load it into the buffer @@ -770,13 +778,13 @@ TranslatableString AudioUnitEffectImportDialog::Import( wxMemoryBuffer buf(len); 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); 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 @@ -810,7 +818,7 @@ void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & evt) if (!msg.empty()) { 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"), wxOK | wxCENTRE, this); @@ -1218,7 +1226,7 @@ sampleCount AudioUnitEffect::GetLatency() &latency, &dataSize); - return sampleCount( latency * mSampleRate ); + return sampleCount(latency * mSampleRate); } return 0; @@ -1248,10 +1256,10 @@ bool AudioUnitEffect::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelN { OSStatus result; - mInputList.reinit( mAudioIns ); + mInputList.reinit(mAudioIns); mInputList[0].mNumberBuffers = mAudioIns; - mOutputList.reinit( mAudioOuts ); + mOutputList.reinit(mAudioOuts); mOutputList[0].mNumberBuffers = mAudioOuts; memset(&mTimeStamp, 0, sizeof(AudioTimeStamp)); @@ -1341,7 +1349,7 @@ size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t b bool AudioUnitEffect::RealtimeInitialize() { mMasterIn.reinit(mAudioIns, mBlockSize, true); - mMasterOut.reinit( mAudioOuts, mBlockSize ); + mMasterOut.reinit(mAudioOuts, mBlockSize); return ProcessInitialize(0); } @@ -1349,14 +1357,18 @@ bool AudioUnitEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRat { auto slave = std::make_unique(mPath, mName, mComponent, this); if (!slave->SetHost(NULL)) + { return false; + } slave->SetBlockSize(mBlockSize); slave->SetChannelCount(numChannels); slave->SetSampleRate(sampleRate); if (!CopyParameters(mUnit, slave->mUnit)) + { return false; + } auto pSlave = slave.get(); mSlaves.push_back(std::move(slave)); @@ -1367,7 +1379,9 @@ bool AudioUnitEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRat bool AudioUnitEffect::RealtimeFinalize() { for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++) + { mSlaves[i]->ProcessFinalize(); + } mSlaves.clear(); mMasterIn.reset(); @@ -1378,26 +1392,46 @@ bool AudioUnitEffect::RealtimeFinalize() 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; } bool AudioUnitEffect::RealtimeResume() { - OSStatus result; - - result = AudioUnitReset(mUnit, kAudioUnitScope_Global, 0); - if (result != noErr) + if (!BypassEffect(false)) { return false; } + for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++) + { + if (!mSlaves[i]->BypassEffect(false)) + { + return false; + } + } + return true; } bool AudioUnitEffect::RealtimeProcessStart() { for (size_t i = 0; i < mAudioIns; i++) + { memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float)); + } mNumSamples = 0; @@ -1425,29 +1459,34 @@ size_t AudioUnitEffect::RealtimeProcess(int group, bool AudioUnitEffect::RealtimeProcessEnd() { - ProcessBlock( - reinterpret_cast(mMasterIn.get()), - reinterpret_cast(mMasterOut.get()), - mNumSamples); + ProcessBlock(reinterpret_cast(mMasterIn.get()), + reinterpret_cast(mMasterOut.get()), + mNumSamples); return true; } -bool AudioUnitEffect::ShowInterface( - wxWindow &parent, const EffectDialogFactory &factory, bool forceModal) +bool AudioUnitEffect::ShowInterface(wxWindow &parent, + const EffectDialogFactory &factory, + bool forceModal) { if (mDialog) { - if( mDialog->Close(true) ) + if (mDialog->Close(true)) + { mDialog = nullptr; + } return false; } // mDialog is null - auto cleanup = valueRestorer( mDialog ); + auto cleanup = valueRestorer(mDialog); - if ( factory ) + if (factory) + { mDialog = factory(parent, mHost, this); + } + if (!mDialog) { return false; @@ -1713,7 +1752,7 @@ bool AudioUnitEffect::PopulateUI(ShuttleGui &S) else #endif { - auto pControl = Destroy_ptr( safenew AUControl ); + auto pControl = Destroy_ptr(safenew AUControl); if (!pControl) { return false; @@ -1856,7 +1895,7 @@ void AudioUnitEffect::ExportPresets() if (!msg.empty()) { 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"), wxOK | wxCENTRE, mParent); @@ -1898,7 +1937,7 @@ void AudioUnitEffect::ImportPresets() if (!msg.empty()) { 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"), wxOK | wxCENTRE, mParent); @@ -2477,7 +2516,7 @@ void AudioUnitEffect::EventListener(const AudioUnitEvent *inEvent, } } } - + // static void AudioUnitEffect::EventListenerCallback(void *inCallbackRefCon, void *inObject, @@ -2649,4 +2688,24 @@ void AudioUnitEffect::GetChannelCounts() 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 diff --git a/src/effects/audiounits/AudioUnitEffect.h b/src/effects/audiounits/AudioUnitEffect.h index 1103fd055..d1bd7206e 100644 --- a/src/effects/audiounits/AudioUnitEffect.h +++ b/src/effects/audiounits/AudioUnitEffect.h @@ -172,6 +172,8 @@ private: bool CreatePlain(wxWindow *parent); #endif + bool BypassEffect(bool bypass); + private: PluginPath mPath;