Audacity 3.2.0
AudioUnitEffect.cpp
Go to the documentation of this file.
1/*!********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file AudioUnitEffect.cpp
6
7 Dominic Mazzoni
8 Leland Lucius
9
10*******************************************************************//*******************************************************************/
16
17#if USE_AUDIO_UNITS
18#include "AudioUnitEffect.h"
20#include "AudioUnitInstance.h"
21#include "AudioUnitValidator.h"
22#include "SampleCount.h"
23#include "ConfigInterface.h"
24
25#include <optional>
26#include <wx/defs.h>
27#include <wx/base64.h>
28#include <wx/button.h>
29#include <wx/control.h>
30#include <wx/crt.h>
31#include <wx/dir.h>
32#include <wx/ffile.h>
33
34#ifdef __WXMAC__
35#include <wx/evtloop.h>
36#endif
37
38#include <wx/filename.h>
39#include <wx/frame.h>
40#include <wx/listctrl.h>
41#include <wx/log.h>
42#include <wx/settings.h>
43#include <wx/stattext.h>
44#include <wx/textctrl.h>
45#include <wx/osx/core/private.h>
46
47#include "../../SelectFile.h"
48#include "../../ShuttleGui.h"
49#include "../../widgets/AudacityMessageBox.h"
50#include "../../widgets/valnum.h"
51
52//
53// When a plug-in's state is saved to the settings file (as a preset),
54// it is in binary and gets base64 encoded before storing.
55//
56// When exporting, save as XML without base64 encoding.
57//
58// The advantages of XML format is less chance of failures occurring
59// when exporting. But, it can take a bit more space per preset int
60// the Audacity settings file.
61//
62// Using binary for now. Use kCFPropertyListXMLFormat_v1_0 if XML
63// format is desired.
64//
65#define PRESET_FORMAT kCFPropertyListBinaryFormat_v1_0
66
67// Name of the settings key to use for the above value
68#define PRESET_KEY wxT("Data")
69
70// Where the presets are located
71#define PRESET_LOCAL_PATH wxT("/Library/Audio/Presets")
72#define PRESET_USER_PATH wxT("~/Library/Audio/Presets")
73
75 const RegistryPath &group, const wxString &path,
76 const void *blob, size_t len, bool allowEmpty) const
77{
78 // Base64 encode the returned binary property list
79 auto parms = wxBase64Encode(blob, len);
80 if (!allowEmpty && parms.IsEmpty())
81 return XO("Failed to encode preset from \"%s\"").Format(path);
82
83 // And write it to the config
84 if (!SetConfig(*this, PluginSettings::Private, group, PRESET_KEY, parms))
85 return XO("Unable to store preset in config file");
86 return {};
87}
88
90//
91// AudioUnitEffect
92//
94
96 const wxString & name, AudioComponent component,
97 Parameters *pParameters, AudioUnitEffect *master
98) : AudioUnitWrapper{ component, pParameters }
99 , mPath{ path }
100 , mName{ name.AfterFirst(wxT(':')).Trim(true).Trim(false) }
101 , mVendor{ name.BeforeFirst(wxT(':')).Trim(true).Trim(false) }
102{
103}
104
106{
107}
108
109// ============================================================================
110// ComponentInterface implementation
111// ============================================================================
112
114{
115 return mPath;
116}
117
119{
120 return mName;
121}
122
124{
125 return { mVendor };
126}
127
129{
130 UInt32 version;
131
132 OSStatus result = AudioComponentGetVersion(mComponent, &version);
133
134 return wxString::Format(wxT("%d.%d.%d"),
135 (version >> 16) & 0xffff,
136 (version >> 8) & 0xff,
137 version & 0xff);
138}
139
141{
142 /* i18n-hint: Can mean "not available," "not applicable," "no answer" */
143 return XO("n/a");
144}
145
146// ============================================================================
147// EffectDefinitionInterface implementation
148// ============================================================================
149
151{
152 if (mAudioIns == 0 && mAudioOuts == 0)
153 {
154 return EffectTypeNone;
155 }
156
157 if (mAudioIns == 0)
158 {
159 return EffectTypeGenerate;
160 }
161
162 if (mAudioOuts == 0)
163 {
164 return EffectTypeAnalyze;
165 }
166
167 return EffectTypeProcess;
168}
169
171{
173}
174
176{
177 return mInteractive;
178}
179
181{
182 return false;
183}
184
186{
187 return GetType() == EffectTypeProcess
190}
191
193{
194 bool supports = false;
196 [&supports](const ParameterInfo &pi, AudioUnitParameterID) {
197 if (pi.mInfo.flags & kAudioUnitParameterFlag_IsWritable)
198 supports = true;
199 // Search only until we find one, that's all we need to know
200 return !supports;
201 });
202 return supports;
203}
204
205std::shared_ptr<EffectInstance> AudioUnitEffect::MakeInstance() const
206{
207 return std::make_shared<AudioUnitInstance>(*this, mComponent, mParameters,
209}
210
211constexpr auto OptionsKey = L"Options";
212constexpr auto UseLatencyKey = L"UseLatency";
213constexpr auto UITypeKey = L"UIType";
214
216{
217 // To implement the services of EffectPlugin -- such as, a query of the
218 // set of effect parameters, so that we can implement MakeSettings -- we
219 // also need what is called an AudioComponentInstance, also called an
220 // AudioUnit.
221 // It's not just for implementing EffectInstance. AudioUnits is unlike other
222 // third party effect families that distinguish the notions of plug-in and
223 // instance.
224
226
227 if (!CreateAudioUnit())
228 return false;
229
230 // Use an arbitrary rate while completing the discovery of channel support
231 if (!SetRateAndChannels(44100.0, GetSymbol().Internal()))
232 return false;
233
234 // Determine interactivity
236 if (!mInteractive) {
237 // Check for a Cocoa UI
238 // This could retrieve a variable-size property, but we only look at
239 // the first element.
240 AudioUnitCocoaViewInfo cocoaViewInfo;
242 !GetFixedSizeProperty(kAudioUnitProperty_CocoaUI, cocoaViewInfo);
243 if (!mInteractive) {
244 // Check for a Carbon UI
245 // This could retrieve a variable sized array but we only need the
246 // first
247 AudioComponentDescription compDesc;
249 kAudioUnitProperty_GetUIComponentList, compDesc);
250 }
251 }
252
253 return true;
254}
255
257{
258 if (!InitializePlugin())
259 return false;
260
261 // Reading these values from the config file can't be done in the PluginHost
262 // process but isn't needed only for plugin discovery.
263
264 // Consult preferences
265 // Decide mUseLatency, which affects GetLatency(), which is actually used
266 // so far only in destructive effect processing
268 mUseLatency, true);
269 // Decide whether to build plain or fancy user interfaces
271 mUIType, FullValue.MSGID().GET() /* Config stores un-localized string */);
272
273 return true;
274}
275
276#if 0
278{
279 // Retrieve the tail time
280 Float64 tailTime = 0.0;
281 if (!GetFixedSizeProperty(kAudioUnitProperty_TailTime, tailTime))
282 return tailTime * mSampleRate;
283 return 0;
284}
285#endif
286
287int AudioUnitEffect::ShowClientInterface(wxWindow &parent, wxDialog &dialog,
288 EffectUIValidator *, bool forceModal)
289{
290 if ((SupportsRealtime() || GetType() == EffectTypeAnalyze) && !forceModal) {
291 dialog.Show();
292 return 0;
293 }
294 return dialog.ShowModal();
295}
296
297// Don't use the template-generated MakeSettings(), which default-constructs
298// the structure. Instead allocate a number of values chosen by the plug-in
300{
302 FetchSettings(settings, true);
303 return EffectSettings::Make<AudioUnitEffectSettings>(std::move(settings));
304}
305
307 const EffectSettings &, EffectSettings &) const
308{
309 // Not needed -- rely on EffectInstance::Message instead
310 return true;
311}
312
313constexpr auto PresetStr = "_PRESET";
314
317{
318 // Find a key to use for the preset that does not collide with any
319 // parameter name
320 wxString result = PresetStr;
321
322 // That string probably works but be sure
323 const auto &map = GetSettings(settings).values;
324 using Pair = decltype(*map.begin());
325 while (std::any_of(map.begin(), map.end(), [&](Pair &pair){
326 return pair.second && pair.second->first == result;
327 }))
328 result += "_";
329
330 return result;
331}
332
334{
335 RegistryPath result;
336 auto len = strlen(PresetStr);
337 if (auto [index, key] = std::tuple(0L, wxString{})
338 ; parms.GetFirstEntry(key, index)
339 ) do {
340 if (key.StartsWith(PresetStr)
341 && key.Mid(len).find_first_not_of("_") == wxString::npos
342 && key.length() > result.length())
343 result = key;
344 } while(parms.GetNextEntry(key, index));
345 return result;
346}
347
349 const EffectSettings &settings, CommandParameters & parms) const
350{
351 const auto &mySettings = GetSettings(settings);
352 if (mySettings.mPresetNumber) {
353 const auto key = ChoosePresetKey(settings);
354 parms.Write(key, *mySettings.mPresetNumber);
355 }
356
357 // Save settings into CommandParameters
358 // Iterate the map only, not using any AudioUnit handles
359 for (auto &[ID, pPair] : mySettings.values)
360 if (pPair)
361 // Write names, not numbers, as keys in the config file
362 parms.Write(pPair->first, pPair->second);
363 return true;
364}
365
367 const CommandParameters & parms, EffectSettings &settings) const
368{
369 // First clean all settings, in case any are not defined in parms
370 auto &mySettings = GetSettings(settings);
371 mySettings.ResetValues();
372 auto &map = mySettings.values;
373
374 // Reload preset first
375 if (auto presetKey = FindPresetKey(parms); !presetKey.empty()) {
376 SInt32 value = 0;
377 if (parms.Read(presetKey, &value))
379 }
380
381 // Load settings from CommandParameters
382 // Iterate the config only, not using any AudioUnit handles
383 if (auto [index, key, value] = std::tuple(
384 0L, wxString{}, AudioUnitParameterValue{})
385 ; parms.GetFirstEntry(key, index)
386 ) do {
387 if (auto pKey = ParameterInfo::ParseKey(key)
388 ; pKey && parms.Read(key, &value)
389 )
390 map[*pKey].emplace(mySettings.Intern(key), value);
391 } while(parms.GetNextEntry(key, index));
392 return true;
393}
394
397{
398 // To do: externalize state so const_cast isn't needed
399 return const_cast<AudioUnitEffect*>(this)->LoadPreset(name, settings);
400}
401
403 const RegistryPath & name, const EffectSettings &settings) const
404{
406}
407
410{
412 return { nullptr };
413 return {};
414}
415
417{
418 RegistryPaths presets;
419
420 // Retrieve the list of factory presets
421 CF_ptr<CFArrayRef> array;
422 if (!GetFixedSizeProperty(kAudioUnitProperty_FactoryPresets, array))
423 for (CFIndex i = 0, cnt = CFArrayGetCount(array.get()); i < cnt; ++i)
424 presets.push_back(wxCFStringRef::AsString(
425 static_cast<const AUPreset*>(CFArrayGetValueAtIndex(array.get(), i))
426 ->presetName));
427 return presets;
428}
429
430// ============================================================================
431// EffectUIClientInterface Implementation
432// ============================================================================
433
434std::unique_ptr<EffectUIValidator> AudioUnitEffect::PopulateUI(ShuttleGui &S,
435 EffectInstance &instance, EffectSettingsAccess &access,
436 const EffectOutputs *)
437{
438 mParent = S.GetParent();
439 return AudioUnitValidator::Create(*this, S, mUIType, instance, access);
440}
441
442#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
443bool AudioUnitEffect::CreatePlain(wxWindow *parent)
444{
445 // TODO??? Never implemented...
446 return false;
447}
448#endif
449
451{
452#ifdef __WXMAC__
453#ifdef __WX_EVTLOOP_BUSY_WAITING__
454 wxEventLoop::SetBusyWaiting(false);
455#endif
456#endif
457 mParent = nullptr;
458 return true;
459}
460
462{
463 return true;
464}
465
467{
468 // Generate the user domain path
469 wxFileName fn;
470 fn.SetPath(PRESET_USER_PATH);
471 fn.AppendDir(mVendor);
472 fn.AppendDir(mName);
473 fn.Normalize();
474 FilePath path = fn.GetFullPath();
475
476 if (!fn.Mkdir(fn.GetFullPath(), 0755, wxPATH_MKDIR_FULL)) {
477 wxLogError(wxT("Couldn't create the \"%s\" directory"), fn.GetPath());
478 return;
479 }
480
481 // Ask the user for the name to use
482 //
483 // Passing a valid parent will cause some effects dialogs to malfunction
484 // upon returning from the SelectFile().
485 path = SelectFile(FileNames::Operation::_None,
486 XO("Export Audio Unit Preset As %s:").Format(fn.GetFullPath()),
487 fn.GetFullPath(),
488 wxEmptyString,
489 wxT("aupreset"),
490 {
491 { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
492 },
493 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
494 NULL);
495
496 // User canceled...
497 if (path.empty())
498 return;
499
500 auto msg = Export(GetSettings(settings), path);
501 if (!msg.empty())
503 XO("Could not export \"%s\" preset\n\n%s").Format(path, msg),
504 XO("Export Audio Unit Presets"),
505 wxOK | wxCENTRE,
506 mParent);
507}
508
510{
511 // Generate the user domain path
512 wxFileName fn;
513 fn.SetPath(PRESET_USER_PATH);
514 fn.AppendDir(mVendor);
515 fn.AppendDir(mName);
516 fn.Normalize();
517 FilePath path = fn.GetFullPath();
518
519 // Ask the user for the name to use
520 //
521 // Passing a valid parent will cause some effects dialogs to malfunction
522 // upon returning from the SelectFile().
523 path = SelectFile(FileNames::Operation::_None,
524 XO("Import Audio Unit Preset As %s:").Format(fn.GetFullPath()),
525 fn.GetFullPath(), wxEmptyString, wxT("aupreset"),
526 {
527 { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
528 },
529 wxFD_OPEN | wxRESIZE_BORDER,
530 nullptr);
531
532 // User canceled...
533 if (path.empty())
534 return {};
535
536 auto msg = Import(GetSettings(settings), path);
537 if (!msg.empty()) {
539 XO("Could not import \"%s\" preset\n\n%s").Format(path, msg),
540 XO("Import Audio Unit Presets"),
541 wxOK | wxCENTRE,
542 mParent);
543 return {};
544 }
545
546 return { nullptr };
547}
548
550{
551 return true;
552}
553
555{
557 if (dlg.ShowModal()) {
558 // Save changed values to the config file
562 }
563}
564
565// ============================================================================
566// AudioUnitEffect Implementation
567// ============================================================================
568
570 const RegistryPath & group, EffectSettings &settings) const
571{
572 // Migration of very old format configuration file, should not normally
573 // happen and perhaps this code can be abandoned
574 // Attempt to load old preset parameters and resave using new method
575 constexpr auto oldKey = L"Parameters";
576 wxString parms;
578 group, oldKey, parms, wxEmptyString)) {
580 if (eap.SetParameters(parms))
581 if (LoadSettings(eap, settings))
582 if (SavePreset(group, GetSettings(settings)))
583 RemoveConfig(*this, PluginSettings::Private, group, oldKey);
584 return true;
585 }
586 return false;
587}
588
590 const RegistryPath & group, EffectSettings &settings) const
591{
592 if (MigrateOldConfigFile(group, settings))
593 return { nullptr };
594
595 if (AudioUnitWrapper::LoadPreset(*this, group, settings))
596 return { nullptr };
597 return {};
598}
599
601 const RegistryPath & group, const AudioUnitEffectSettings &settings) const
602{
603 wxCFStringRef cfname(wxFileNameFromPath(group));
604 const auto &[data, _] = MakeBlob(*this, settings, cfname, true);
605 if (!data)
606 return false;
607
608 // Nothing to do if we don't have any data
609 if (const auto length = CFDataGetLength(data.get())) {
610 auto error =
611 SaveBlobToConfig(group, {}, CFDataGetBytePtr(data.get()), length);
612 if (!error.empty())
613 return false;
614 }
615 return true;
616}
617
619 const AudioUnitEffectSettings &settings, const wxString & path) const
620{
621 // Create the file
622 wxFFile f(path, wxT("wb"));
623 if (!f.IsOpened())
624 return XO("Couldn't open \"%s\"").Format(path);
625
626 // First set the name of the preset
627 wxCFStringRef cfname(wxFileName(path).GetName());
628
629 const auto &[data, message] = MakeBlob(*this, settings, cfname, false);
630 if (!data || !message.empty())
631 return message;
632
633 // Write XML data
634 auto length = CFDataGetLength(data.get());
635 if (f.Write(CFDataGetBytePtr(data.get()), length) != length || f.Error())
636 return XO("Failed to write XML preset to \"%s\"").Format(path);
637
638 f.Close();
639 return {};
640}
641
643 AudioUnitEffectSettings &settings, const wxString & path) const
644{
645 // Open the preset
646 wxFFile f(path, wxT("r"));
647 if (!f.IsOpened())
648 return XO("Couldn't open \"%s\"").Format(path);
649
650 // Load it into the buffer
651 size_t len = f.Length();
652 wxMemoryBuffer buf(len);
653 if (f.Read(buf.GetData(), len) != len || f.Error())
654 return XO("Unable to read the preset from \"%s\"").Format(path);
655 buf.SetDataLen(len);
656
657 const auto error = InterpretBlob(settings, path, buf);
658 if (!error.empty())
659 return error;
660
661 return {};
662}
663
665{
666 // Does AU have channel info
668 if (GetVariableSizeProperty(kAudioUnitProperty_SupportedNumChannels, info)) {
669 // None supplied. Apparently all FX type units can do any number of INs
670 // and OUTs as long as they are the same number. In this case, we'll
671 // just say stereo.
672 //
673 // We should probably check to make sure we're dealing with an FX type.
674 mAudioIns = 2;
675 mAudioOuts = 2;
676 return;
677 }
678
679 // This is where it gets weird...not sure what is the best
680 // way to do this really. If we knew how many ins/outs we
681 // really needed, we could make a better choice.
682
683 bool haven2m = false; // nothing -> mono
684 bool haven2s = false; // nothing -> stereo
685 bool havem2n = false; // mono -> nothing
686 bool haves2n = false; // stereo -> nothing
687 bool havem2m = false; // mono -> mono
688 bool haves2s = false; // stereo -> stereo
689 bool havem2s = false; // mono -> stereo
690 bool haves2m = false; // stereo -> mono
691
692 mAudioIns = 2;
693 mAudioOuts = 2;
694
695 // Look only for exact channel constraints
696 for (auto &ci : info) {
697 int ic = ci.inChannels;
698 int oc = ci.outChannels;
699
700 if (ic < 0 && oc >= 0)
701 ic = 2;
702 else if (ic >= 0 && oc < 0)
703 oc = 2;
704 else if (ic < 0 && oc < 0) {
705 ic = 2;
706 oc = 2;
707 }
708
709 if (ic == 2 && oc == 2)
710 haves2s = true;
711 else if (ic == 1 && oc == 1)
712 havem2m = true;
713 else if (ic == 1 && oc == 2)
714 havem2s = true;
715 else if (ic == 2 && oc == 1)
716 haves2m = true;
717 else if (ic == 0 && oc == 2)
718 haven2s = true;
719 else if (ic == 0 && oc == 1)
720 haven2m = true;
721 else if (ic == 1 && oc == 0)
722 havem2n = true;
723 else if (ic == 2 && oc == 0)
724 haves2n = true;
725 }
726
727 if (haves2s) {
728 mAudioIns = 2;
729 mAudioOuts = 2;
730 }
731 else if (havem2m) {
732 mAudioIns = 1;
733 mAudioOuts = 1;
734 }
735 else if (havem2s) {
736 mAudioIns = 1;
737 mAudioOuts = 2;
738 }
739 else if (haves2m) {
740 mAudioIns = 2;
741 mAudioOuts = 1;
742 }
743 else if (haven2m) {
744 mAudioIns = 0;
745 mAudioOuts = 1;
746 }
747 else if (haven2s) {
748 mAudioIns = 0;
749 mAudioOuts = 2;
750 }
751 else if (haves2n) {
752 mAudioIns = 2;
753 mAudioOuts = 0;
754 }
755 else if (havem2n) {
756 mAudioIns = 1;
757 mAudioOuts = 0;
758 }
759
760 return;
761}
762#endif
wxT("CloseDown"))
@ Internal
Indicates internal failure from Audacity.
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
constexpr auto OptionsKey
constexpr auto UseLatencyKey
constexpr auto PresetStr
#define PRESET_KEY
#define PRESET_USER_PATH
constexpr auto UITypeKey
#define AUDIOUNITEFFECTS_FAMILY
static const auto FullValue
static const AudacityProject::AttachedObjects::RegisteredFactory key
const TranslatableString name
Definition: Distortion.cpp:82
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
EffectType
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeNone
@ EffectTypeProcess
wxString RegistryPath
Definition: Identifier.h:218
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
wxString FilePath
Definition: Project.h:20
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
Definition: SelectFile.cpp:17
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:87
static const auto fn
An Effect class that handles a wide range of effects. ??Mac only??
bool HasOptions() override
TranslatableString SaveBlobToConfig(const RegistryPath &group, const wxString &path, const void *blob, size_t len, bool allowEmpty=true) const
bool CloseUI() override
bool SaveUserPreset(const RegistryPath &name, const EffectSettings &settings) const override
Save settings in the configuration file as a user-named preset.
bool IsDefault() const override
Whether the effect sorts "above the line" in the menus.
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
static RegistryPath ChoosePresetKey(const EffectSettings &settings)
static RegistryPath FindPresetKey(const CommandParameters &parms)
PluginPath GetPath() const override
RegistryPaths GetFactoryPresets() const override
Report names of factory presets.
EffectType GetType() const override
Type determines how it behaves.
OptionalMessage ImportPresets(EffectSettings &settings) override
void ShowOptions() override
TranslatableString Export(const AudioUnitEffectSettings &settings, const wxString &path) const
int ShowClientInterface(wxWindow &parent, wxDialog &dialog, EffectUIValidator *pValidator, bool forceModal) override
TranslatableString GetDescription() const override
OptionalMessage LoadFactoryPreset(int id, EffectSettings &settings) const override
std::unique_ptr< EffectUIValidator > PopulateUI(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Adds controls to a panel that is given as the parent window of S
EffectSettings MakeSettings() const override
bool CanExportPresets() override
virtual ~AudioUnitEffect()
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
wxWindow * mParent
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
bool MigrateOldConfigFile(const RegistryPath &group, EffectSettings &settings) const
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
May allocate memory, so should be called only in the main thread.
const wxString mName
bool CopySettingsContents(const EffectSettings &src, EffectSettings &dst) const override
Update one settings object from another.
bool SupportsAutomation() const override
Whether the effect has any automatable controls.
TranslatableString Import(AudioUnitEffectSettings &settings, const wxString &path) const
OptionalMessage LoadPreset(const RegistryPath &group, EffectSettings &settings) const
wxString GetVersion() const override
const wxString mVendor
AudioUnitEffect(const PluginPath &path, const wxString &name, AudioComponent component, Parameters *pParameters=nullptr, AudioUnitEffect *master=nullptr)
OptionalMessage LoadUserPreset(const RegistryPath &name, EffectSettings &settings) const override
void ExportPresets(const EffectSettings &settings) const override
bool SavePreset(const RegistryPath &group, const AudioUnitEffectSettings &settings) const
VendorSymbol GetVendor() const override
const PluginPath mPath
ComponentInterfaceSymbol GetSymbol() const override
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
static std::unique_ptr< EffectUIValidator > Create(EffectUIClientInterface &effect, ShuttleGui &S, const wxString &uiType, EffectInstance &instance, EffectSettingsAccess &access)
static std::optional< AudioUnitParameterID > ParseKey(const wxString &key)
Recover the parameter ID from the key, if well formed.
AudioUnitUtils::ParameterInfo mInfo
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool SetParameters(const wxString &parms)
TranslatableString GetName() const
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
RealtimeSince
In which versions of Audacity was an effect realtime capable?
Performs effect computation.
virtual size_t GetTailSize() const
Hold values to send to effect output meters.
Interface for transferring values from a panel of effect controls.
Abstract base class used in importing a file.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
Holds a msgid for the translation catalog; may also bind format arguments.
size_t Count(const Ptr< Type, BaseDeleter > &p)
Find out how many elements were allocated with a Ptr.
Definition: PackedArray.h:143
bool SetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, const Value &value)
bool RemoveConfig(const EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group, const RegistryPath &key)
bool GetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, Value &var, const Value &defval)
std::pair< const char *, const char * > Pair
Common base class for AudioUnitEffect and its Instance.
Parameters & mParameters
bool LoadPreset(const EffectDefinitionInterface &effect, const RegistryPath &group, EffectSettings &settings) const
bool LoadFactoryPreset(const EffectDefinitionInterface &effect, int id, EffectSettings *pSettings) const
OSStatus GetFixedSizeProperty(AudioUnitPropertyID inID, T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
OSStatus GetVariableSizeProperty(AudioUnitPropertyID inID, PackedArray::Ptr< T > &pObject, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
TranslatableString InterpretBlob(AudioUnitEffectSettings &settings, const wxString &group, const wxMemoryBuffer &buf) const
Interpret the dump made before by MakeBlob.
bool SetRateAndChannels(double sampleRate, const wxString &identifier)
static AudioUnitEffectSettings & GetSettings(EffectSettings &settings)
const AudioComponent mComponent
std::pair< CF_ptr< CFDataRef >, TranslatableString > MakeBlob(const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings, const wxCFStringRef &cfname, bool binary) const
Obtain dump of the setting state of an AudioUnit instance.
void ForEachParameter(ParameterVisitor visitor) const
bool FetchSettings(AudioUnitEffectSettings &settings, bool fetchValues, bool fetchPreset=false) const
May allocate memory, so should be called only in the main thread.
Externalized state of a plug-in.