Audacity 3.2.0
Classes | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
AudioUnitValidator Class Reference

#include <AudioUnitValidator.h>

Inheritance diagram for AudioUnitValidator:
[legend]
Collaboration diagram for AudioUnitValidator:
[legend]

Classes

struct  CreateToken
 

Public Member Functions

 AudioUnitValidator (CreateToken, EffectUIClientInterface &effect, EffectSettingsAccess &access, AudioUnitInstance &instance, AUControl *pControl, bool isGraphical)
 
 ~AudioUnitValidator () override
 
bool UpdateUI () override
 Update appearance of the panel for changes in settings. More...
 
bool ValidateUI () override
 Get settings data from the panel; may make error dialogs and return false. More...
 
bool IsGraphicalUI () override
 
- Public Member Functions inherited from EffectUIValidator
 EffectUIValidator (EffectUIClientInterface &effect, EffectSettingsAccess &access)
 
virtual ~EffectUIValidator ()
 
virtual bool ValidateUI ()=0
 Get settings data from the panel; may make error dialogs and return false. More...
 
virtual bool UpdateUI ()
 Update appearance of the panel for changes in settings. More...
 
virtual bool IsGraphicalUI ()
 
virtual void Disconnect ()
 On the first call only, may disconnect from further event handling. More...
 
virtual void OnClose ()
 
- Public Member Functions inherited from Observer::Publisher< EffectSettingChanged >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Member Functions

static std::unique_ptr< EffectUIValidatorCreate (EffectUIClientInterface &effect, ShuttleGui &S, const wxString &uiType, EffectInstance &instance, EffectSettingsAccess &access)
 
- Static Public Member Functions inherited from EffectUIValidator
static bool EnableApply (wxWindow *parent, bool enable=true)
 Enable or disable the Apply button of the dialog that contains parent. More...
 
static bool EnablePreview (wxWindow *parent, bool enable=true)
 

Private Types

using EventListenerPtr = AudioUnitCleanup< AUEventListenerRef, AUListenerDispose >
 

Private Member Functions

void EventListener (const AudioUnitEvent *inEvent, AudioUnitParameterValue inParameterValue)
 
void OnIdle (wxIdleEvent &evt)
 
bool FetchSettingsFromInstance (EffectSettings &settings)
 
bool StoreSettingsToInstance (const EffectSettings &settings)
 
void Notify ()
 
EventListenerPtr MakeListener ()
 

Static Private Member Functions

static void EventListenerCallback (void *inCallbackRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inEventHostTime, AudioUnitParameterValue inParameterValue)
 

Private Attributes

AudioUnitInstancemInstance
 
const EventListenerPtr mEventListenerRef
 
AUControl *const mpControl {}
 
std::vector< std::pair< AudioUnitParameterID, AudioUnitParameterValue > > mToUpdate
 
const bool mIsGraphical
 
std::unordered_map< AudioUnitParameterID, AudioUnitParameterValue > mParameterValues
 

Additional Inherited Members

- Public Types inherited from Observer::Publisher< EffectSettingChanged >
using message_type = EffectSettingChanged
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const EffectSettingChanged &) >
 Type of functions that can be connected to the Publisher. More...
 
- Static Public Attributes inherited from EffectUIValidator
static constexpr int kPlayID = 20102
 
- Static Public Attributes inherited from Observer::Publisher< EffectSettingChanged >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from EffectUIValidator
template<typename EventTag , typename Class , typename Event >
void BindTo (wxEvtHandler &src, const EventTag &eventType, void(Class::*pmf)(Event &))
 
- Protected Member Functions inherited from Observer::Publisher< EffectSettingChanged >
CallbackReturn Publish (const EffectSettingChanged &message)
 Send a message to connected callbacks. More...
 
- Protected Attributes inherited from EffectUIValidator
EffectUIClientInterfacemEffect
 
EffectSettingsAccessmAccess
 
bool mUIClosed { false }
 

Detailed Description

Definition at line 26 of file AudioUnitValidator.h.

Member Typedef Documentation

◆ EventListenerPtr

using AudioUnitValidator::EventListenerPtr = AudioUnitCleanup<AUEventListenerRef, AUListenerDispose>
private

Definition at line 56 of file AudioUnitValidator.h.

Constructor & Destructor Documentation

◆ AudioUnitValidator()

AudioUnitValidator::AudioUnitValidator ( CreateToken  ,
EffectUIClientInterface effect,
EffectSettingsAccess access,
AudioUnitInstance instance,
AUControl pControl,
bool  isGraphical 
)

Definition at line 24 of file AudioUnitValidator.cpp.

28 : EffectUIValidator{ effect, access }
29 , mInstance{ instance }
31 , mpControl{ pControl }
32 , mIsGraphical{ isGraphical }
33{
34 // Make the settings of the instance up to date before using it to
35 // build a UI
37
38 wxTheApp->Bind(wxEVT_IDLE, &AudioUnitValidator::OnIdle, this);
39}
const EventListenerPtr mEventListenerRef
void OnIdle(wxIdleEvent &evt)
EventListenerPtr MakeListener()
bool StoreSettingsToInstance(const EffectSettings &settings)
AUControl *const mpControl
AudioUnitInstance & mInstance
virtual const EffectSettings & Get()=0
Interface for transferring values from a panel of effect controls.
Definition: EffectPlugin.h:239
EffectSettingsAccess & mAccess
Definition: EffectPlugin.h:297

References EffectSettingsAccess::Get(), EffectUIValidator::mAccess, OnIdle(), and StoreSettingsToInstance().

Here is the call graph for this function:

◆ ~AudioUnitValidator()

AudioUnitValidator::~AudioUnitValidator ( )
override

Definition at line 41 of file AudioUnitValidator.cpp.

42{
43 if (mpControl)
45}
void Close()

References AUControl::Close(), and mpControl.

Here is the call graph for this function:

Member Function Documentation

◆ Create()

std::unique_ptr< EffectUIValidator > AudioUnitValidator::Create ( EffectUIClientInterface effect,
ShuttleGui S,
const wxString &  uiType,
EffectInstance instance,
EffectSettingsAccess access 
)
static

Definition at line 141 of file AudioUnitValidator.cpp.

145{
146 const auto parent = S.GetParent();
147 bool isGraphical = (uiType == FullValue.MSGID().GET());
148 // Cast is assumed to succeed because only this effect's own instances
149 // are passed back by the framework
150 auto &myInstance = dynamic_cast<AudioUnitInstance&>(instance);
151
152 AUControl *pControl{};
153 wxPanel *container{};
154 {
155 auto mainSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
156 wxASSERT(parent); // To justify safenew
157 container = safenew wxPanelWrapper(parent, wxID_ANY);
158 mainSizer->Add(container, 1, wxEXPAND);
159 parent->SetSizer(mainSizer.release());
160 }
161
162#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
163 if (uiType == BasicValue.MSGID().GET()) {
164 if (!CreatePlain(mParent))
165 return nullptr;
166 }
167 else
168#endif
169 {
171 if (!uControl)
172 return nullptr;
173 pControl = uControl.get();
174
175 if (!pControl->Create(container, myInstance.GetComponent(),
176 myInstance.GetAudioUnit(), isGraphical))
177 return nullptr;
178
179 {
180 auto innerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
181
182 innerSizer->Add(uControl.release(), 1, wxEXPAND);
183 container->SetSizer(innerSizer.release());
184 }
185
186 parent->SetMinSize(wxDefaultSize);
187
188#ifdef __WXMAC__
189#ifdef __WX_EVTLOOP_BUSY_WAITING__
190 wxEventLoop::SetBusyWaiting(true);
191#endif
192#endif
193 }
194
195 return std::make_unique<AudioUnitValidator>(
196 CreateToken{}, effect, access, myInstance, pControl, isGraphical);
197}
static const auto BasicValue
static const auto FullValue
#define safenew
Definition: MemoryX.h:10
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:162
#define S(N)
Definition: ToChars.cpp:64

References BasicValue, FullValue, S, and safenew.

Referenced by AudioUnitEffect::PopulateUI().

Here is the caller graph for this function:

◆ EventListener()

void AudioUnitValidator::EventListener ( const AudioUnitEvent *  inEvent,
AudioUnitParameterValue  inParameterValue 
)
private

Definition at line 209 of file AudioUnitValidator.cpp.

211{
212 // Modify the instance and its workers
213 mInstance.EventListener(inEvent, inParameterValue);
214
215 if (inEvent->mEventType == kAudioUnitEvent_ParameterValueChange) {
216 constexpr AudioUnitParameterValue epsilon = 1e-6;
217
218 auto it = mParameterValues.find(inEvent->mArgument.mParameter.mParameterID);
219
220 // When the UI is opened - EventListener is called for each parameter
221 // with the current value.
222 if (it == mParameterValues.end())
223 mParameterValues.insert(std::make_pair(inEvent->mArgument.mParameter.mParameterID, inParameterValue));
224 else if (std::abs(it->second - inParameterValue) > epsilon)
225 {
226 it->second = inParameterValue;
227 Publish({inEvent->mArgument.mParameter.mParameterID, inParameterValue});
228 }
229
230 const auto ID = inEvent->mArgument.mParameter.mParameterID;
231 mToUpdate.emplace_back(ID, inParameterValue);
232 mAccess.Set(mInstance.MakeMessage(ID, inParameterValue));
233 }
234 else if (inEvent->mEventType == kAudioUnitEvent_PropertyChange &&
235 inEvent->mArgument.mProperty.mPropertyID ==
236 kAudioUnitProperty_PresentPreset
237 ) {
238 ValidateUI();
239 }
240}
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)
std::vector< std::pair< AudioUnitParameterID, AudioUnitParameterValue > > mToUpdate
bool ValidateUI() override
Get settings data from the panel; may make error dialogs and return false.
std::unordered_map< AudioUnitParameterID, AudioUnitParameterValue > mParameterValues
virtual void Set(EffectSettings &&settings, std::unique_ptr< Message > pMessage=nullptr)=0
CallbackReturn Publish(const EffectSettingChanged &message)
Send a message to connected callbacks.
Definition: Observer.h:207

References AudioUnitInstance::EventListener(), EffectUIValidator::mAccess, AudioUnitInstance::MakeMessage(), mInstance, mParameterValues, mToUpdate, Observer::Publisher< EffectSettingChanged >::Publish(), EffectSettingsAccess::Set(), and ValidateUI().

Referenced by EventListenerCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EventListenerCallback()

void AudioUnitValidator::EventListenerCallback ( void *  inCallbackRefCon,
void *  inObject,
const AudioUnitEvent *  inEvent,
UInt64  inEventHostTime,
AudioUnitParameterValue  inParameterValue 
)
staticprivate

Definition at line 243 of file AudioUnitValidator.cpp.

246{
247 static_cast<AudioUnitValidator *>(inCallbackRefCon)
248 ->EventListener(inEvent, inParameterValue);
249}
void EventListener(const AudioUnitEvent *inEvent, AudioUnitParameterValue inParameterValue)

References EventListener().

Referenced by MakeListener().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FetchSettingsFromInstance()

bool AudioUnitValidator::FetchSettingsFromInstance ( EffectSettings settings)
private

Definition at line 129 of file AudioUnitValidator.cpp.

130{
131 return mInstance
133}
static Settings & settings()
Definition: TrackInfo.cpp:87
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.

References AudioUnitWrapper::FetchSettings(), AudioUnitWrapper::GetSettings(), mInstance, and settings().

Referenced by ValidateUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsGraphicalUI()

bool AudioUnitValidator::IsGraphicalUI ( )
overridevirtual

Default implementation returns false

Returns
true if using a native plug-in UI, not widgets

Reimplemented from EffectUIValidator.

Definition at line 124 of file AudioUnitValidator.cpp.

125{
126 return mIsGraphical;
127}

References mIsGraphical.

◆ MakeListener()

auto AudioUnitValidator::MakeListener ( )
private

Definition at line 47 of file AudioUnitValidator.cpp.

49{
50 const auto unit = mInstance.GetAudioUnit();
51 EventListenerPtr result;
52
53 // Register a callback with the audio unit
54 AUEventListenerRef eventListenerRef{};
55 if (AUEventListenerCreate(AudioUnitValidator::EventListenerCallback,
56 this,
57 static_cast<CFRunLoopRef>( const_cast<void*>(
58 GetCFRunLoopFromEventLoop(GetCurrentEventLoop()))),
59 kCFRunLoopDefaultMode, 0.0, 0.0, &eventListenerRef))
60 return nullptr;
61 result.reset(eventListenerRef);
62
63 // AudioUnitEvent is a struct with a discriminator field and a union
64 AudioUnitEvent event{ kAudioUnitEvent_ParameterValueChange };
65 // Initialize union member -- the ID (second field) reassigned later
66 auto &parameter = event.mArgument.mParameter;
67 parameter = AudioUnitUtils::Parameter{ unit, kAudioUnitScope_Global };
68
69 // Register each parameter as something we're interested in
70 if (auto &parameters = mInstance.GetParameters())
71 for (const auto &ID : parameters) {
72 parameter.mParameterID = ID;
73 if (AUEventListenerAddEventType(result.get(), this, &event))
74 return nullptr;
75 }
76
77 // Now set up the other union member
78 event = { kAudioUnitEvent_PropertyChange };
79 // And bind the listener function to certain property changes
80 for (auto type : {
81 kAudioUnitProperty_Latency,
82 kAudioUnitProperty_PresentPreset,
83 }) {
84 event.mArgument.mProperty = AudioUnitUtils::Property{
85 unit, type, kAudioUnitScope_Global };
86 if (AUEventListenerAddEventType(result.get(), this, &event))
87 return nullptr;
88 }
89
90 return result;
91}
AudioUnitCleanup< AUEventListenerRef, AUListenerDispose > EventListenerPtr
static void EventListenerCallback(void *inCallbackRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inEventHostTime, AudioUnitParameterValue inParameterValue)
AudioUnit GetAudioUnit() const
const Parameters & GetParameters() const

References EventListenerCallback().

Here is the call graph for this function:

◆ Notify()

void AudioUnitValidator::Notify ( )
private

Definition at line 199 of file AudioUnitValidator.cpp.

200{
201 AudioUnitParameter aup = {};
202 aup.mAudioUnit = mInstance.GetAudioUnit();
203 aup.mParameterID = kAUParameterListener_AnyParameter;
204 aup.mScope = kAudioUnitScope_Global;
205 aup.mElement = 0;
206 AUParameterListenerNotify(NULL, NULL, &aup);
207}

References AudioUnitWrapper::GetAudioUnit(), and mInstance.

Referenced by UpdateUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnIdle()

void AudioUnitValidator::OnIdle ( wxIdleEvent &  evt)
private

Definition at line 251 of file AudioUnitValidator.cpp.

252{
253 evt.Skip();
254 if (mToUpdate.size()) {
256 // Reassign settings, so that there is "stickiness" when dialog is
257 // closed and opened again
258 auto &mySettings = AudioUnitInstance::GetSettings(settings);
259 for (auto [ID, value] : mToUpdate)
260 if (auto &pair = mySettings.values[ID]; pair.has_value())
261 pair->second = value;
262 return nullptr;
263 });
264 mToUpdate.clear();
265 }
266}
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
Externalized state of a plug-in.

References AudioUnitWrapper::GetSettings(), EffectUIValidator::mAccess, EffectSettingsAccess::ModifySettings(), mToUpdate, and settings().

Referenced by AudioUnitValidator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StoreSettingsToInstance()

bool AudioUnitValidator::StoreSettingsToInstance ( const EffectSettings settings)
private

Definition at line 135 of file AudioUnitValidator.cpp.

136{
139}
const PerTrackEffect & mProcessor
bool StoreSettings(const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings) const

References AudioUnitWrapper::GetSettings(), mInstance, PerTrackEffect::Instance::mProcessor, settings(), and AudioUnitWrapper::StoreSettings().

Referenced by AudioUnitValidator(), and UpdateUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateUI()

bool AudioUnitValidator::UpdateUI ( )
overridevirtual

Update appearance of the panel for changes in settings.

Default implementation does nothing, returns true

Returns
true if successful

Reimplemented from EffectUIValidator.

Definition at line 93 of file AudioUnitValidator.cpp.

94{
95 // Update parameter values in AudioUnit, and propagate to any listeners
97 // See AUView::viewWillDraw
98 if (mpControl)
100
101 // This will be the AudioUnit of a stateful instance, not of the effect
102 Notify();
103
104 return true;
105 }
106 return false;
107}
void ForceRedraw()

References AUControl::ForceRedraw(), EffectSettingsAccess::Get(), EffectUIValidator::mAccess, mpControl, Notify(), and StoreSettingsToInstance().

Here is the call graph for this function:

◆ ValidateUI()

bool AudioUnitValidator::ValidateUI ( )
overridevirtual

Get settings data from the panel; may make error dialogs and return false.

Returns
true only if panel settings are acceptable

Implements EffectUIValidator.

Definition at line 109 of file AudioUnitValidator.cpp.

110{
112#if 0
113 // This analogy with other generators doesn't seem to fit AudioUnits
114 // How can we define the control mDuration?
115 if (GetType() == EffectTypeGenerate)
116 settings.extra.SetDuration(mDuration->GetValue());
117#endif
119 return nullptr;
120 });
121 return true;
122}
@ EffectTypeGenerate
bool FetchSettingsFromInstance(EffectSettings &settings)

References EffectTypeGenerate, FetchSettingsFromInstance(), EffectUIValidator::mAccess, EffectSettingsAccess::ModifySettings(), and settings().

Referenced by EventListener().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mEventListenerRef

const EventListenerPtr AudioUnitValidator::mEventListenerRef
private

Definition at line 64 of file AudioUnitValidator.h.

◆ mInstance

AudioUnitInstance& AudioUnitValidator::mInstance
private

◆ mIsGraphical

const bool AudioUnitValidator::mIsGraphical
private

Definition at line 68 of file AudioUnitValidator.h.

Referenced by IsGraphicalUI().

◆ mParameterValues

std::unordered_map<AudioUnitParameterID, AudioUnitParameterValue> AudioUnitValidator::mParameterValues
private

Definition at line 72 of file AudioUnitValidator.h.

Referenced by EventListener().

◆ mpControl

AUControl* const AudioUnitValidator::mpControl {}
private

Definition at line 65 of file AudioUnitValidator.h.

Referenced by UpdateUI(), and ~AudioUnitValidator().

◆ mToUpdate

std::vector< std::pair<AudioUnitParameterID, AudioUnitParameterValue> > AudioUnitValidator::mToUpdate
private

Definition at line 67 of file AudioUnitValidator.h.

Referenced by EventListener(), and OnIdle().


The documentation for this class was generated from the following files: