28#include <wx/control.h>
34#include <wx/evtloop.h>
37#include <wx/filename.h>
39#include <wx/listctrl.h>
41#include <wx/settings.h>
42#include <wx/stattext.h>
43#include <wx/textctrl.h>
44#include <wx/osx/core/private.h>
49#include "../../widgets/valnum.h"
64#define PRESET_FORMAT kCFPropertyListBinaryFormat_v1_0
67#define PRESET_KEY wxT("Data")
70#define PRESET_LOCAL_PATH wxT("/Library/Audio/Presets")
71#define PRESET_USER_PATH wxT("~/Library/Audio/Presets")
75 const void *blob,
size_t len,
bool allowEmpty)
const
78 auto parms = wxBase64Encode(blob, len);
79 if (!allowEmpty && parms.IsEmpty())
80 return XO(
"Failed to encode preset from \"%s\"").Format(path);
84 return XO(
"Unable to store preset in config file");
95 const wxString &
name, AudioComponent component,
99 , mName{
name.AfterFirst(
wxT(
':')).Trim(true).Trim(false) }
100 , mVendor{
name.BeforeFirst(
wxT(
':')).Trim(true).Trim(false) }
131 OSStatus result = AudioComponentGetVersion(
mComponent, &version);
133 return wxString::Format(
wxT(
"%d.%d.%d"),
134 (version >> 16) & 0xffff,
135 (version >> 8) & 0xff,
193 bool supports =
false;
196 if (pi.
mInfo.flags & kAudioUnitParameterFlag_IsWritable)
239 AudioUnitCocoaViewInfo cocoaViewInfo;
246 AudioComponentDescription compDesc;
248 kAudioUnitProperty_GetUIComponentList, compDesc);
259 Float64 tailTime = 0.0;
261 return tailTime * mSampleRate;
267 wxWindow &parent, wxDialog &dialog,
274 return dialog.ShowModal();
283 return EffectSettings::Make<AudioUnitEffectSettings>(std::move(
settings));
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;
317 if (
auto [index,
key] = std::tuple(0L, wxString{})
318 ; parms.GetFirstEntry(
key, index)
321 &&
key.Mid(len).find_first_not_of(
"_") == wxString::npos
322 &&
key.length() > result.length())
324 }
while(parms.GetNextEntry(
key, index));
332 if (mySettings.mPresetNumber) {
334 parms.Write(
key, *mySettings.mPresetNumber);
339 for (
auto &[ID, pPair] : mySettings.values)
342 parms.Write(pPair->first, pPair->second);
351 mySettings.ResetValues();
352 auto &map = mySettings.values;
355 if (
auto presetKey =
FindPresetKey(parms); !presetKey.empty()) {
357 if (parms.Read(presetKey, &value))
363 if (
auto [index,
key, value] = std::tuple(
364 0L, wxString{}, AudioUnitParameterValue{})
365 ; parms.GetFirstEntry(
key, index)
368 ; pKey && parms.Read(
key, &value)
370 map[*pKey].emplace(mySettings.Intern(
key), value);
371 }
while(parms.GetNextEntry(
key, index));
401 CF_ptr<CFArrayRef> 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))
431#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
432bool AudioUnitEffect::CreatePlain(wxWindow *parent)
442#ifdef __WX_EVTLOOP_BUSY_WAITING__
443 wxEventLoop::SetBusyWaiting(
false);
465 if (!
fn.Mkdir(
fn.GetFullPath(), 0755, wxPATH_MKDIR_FULL)) {
466 wxLogError(
wxT(
"Couldn't create the \"%s\" directory"),
fn.GetPath());
474 path =
SelectFile(FileNames::Operation::_None,
475 XO(
"Export Audio Unit Preset As %s:").
Format(
fn.GetFullPath()),
480 {
XO(
"Standard Audio Unit preset file"), {
wxT(
"aupreset") },
true },
482 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
492 XO(
"Could not export \"%s\" preset\n\n%s").
Format(path, msg),
493 XO(
"Export Audio Unit Presets"),
512 path =
SelectFile(FileNames::Operation::_None,
513 XO(
"Import Audio Unit Preset As %s:").
Format(
fn.GetFullPath()),
514 fn.GetFullPath(), wxEmptyString,
wxT(
"aupreset"),
516 {
XO(
"Standard Audio Unit preset file"), {
wxT(
"aupreset") },
true },
518 wxFD_OPEN | wxRESIZE_BORDER,
528 XO(
"Could not import \"%s\" preset\n\n%s").
Format(path, msg),
529 XO(
"Import Audio Unit Presets"),
557 constexpr auto oldKey = L
"Parameters";
560 group, oldKey, parms, wxEmptyString)) {
585 wxCFStringRef cfname(wxFileNameFromPath(group));
591 if (
const auto length = CFDataGetLength(data.get())) {
604 wxFFile f(path,
wxT(
"wb"));
606 return XO(
"Couldn't open \"%s\"").Format(path);
609 wxCFStringRef cfname(wxFileName(path).
GetName());
612 if (!data || !message.empty())
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);
628 wxFFile f(path,
wxT(
"r"));
630 return XO(
"Couldn't open \"%s\"").Format(path);
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);
665 bool haven2m =
false;
666 bool haven2s =
false;
667 bool havem2n =
false;
668 bool haves2n =
false;
669 bool havem2m =
false;
670 bool haves2s =
false;
671 bool havem2s =
false;
672 bool haves2m =
false;
678 for (
auto &ci : info) {
679 int ic = ci.inChannels;
680 int oc = ci.outChannels;
682 if (ic < 0 && oc >= 0)
684 else if (ic >= 0 && oc < 0)
686 else if (ic < 0 && oc < 0) {
691 if (ic == 2 && oc == 2)
693 else if (ic == 1 && oc == 1)
695 else if (ic == 1 && oc == 2)
697 else if (ic == 2 && oc == 1)
699 else if (ic == 0 && oc == 2)
701 else if (ic == 0 && oc == 1)
703 else if (ic == 1 && oc == 0)
705 else if (ic == 2 && oc == 0)
@ Internal
Indicates internal failure from Audacity.
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
#define AUDIOUNITEFFECTS_FAMILY
static const auto FullValue
constexpr auto OptionsKey
constexpr auto UseLatencyKey
static const AudacityProject::AttachedObjects::RegisteredFactory key
const TranslatableString name
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
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)
static Settings & settings()
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
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
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
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,...
bool SupportsRealtime() const
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.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
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)
std::pair< const char *, const char * > Pair
Common base class for AudioUnitEffect and its Instance.
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.