25#include <wx/osx/core/private.h>
40#define PRESET_FORMAT kCFPropertyListBinaryFormat_v1_0
43#define PRESET_KEY wxT("Data")
46#define PRESET_LOCAL_PATH wxT("/Library/Audio/Presets")
47#define PRESET_USER_PATH wxT("~/Library/Audio/Presets")
51 const void *blob,
size_t len,
bool allowEmpty)
const
54 auto parms = wxBase64Encode(blob, len);
55 if (!allowEmpty && parms.IsEmpty())
56 return XO(
"Failed to encode preset from \"%s\"").Format(path);
60 return XO(
"Unable to store preset in config file");
71 const wxString &
name, AudioComponent component,
75 , mName{
name.AfterFirst(
wxT(
':')).Trim(true).Trim(false) }
76 , mVendor{
name.BeforeFirst(
wxT(
':')).Trim(true).Trim(false) }
105 OSStatus result = AudioComponentGetVersion(
mComponent, &version);
107 return wxString::Format(
wxT(
"%d.%d.%d"),
108 (version >> 16) & 0xffff,
109 (version >> 8) & 0xff,
167 bool supports =
false;
170 if (
pi.mInfo.flags & kAudioUnitParameterFlag_IsWritable)
213 AudioUnitCocoaViewInfo cocoaViewInfo;
220 AudioComponentDescription compDesc;
222 kAudioUnitProperty_GetUIComponentList, compDesc);
233 Float64 tailTime = 0.0;
235 return tailTime * mSampleRate;
246 return EffectSettings::Make<AudioUnitEffectSettings>(std::move(
settings));
267 using Pair =
decltype(*map.begin());
268 while (std::any_of(map.begin(), map.end(), [&](
Pair &pair){
269 return pair.second && pair.second->first == result;
280 if (
auto [index,
key] = std::tuple(0L, wxString{})
281 ; parms.GetFirstEntry(
key, index)
285 &&
key.length() > result.length())
287 }
while(parms.GetNextEntry(
key, index));
295 if (mySettings.mPresetNumber) {
297 parms.Write(
key, *mySettings.mPresetNumber);
302 for (
auto &[ID, pPair] : mySettings.values)
305 parms.Write(pPair->first, pPair->second);
314 mySettings.ResetValues();
315 auto &map = mySettings.values;
318 if (
auto presetKey =
FindPresetKey(parms); !presetKey.empty()) {
320 if (parms.Read(presetKey, &value))
326 if (
auto [index,
key, value] = std::tuple(
327 0L, wxString{}, AudioUnitParameterValue{})
328 ; parms.GetFirstEntry(
key, index)
331 ; pKey && parms.Read(
key, &value)
333 map[*pKey].emplace(mySettings.Intern(
key), value);
334 }
while(parms.GetNextEntry(
key, index));
364 CF_ptr<CFArrayRef> array;
366 for (CFIndex i = 0, cnt = CFArrayGetCount(array.get()); i < cnt; ++i)
367 presets.push_back(wxCFStringRef::AsString(
368 static_cast<const AUPreset*
>(CFArrayGetValueAtIndex(array.get(), i))
393 constexpr auto oldKey = L
"Parameters";
396 group, oldKey, parms, wxEmptyString)) {
421 wxCFStringRef cfname(wxFileNameFromPath(group));
427 if (
const auto length = CFDataGetLength(data.get())) {
440 wxFFile f(path,
wxT(
"wb"));
442 return XO(
"Couldn't open \"%s\"").Format(path);
445 wxCFStringRef cfname(wxFileName(path).
GetName());
448 if (!data || !message.empty())
452 auto length = CFDataGetLength(data.get());
453 if (f.Write(CFDataGetBytePtr(data.get()), length) != length || f.Error())
454 return XO(
"Failed to write XML preset to \"%s\"").Format(path);
464 wxFFile f(path,
wxT(
"r"));
466 return XO(
"Couldn't open \"%s\"").Format(path);
469 size_t len = f.Length();
470 wxMemoryBuffer buf(len);
471 if (f.Read(buf.GetData(), len) != len || f.Error())
472 return XO(
"Unable to read the preset from \"%s\"").Format(path);
501 bool haven2m =
false;
502 bool haven2s =
false;
503 bool havem2n =
false;
504 bool haves2n =
false;
505 bool havem2m =
false;
506 bool haves2s =
false;
507 bool havem2s =
false;
508 bool haves2m =
false;
514 for (
auto &ci : info) {
515 int ic = ci.inChannels;
516 int oc = ci.outChannels;
518 if (ic < 0 && oc >= 0)
520 else if (ic >= 0 && oc < 0)
522 else if (ic < 0 && oc < 0) {
527 if (ic == 2 && oc == 2)
529 else if (ic == 1 && oc == 1)
531 else if (ic == 1 && oc == 2)
533 else if (ic == 2 && oc == 1)
535 else if (ic == 0 && oc == 2)
537 else if (ic == 0 && oc == 1)
539 else if (ic == 1 && oc == 0)
541 else if (ic == 2 && oc == 0)
@ Internal
Indicates internal failure from Audacity.
constexpr auto OptionsKey
constexpr auto UseLatencyKey
#define AUDIOUNITEFFECTS_FAMILY
std::optional< std::unique_ptr< EffectSettingsAccess::Message > > OptionalMessage
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
std::vector< RegistryPath > RegistryPaths
static Settings & settings()
An Effect class that handles a wide range of effects. ??Mac only??
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
bool IsDefault() const override
Whether the effect sorts "above the line" in the menus.
static RegistryPath FindPresetKey(const CommandParameters &parms)
TranslatableString SaveBlobToConfig(const RegistryPath &group, const wxString &path, const void *blob, size_t len, bool allowEmpty=true) const
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
bool SupportsAutomation() const override
Whether the effect has any automatable controls.
TranslatableString GetDescription() const override
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
TranslatableString Export(const AudioUnitEffectSettings &settings, const wxString &path) const
OptionalMessage LoadFactoryPreset(int id, EffectSettings &settings) const override
PluginPath GetPath() const override
EffectSettings MakeSettings() const override
TranslatableString Import(AudioUnitEffectSettings &settings, const wxString &path) const
bool SavePreset(const RegistryPath &group, const AudioUnitEffectSettings &settings) const
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
May allocate memory, so should be called only in the main thread.
ComponentInterfaceSymbol GetSymbol() const override
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
bool SaveUserPreset(const RegistryPath &name, const EffectSettings &settings) const override
Save settings in the configuration file as a user-named preset.
AudioUnitEffectBase(const PluginPath &path, const wxString &name, AudioComponent component, Parameters *pParameters=nullptr, AudioUnitEffectBase *master=nullptr)
EffectType GetType() const override
Type determines how it behaves.
wxString GetVersion() const override
OptionalMessage LoadPreset(const RegistryPath &group, EffectSettings &settings) const
VendorSymbol GetVendor() const override
static RegistryPath ChoosePresetKey(const EffectSettings &settings)
bool MigrateOldConfigFile(const RegistryPath &group, EffectSettings &settings) const
OptionalMessage LoadUserPreset(const RegistryPath &name, EffectSettings &settings) const override
bool HasOptions() const override
bool CopySettingsContents(const EffectSettings &src, EffectSettings &dst) const override
Update one settings object from another.
bool CanExportPresets() const override
Whether the effect supports export of presets to files, and importing too.
RegistryPaths GetFactoryPresets() const override
Report names of factory presets.
~AudioUnitEffectBase() override
Encapsulates parameter information for an AudioUnit.
static std::optional< AudioUnitParameterID > ParseKey(const wxString &key)
Recover the parameter ID from the key, if well formed.
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?
virtual size_t GetTailSize() const
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.
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)
constexpr size_t npos(-1)
std::pair< const char *, const char * > Pair
Represents a cached copy of the state stored in an AudioUnit, but can outlive the original AudioUnit.
Manages and interacts with an AudioUnit, providing operations on audio effects.
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.