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 "AudioUnitEditor.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/control.h>
29#include <wx/crt.h>
30#include <wx/dir.h>
31#include <wx/ffile.h>
32
33#ifdef __WXMAC__
34#include <wx/evtloop.h>
35#endif
36
37#include <wx/filename.h>
38#include <wx/frame.h>
39#include <wx/listctrl.h>
40#include <wx/log.h>
41#include <wx/settings.h>
42#include <wx/stattext.h>
43#include <wx/textctrl.h>
44#include <wx/osx/core/private.h>
45
46#include "SelectFile.h"
47#include "ShuttleGui.h"
48#include "AudacityMessageBox.h"
49#include "../../widgets/valnum.h"
50
51//
52// When a plug-in's state is saved to the settings file (as a preset),
53// it is in binary and gets base64 encoded before storing.
54//
55// When exporting, save as XML without base64 encoding.
56//
57// The advantages of XML format is less chance of failures occurring
58// when exporting. But, it can take a bit more space per preset int
59// the Audacity settings file.
60//
61// Using binary for now. Use kCFPropertyListXMLFormat_v1_0 if XML
62// format is desired.
63//
64#define PRESET_FORMAT kCFPropertyListBinaryFormat_v1_0
65
66// Name of the settings key to use for the above value
67#define PRESET_KEY wxT("Data")
68
69// Where the presets are located
70#define PRESET_LOCAL_PATH wxT("/Library/Audio/Presets")
71#define PRESET_USER_PATH wxT("~/Library/Audio/Presets")
72
74 const RegistryPath &group, const wxString &path,
75 const void *blob, size_t len, bool allowEmpty) const
76{
77 // Base64 encode the returned binary property list
78 auto parms = wxBase64Encode(blob, len);
79 if (!allowEmpty && parms.IsEmpty())
80 return XO("Failed to encode preset from \"%s\"").Format(path);
81
82 // And write it to the config
83 if (!SetConfig(*this, PluginSettings::Private, group, PRESET_KEY, parms))
84 return XO("Unable to store preset in config file");
85 return {};
86}
87
89//
90// AudioUnitEffect
91//
93
95 const wxString & name, AudioComponent component,
96 Parameters *pParameters, AudioUnitEffect *master
97) : AudioUnitWrapper{ component, pParameters }
98 , mPath{ path }
99 , mName{ name.AfterFirst(wxT(':')).Trim(true).Trim(false) }
100 , mVendor{ name.BeforeFirst(wxT(':')).Trim(true).Trim(false) }
101{
102}
103
105{
106}
107
108// ============================================================================
109// ComponentInterface implementation
110// ============================================================================
111
113{
114 return mPath;
115}
116
118{
119 return mName;
120}
121
123{
124 return { mVendor };
125}
126
128{
129 UInt32 version;
130
131 OSStatus result = AudioComponentGetVersion(mComponent, &version);
132
133 return wxString::Format(wxT("%d.%d.%d"),
134 (version >> 16) & 0xffff,
135 (version >> 8) & 0xff,
136 version & 0xff);
137}
138
140{
141 /* i18n-hint: Can mean "not available," "not applicable," "no answer" */
142 return XO("n/a");
143}
144
145// ============================================================================
146// EffectDefinitionInterface implementation
147// ============================================================================
148
150{
151 if (mAudioIns == 0 && mAudioOuts == 0)
152 {
153 return EffectTypeNone;
154 }
155
156 if (mAudioIns == 0)
157 {
158 return EffectTypeGenerate;
159 }
160
161 if (mAudioOuts == 0)
162 {
163 return EffectTypeAnalyze;
164 }
165
166 return EffectTypeProcess;
167}
168
170{
172}
173
175{
176 return mInteractive;
177}
178
180{
181 return false;
182}
183
185{
186 return GetType() == EffectTypeProcess
189}
190
192{
193 bool supports = false;
195 [&supports](const ParameterInfo &pi, AudioUnitParameterID) {
196 if (pi.mInfo.flags & kAudioUnitParameterFlag_IsWritable)
197 supports = true;
198 // Search only until we find one, that's all we need to know
199 return !supports;
200 });
201 return supports;
202}
203
204std::shared_ptr<EffectInstance> AudioUnitEffect::MakeInstance() const
205{
206 bool useLatency;
208 useLatency, true);
209
210 return std::make_shared<AudioUnitInstance>(*this, mComponent, mParameters,
211 GetSymbol().Internal(), mAudioIns, mAudioOuts, useLatency);
212}
213
215{
216 // To implement the services of EffectPlugin -- such as, a query of the
217 // set of effect parameters, so that we can implement MakeSettings -- we
218 // also need what is called an AudioComponentInstance, also called an
219 // AudioUnit.
220 // It's not just for implementing EffectInstance. AudioUnits is unlike other
221 // third party effect families that distinguish the notions of plug-in and
222 // instance.
223
225
226 if (!CreateAudioUnit())
227 return false;
228
229 // Use an arbitrary rate while completing the discovery of channel support
230 if (!SetRateAndChannels(44100.0, GetSymbol().Internal()))
231 return false;
232
233 // Determine interactivity
235 if (!mInteractive) {
236 // Check for a Cocoa UI
237 // This could retrieve a variable-size property, but we only look at
238 // the first element.
239 AudioUnitCocoaViewInfo cocoaViewInfo;
241 !GetFixedSizeProperty(kAudioUnitProperty_CocoaUI, cocoaViewInfo);
242 if (!mInteractive) {
243 // Check for a Carbon UI
244 // This could retrieve a variable sized array but we only need the
245 // first
246 AudioComponentDescription compDesc;
248 kAudioUnitProperty_GetUIComponentList, compDesc);
249 }
250 }
251
252 return true;
253}
254
255#if 0
257{
258 // Retrieve the tail time
259 Float64 tailTime = 0.0;
260 if (!GetFixedSizeProperty(kAudioUnitProperty_TailTime, tailTime))
261 return tailTime * mSampleRate;
262 return 0;
263}
264#endif
265
267 wxWindow &parent, wxDialog &dialog,
268 EffectEditor *, bool forceModal) const
269{
270 if ((SupportsRealtime() || GetType() == EffectTypeAnalyze) && !forceModal) {
271 dialog.Show();
272 return 0;
273 }
274 return dialog.ShowModal();
275}
276
277// Don't use the template-generated MakeSettings(), which default-constructs
278// the structure. Instead allocate a number of values chosen by the plug-in
280{
282 FetchSettings(settings, true);
283 return EffectSettings::Make<AudioUnitEffectSettings>(std::move(settings));
284}
285
287 const EffectSettings &, EffectSettings &) const
288{
289 // Not needed -- rely on EffectInstance::Message instead
290 return true;
291}
292
293constexpr auto PresetStr = "_PRESET";
294
297{
298 // Find a key to use for the preset that does not collide with any
299 // parameter name
300 wxString result = PresetStr;
301
302 // That string probably works but be sure
303 const auto &map = GetSettings(settings).values;
304 using Pair = decltype(*map.begin());
305 while (std::any_of(map.begin(), map.end(), [&](Pair &pair){
306 return pair.second && pair.second->first == result;
307 }))
308 result += "_";
309
310 return result;
311}
312
314{
315 RegistryPath result;
316 auto len = strlen(PresetStr);
317 if (auto [index, key] = std::tuple(0L, wxString{})
318 ; parms.GetFirstEntry(key, index)
319 ) do {
320 if (key.StartsWith(PresetStr)
321 && key.Mid(len).find_first_not_of("_") == wxString::npos
322 && key.length() > result.length())
323 result = key;
324 } while(parms.GetNextEntry(key, index));
325 return result;
326}
327
329 const EffectSettings &settings, CommandParameters & parms) const
330{
331 const auto &mySettings = GetSettings(settings);
332 if (mySettings.mPresetNumber) {
333 const auto key = ChoosePresetKey(settings);
334 parms.Write(key, *mySettings.mPresetNumber);
335 }
336
337 // Save settings into CommandParameters
338 // Iterate the map only, not using any AudioUnit handles
339 for (auto &[ID, pPair] : mySettings.values)
340 if (pPair)
341 // Write names, not numbers, as keys in the config file
342 parms.Write(pPair->first, pPair->second);
343 return true;
344}
345
347 const CommandParameters & parms, EffectSettings &settings) const
348{
349 // First clean all settings, in case any are not defined in parms
350 auto &mySettings = GetSettings(settings);
351 mySettings.ResetValues();
352 auto &map = mySettings.values;
353
354 // Reload preset first
355 if (auto presetKey = FindPresetKey(parms); !presetKey.empty()) {
356 SInt32 value = 0;
357 if (parms.Read(presetKey, &value))
359 }
360
361 // Load settings from CommandParameters
362 // Iterate the config only, not using any AudioUnit handles
363 if (auto [index, key, value] = std::tuple(
364 0L, wxString{}, AudioUnitParameterValue{})
365 ; parms.GetFirstEntry(key, index)
366 ) do {
367 if (auto pKey = ParameterInfo::ParseKey(key)
368 ; pKey && parms.Read(key, &value)
369 )
370 map[*pKey].emplace(mySettings.Intern(key), value);
371 } while(parms.GetNextEntry(key, index));
372 return true;
373}
374
377{
378 // To do: externalize state so const_cast isn't needed
379 return const_cast<AudioUnitEffect*>(this)->LoadPreset(name, settings);
380}
381
383 const RegistryPath & name, const EffectSettings &settings) const
384{
386}
387
390{
392 return { nullptr };
393 return {};
394}
395
397{
398 RegistryPaths presets;
399
400 // Retrieve the list of factory presets
401 CF_ptr<CFArrayRef> array;
402 if (!GetFixedSizeProperty(kAudioUnitProperty_FactoryPresets, array))
403 for (CFIndex i = 0, cnt = CFArrayGetCount(array.get()); i < cnt; ++i)
404 presets.push_back(wxCFStringRef::AsString(
405 static_cast<const AUPreset*>(CFArrayGetValueAtIndex(array.get(), i))
406 ->presetName));
407 return presets;
408}
409
410std::unique_ptr<EffectEditor> AudioUnitEffect::PopulateUI(
411 const EffectPlugin &, ShuttleGui &S,
412 EffectInstance &instance, EffectSettingsAccess &access,
413 const EffectOutputs *) const
414{
415 wxString uiType;
416 // Decide whether to build plain or fancy user interfaces
418 uiType, FullValue.MSGID().GET() /* Config stores un-localized string */);
419 return AudioUnitEditor::Create(*this, S, uiType, instance, access);
420}
421
422std::unique_ptr<EffectEditor> AudioUnitEffect::MakeEditor(
424 const EffectOutputs *) const
425{
427 assert(false);
428 return nullptr;
429}
430
431#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
432bool AudioUnitEffect::CreatePlain(wxWindow *parent)
433{
434 // TODO??? Never implemented...
435 return false;
436}
437#endif
438
440{
441#ifdef __WXMAC__
442#ifdef __WX_EVTLOOP_BUSY_WAITING__
443 wxEventLoop::SetBusyWaiting(false);
444#endif
445#endif
446 return true;
447}
448
450{
451 return true;
452}
453
455 const EffectPlugin &, const EffectSettings &settings) const
456{
457 // Generate the user domain path
458 wxFileName fn;
459 fn.SetPath(PRESET_USER_PATH);
460 fn.AppendDir(mVendor);
461 fn.AppendDir(mName);
462 fn.Normalize();
463 FilePath path = fn.GetFullPath();
464
465 if (!fn.Mkdir(fn.GetFullPath(), 0755, wxPATH_MKDIR_FULL)) {
466 wxLogError(wxT("Couldn't create the \"%s\" directory"), fn.GetPath());
467 return;
468 }
469
470 // Ask the user for the name to use
471 //
472 // Passing a valid parent will cause some effects dialogs to malfunction
473 // upon returning from the SelectFile().
474 path = SelectFile(FileNames::Operation::_None,
475 XO("Export Audio Unit Preset As %s:").Format(fn.GetFullPath()),
476 fn.GetFullPath(),
477 wxEmptyString,
478 wxT("aupreset"),
479 {
480 { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
481 },
482 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
483 NULL);
484
485 // User canceled...
486 if (path.empty())
487 return;
488
489 auto msg = Export(GetSettings(settings), path);
490 if (!msg.empty())
492 XO("Could not export \"%s\" preset\n\n%s").Format(path, msg),
493 XO("Export Audio Unit Presets"),
494 wxOK | wxCENTRE);
495}
496
498 const EffectPlugin &, EffectSettings &settings) const
499{
500 // Generate the user domain path
501 wxFileName fn;
502 fn.SetPath(PRESET_USER_PATH);
503 fn.AppendDir(mVendor);
504 fn.AppendDir(mName);
505 fn.Normalize();
506 FilePath path = fn.GetFullPath();
507
508 // Ask the user for the name to use
509 //
510 // Passing a valid parent will cause some effects dialogs to malfunction
511 // upon returning from the SelectFile().
512 path = SelectFile(FileNames::Operation::_None,
513 XO("Import Audio Unit Preset As %s:").Format(fn.GetFullPath()),
514 fn.GetFullPath(), wxEmptyString, wxT("aupreset"),
515 {
516 { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
517 },
518 wxFD_OPEN | wxRESIZE_BORDER,
519 nullptr);
520
521 // User canceled...
522 if (path.empty())
523 return {};
524
525 auto msg = Import(GetSettings(settings), path);
526 if (!msg.empty()) {
528 XO("Could not import \"%s\" preset\n\n%s").Format(path, msg),
529 XO("Import Audio Unit Presets"),
530 wxOK | wxCENTRE);
531 return {};
532 }
533
534 return { nullptr };
535}
536
538{
539 return true;
540}
541
543{
544 AudioUnitEffectOptionsDialog{ *this }.ShowModal();
545}
546
547// ============================================================================
548// AudioUnitEffect Implementation
549// ============================================================================
550
552 const RegistryPath & group, EffectSettings &settings) const
553{
554 // Migration of very old format configuration file, should not normally
555 // happen and perhaps this code can be abandoned
556 // Attempt to load old preset parameters and resave using new method
557 constexpr auto oldKey = L"Parameters";
558 wxString parms;
560 group, oldKey, parms, wxEmptyString)) {
562 if (eap.SetParameters(parms))
563 if (LoadSettings(eap, settings))
564 if (SavePreset(group, GetSettings(settings)))
565 RemoveConfig(*this, PluginSettings::Private, group, oldKey);
566 return true;
567 }
568 return false;
569}
570
572 const RegistryPath & group, EffectSettings &settings) const
573{
574 if (MigrateOldConfigFile(group, settings))
575 return { nullptr };
576
577 if (AudioUnitWrapper::LoadPreset(*this, group, settings))
578 return { nullptr };
579 return {};
580}
581
583 const RegistryPath & group, const AudioUnitEffectSettings &settings) const
584{
585 wxCFStringRef cfname(wxFileNameFromPath(group));
586 const auto &[data, _] = MakeBlob(*this, settings, cfname, true);
587 if (!data)
588 return false;
589
590 // Nothing to do if we don't have any data
591 if (const auto length = CFDataGetLength(data.get())) {
592 auto error =
593 SaveBlobToConfig(group, {}, CFDataGetBytePtr(data.get()), length);
594 if (!error.empty())
595 return false;
596 }
597 return true;
598}
599
601 const AudioUnitEffectSettings &settings, const wxString & path) const
602{
603 // Create the file
604 wxFFile f(path, wxT("wb"));
605 if (!f.IsOpened())
606 return XO("Couldn't open \"%s\"").Format(path);
607
608 // First set the name of the preset
609 wxCFStringRef cfname(wxFileName(path).GetName());
610
611 const auto &[data, message] = MakeBlob(*this, settings, cfname, false);
612 if (!data || !message.empty())
613 return message;
614
615 // Write XML data
616 auto length = CFDataGetLength(data.get());
617 if (f.Write(CFDataGetBytePtr(data.get()), length) != length || f.Error())
618 return XO("Failed to write XML preset to \"%s\"").Format(path);
619
620 f.Close();
621 return {};
622}
623
625 AudioUnitEffectSettings &settings, const wxString & path) const
626{
627 // Open the preset
628 wxFFile f(path, wxT("r"));
629 if (!f.IsOpened())
630 return XO("Couldn't open \"%s\"").Format(path);
631
632 // Load it into the buffer
633 size_t len = f.Length();
634 wxMemoryBuffer buf(len);
635 if (f.Read(buf.GetData(), len) != len || f.Error())
636 return XO("Unable to read the preset from \"%s\"").Format(path);
637 buf.SetDataLen(len);
638
639 const auto error = InterpretBlob(settings, path, buf);
640 if (!error.empty())
641 return error;
642
643 return {};
644}
645
647{
648 // Does AU have channel info
650 if (GetVariableSizeProperty(kAudioUnitProperty_SupportedNumChannels, info)) {
651 // None supplied. Apparently all FX type units can do any number of INs
652 // and OUTs as long as they are the same number. In this case, we'll
653 // just say stereo.
654 //
655 // We should probably check to make sure we're dealing with an FX type.
656 mAudioIns = 2;
657 mAudioOuts = 2;
658 return;
659 }
660
661 // This is where it gets weird...not sure what is the best
662 // way to do this really. If we knew how many ins/outs we
663 // really needed, we could make a better choice.
664
665 bool haven2m = false; // nothing -> mono
666 bool haven2s = false; // nothing -> stereo
667 bool havem2n = false; // mono -> nothing
668 bool haves2n = false; // stereo -> nothing
669 bool havem2m = false; // mono -> mono
670 bool haves2s = false; // stereo -> stereo
671 bool havem2s = false; // mono -> stereo
672 bool haves2m = false; // stereo -> mono
673
674 mAudioIns = 2;
675 mAudioOuts = 2;
676
677 // Look only for exact channel constraints
678 for (auto &ci : info) {
679 int ic = ci.inChannels;
680 int oc = ci.outChannels;
681
682 if (ic < 0 && oc >= 0)
683 ic = 2;
684 else if (ic >= 0 && oc < 0)
685 oc = 2;
686 else if (ic < 0 && oc < 0) {
687 ic = 2;
688 oc = 2;
689 }
690
691 if (ic == 2 && oc == 2)
692 haves2s = true;
693 else if (ic == 1 && oc == 1)
694 havem2m = true;
695 else if (ic == 1 && oc == 2)
696 havem2s = true;
697 else if (ic == 2 && oc == 1)
698 haves2m = true;
699 else if (ic == 0 && oc == 2)
700 haven2s = true;
701 else if (ic == 0 && oc == 1)
702 haven2m = true;
703 else if (ic == 1 && oc == 0)
704 havem2n = true;
705 else if (ic == 2 && oc == 0)
706 haves2n = true;
707 }
708
709 if (haves2s) {
710 mAudioIns = 2;
711 mAudioOuts = 2;
712 }
713 else if (havem2m) {
714 mAudioIns = 1;
715 mAudioOuts = 1;
716 }
717 else if (havem2s) {
718 mAudioIns = 1;
719 mAudioOuts = 2;
720 }
721 else if (haves2m) {
722 mAudioIns = 2;
723 mAudioOuts = 1;
724 }
725 else if (haven2m) {
726 mAudioIns = 0;
727 mAudioOuts = 1;
728 }
729 else if (haven2s) {
730 mAudioIns = 0;
731 mAudioOuts = 2;
732 }
733 else if (haves2n) {
734 mAudioIns = 2;
735 mAudioOuts = 0;
736 }
737 else if (havem2n) {
738 mAudioIns = 1;
739 mAudioOuts = 0;
740 }
741
742 return;
743}
744#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 PresetStr
#define PRESET_KEY
#define PRESET_USER_PATH
#define AUDIOUNITEFFECTS_FAMILY
static const auto FullValue
constexpr auto OptionsKey
constexpr auto UseLatencyKey
constexpr auto UITypeKey
static const AudacityProject::AttachedObjects::RegisteredFactory key
const TranslatableString name
Definition: Distortion.cpp:76
EffectType
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeNone
@ EffectTypeProcess
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
XO("Cut/Copy/Paste")
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 _(s)
Definition: Internat.h:73
wxString FilePath
Definition: Project.h:21
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
static std::unique_ptr< EffectEditor > Create(const EffectUIServices &effect, ShuttleGui &S, const wxString &uiType, EffectInstance &instance, EffectSettingsAccess &access)
An Effect class that handles a wide range of effects. ??Mac only??
bool HasOptions() const override
TranslatableString SaveBlobToConfig(const RegistryPath &group, const wxString &path, const void *blob, size_t len, bool allowEmpty=true) const
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)
bool CanExportPresets() const override
Whether the effect supports export of presets to files, and importing too.
PluginPath GetPath() const override
RegistryPaths GetFactoryPresets() const override
Report names of factory presets.
EffectType GetType() const override
Type determines how it behaves.
void ExportPresets(const EffectPlugin &plugin, const EffectSettings &settings) const override
virtual std::unique_ptr< EffectEditor > MakeEditor(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const final
Will never be called.
TranslatableString Export(const AudioUnitEffectSettings &settings, const wxString &path) const
TranslatableString GetDescription() const override
OptionalMessage LoadFactoryPreset(int id, EffectSettings &settings) const override
EffectSettings MakeSettings() const override
virtual ~AudioUnitEffect()
std::unique_ptr< EffectEditor > PopulateUI(const EffectPlugin &plugin, ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const override
Adds controls to a panel that is given as the parent window of S
void ShowOptions(const EffectPlugin &plugin) const override
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
OptionalMessage ImportPresets(const EffectPlugin &plugin, EffectSettings &settings) const override
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
int ShowClientInterface(const EffectPlugin &plugin, wxWindow &parent, wxDialog &dialog, EffectEditor *pEditor, bool forceModal) const override
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.
bool CloseUI() const override
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
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::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.
Factory of instances of an effect.
Definition: EffectPlugin.h:36
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:625
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.