29 , mInstance{ instance }
30 , mEventListenerRef{ MakeListener() }
31 , mpControl{ pControl }
32 , mIsGraphical{ isGraphical }
50 const auto unit = mInstance.GetAudioUnit();
54 AUEventListenerRef eventListenerRef{};
57 static_cast<CFRunLoopRef
>(
const_cast<void*
>(
58 GetCFRunLoopFromEventLoop(GetCurrentEventLoop()))),
59 kCFRunLoopDefaultMode, 0.0, 0.0, &eventListenerRef))
61 result.reset(eventListenerRef);
64 AudioUnitEvent
event{ kAudioUnitEvent_ParameterValueChange };
66 auto ¶meter =
event.mArgument.mParameter;
70 if (
auto ¶meters = mInstance.GetParameters())
71 for (
const auto &ID : parameters) {
72 parameter.mParameterID = ID;
73 if (AUEventListenerAddEventType(result.get(),
this, &event))
78 event = { kAudioUnitEvent_PropertyChange };
81 kAudioUnitProperty_Latency,
82 kAudioUnitProperty_PresentPreset,
85 unit, type, kAudioUnitScope_Global };
86 if (AUEventListenerAddEventType(result.get(),
this, &event))
116 settings.extra.SetDuration(mDuration->GetValue());
143 const wxString &uiType,
146 const auto parent =
S.GetParent();
147 bool isGraphical = (uiType ==
FullValue.MSGID().GET());
153 wxPanel *container{};
155 auto mainSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
158 mainSizer->Add(container, 1, wxEXPAND);
159 parent->SetSizer(mainSizer.release());
162#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
164 if (!CreatePlain(mParent))
173 pControl = uControl.get();
175 if (!pControl->Create(container, myInstance.GetComponent(),
176 myInstance.GetAudioUnit(), isGraphical))
180 auto innerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
182 innerSizer->Add(uControl.release(), 1, wxEXPAND);
183 container->SetSizer(innerSizer.release());
186 parent->SetMinSize(wxDefaultSize);
189#ifdef __WX_EVTLOOP_BUSY_WAITING__
190 wxEventLoop::SetBusyWaiting(
true);
195 return std::make_unique<AudioUnitEditor>(
196 CreateToken{}, effect, access, myInstance, pControl, isGraphical);
201 AudioUnitParameter aup = {};
203 aup.mParameterID = kAUParameterListener_AnyParameter;
204 aup.mScope = kAudioUnitScope_Global;
206 AUParameterListenerNotify(NULL, NULL, &aup);
210 AudioUnitParameterValue inParameterValue)
215 if (inEvent->mEventType == kAudioUnitEvent_ParameterValueChange) {
216 constexpr AudioUnitParameterValue epsilon = 1e-6;
218 auto it =
mParameterValues.find(inEvent->mArgument.mParameter.mParameterID);
223 mParameterValues.insert(std::make_pair(inEvent->mArgument.mParameter.mParameterID, inParameterValue));
224 else if (std::abs(it->second - inParameterValue) > epsilon)
226 it->second = inParameterValue;
227 Publish({inEvent->mArgument.mParameter.mParameterID, inParameterValue});
230 const auto ID = inEvent->mArgument.mParameter.mParameterID;
231 mToUpdate.emplace_back(ID, inParameterValue);
234 else if (inEvent->mEventType == kAudioUnitEvent_PropertyChange &&
235 inEvent->mArgument.mProperty.mPropertyID ==
236 kAudioUnitProperty_PresentPreset
244 void *inObject,
const AudioUnitEvent *inEvent, UInt64 inEventHostTime,
245 AudioUnitParameterValue inParameterValue)
260 if (
auto &pair = mySettings.values[ID]; pair.has_value())
261 pair->second = value;
static const auto BasicValue
static const auto FullValue
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
static Settings & settings()
static std::unique_ptr< EffectEditor > Create(const EffectUIServices &effect, ShuttleGui &S, const wxString &uiType, EffectInstance &instance, EffectSettingsAccess &access)
void OnIdle(wxIdleEvent &evt)
AUControl *const mpControl
AudioUnitInstance & mInstance
std::unordered_map< AudioUnitParameterID, AudioUnitParameterValue > mParameterValues
bool IsGraphicalUI() override
static void EventListenerCallback(void *inCallbackRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inEventHostTime, AudioUnitParameterValue inParameterValue)
bool ValidateUI() override
Get settings data from the panel; may make error dialogs and return false.
bool UpdateUI() override
Update appearance of the panel for changes in settings.
AudioUnitEditor(CreateToken, const EffectUIServices &effect, EffectSettingsAccess &access, AudioUnitInstance &instance, AUControl *pControl, bool isGraphical)
bool FetchSettingsFromInstance(EffectSettings &settings)
AudioUnitCleanup< AUEventListenerRef, AUListenerDispose > EventListenerPtr
EventListenerPtr MakeListener()
std::vector< std::pair< AudioUnitParameterID, AudioUnitParameterValue > > mToUpdate
void EventListener(const AudioUnitEvent *inEvent, AudioUnitParameterValue inParameterValue)
~AudioUnitEditor() override
bool StoreSettingsToInstance(const EffectSettings &settings)
std::unique_ptr< Message > MakeMessage() const override
Called on the main thread, in which the result may be cloned.
void EventListener(const AudioUnitEvent *inEvent, AudioUnitParameterValue inParameterValue)
EffectSettingsAccess & mAccess
Performs effect computation.
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
virtual const EffectSettings & Get()=0
virtual void Set(EffectSettings &&settings, std::unique_ptr< Message > pMessage=nullptr)=0
CallbackReturn Publish(const EffectSettingChanged &message)
Send a message to connected callbacks.
const PerTrackEffect & mProcessor
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
bool StoreSettings(const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings) const
AudioUnit GetAudioUnit() const
static AudioUnitEffectSettings & GetSettings(EffectSettings &settings)
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.