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
AudioUnitEditor Class Reference

#include <AudioUnitEditor.h>

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

Classes

struct  CreateToken
 

Public Member Functions

 AudioUnitEditor (CreateToken, const EffectUIServices &effect, EffectSettingsAccess &access, AudioUnitInstance &instance, AUControl *pControl, bool isGraphical)
 
 ~AudioUnitEditor () 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 EffectEditor
 EffectEditor (const EffectUIServices &services, EffectSettingsAccess &access)
 
virtual ~EffectEditor ()
 
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< EffectEditorCreate (const EffectUIServices &effect, ShuttleGui &S, const wxString &uiType, EffectInstance &instance, EffectSettingsAccess &access)
 
- Static Public Member Functions inherited from EffectEditor
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 EffectEditor
static constexpr int kPlayID = 20102
 
- Static Public Attributes inherited from Observer::Publisher< EffectSettingChanged >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from EffectEditor
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 EffectEditor
const EffectUIServicesmUIServices
 
EffectSettingsAccessmAccess
 
bool mUIClosed { false }
 

Detailed Description

Definition at line 29 of file AudioUnitEditor.h.

Member Typedef Documentation

◆ EventListenerPtr

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

Definition at line 59 of file AudioUnitEditor.h.

Constructor & Destructor Documentation

◆ AudioUnitEditor()

AudioUnitEditor::AudioUnitEditor ( CreateToken  ,
const EffectUIServices effect,
EffectSettingsAccess access,
AudioUnitInstance instance,
AUControl pControl,
bool  isGraphical 
)

Definition at line 24 of file AudioUnitEditor.cpp.

28 : EffectEditor{ 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, &AudioUnitEditor::OnIdle, this);
39}
void OnIdle(wxIdleEvent &evt)
AUControl *const mpControl
AudioUnitInstance & mInstance
const bool mIsGraphical
const EventListenerPtr mEventListenerRef
EventListenerPtr MakeListener()
bool StoreSettingsToInstance(const EffectSettings &settings)
EffectSettingsAccess & mAccess
Definition: EffectEditor.h:92
virtual const EffectSettings & Get()=0

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

Here is the call graph for this function:

◆ ~AudioUnitEditor()

AudioUnitEditor::~AudioUnitEditor ( )
override

Definition at line 41 of file AudioUnitEditor.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< EffectEditor > AudioUnitEditor::Create ( const EffectUIServices effect,
ShuttleGui S,
const wxString &  uiType,
EffectInstance instance,
EffectSettingsAccess access 
)
static

Definition at line 141 of file AudioUnitEditor.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<AudioUnitEditor>(
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:164
#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 AudioUnitEditor::EventListener ( const AudioUnitEvent *  inEvent,
AudioUnitParameterValue  inParameterValue 
)
private

Definition at line 209 of file AudioUnitEditor.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::unordered_map< AudioUnitParameterID, AudioUnitParameterValue > mParameterValues
bool ValidateUI() override
Get settings data from the panel; may make error dialogs and return false.
std::vector< std::pair< AudioUnitParameterID, AudioUnitParameterValue > > mToUpdate
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)
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(), EffectEditor::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 AudioUnitEditor::EventListenerCallback ( void *  inCallbackRefCon,
void *  inObject,
const AudioUnitEvent *  inEvent,
UInt64  inEventHostTime,
AudioUnitParameterValue  inParameterValue 
)
staticprivate

Definition at line 243 of file AudioUnitEditor.cpp.

246{
247 static_cast<AudioUnitEditor *>(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 AudioUnitEditor::FetchSettingsFromInstance ( EffectSettings settings)
private

Definition at line 129 of file AudioUnitEditor.cpp.

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

Default implementation returns false

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

Reimplemented from EffectEditor.

Definition at line 124 of file AudioUnitEditor.cpp.

125{
126 return mIsGraphical;
127}

References mIsGraphical.

◆ MakeListener()

auto AudioUnitEditor::MakeListener ( )
private

Definition at line 47 of file AudioUnitEditor.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(AudioUnitEditor::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}
static void EventListenerCallback(void *inCallbackRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inEventHostTime, AudioUnitParameterValue inParameterValue)
AudioUnitCleanup< AUEventListenerRef, AUListenerDispose > EventListenerPtr
AudioUnit GetAudioUnit() const
const Parameters & GetParameters() const

References EventListenerCallback().

Here is the call graph for this function:

◆ Notify()

void AudioUnitEditor::Notify ( )
private

Definition at line 199 of file AudioUnitEditor.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 AudioUnitEditor::OnIdle ( wxIdleEvent &  evt)
private

Definition at line 251 of file AudioUnitEditor.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(), EffectEditor::mAccess, EffectSettingsAccess::ModifySettings(), mToUpdate, and settings().

Referenced by AudioUnitEditor().

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

◆ StoreSettingsToInstance()

bool AudioUnitEditor::StoreSettingsToInstance ( const EffectSettings settings)
private

Definition at line 135 of file AudioUnitEditor.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 AudioUnitEditor(), and UpdateUI().

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

◆ UpdateUI()

bool AudioUnitEditor::UpdateUI ( )
overridevirtual

Update appearance of the panel for changes in settings.

Default implementation does nothing, returns true

Returns
true if successful

Reimplemented from EffectEditor.

Definition at line 93 of file AudioUnitEditor.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(), EffectEditor::mAccess, mpControl, Notify(), and StoreSettingsToInstance().

Here is the call graph for this function:

◆ ValidateUI()

bool AudioUnitEditor::ValidateUI ( )
overridevirtual

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

Returns
true only if panel settings are acceptable

Implements EffectEditor.

Definition at line 109 of file AudioUnitEditor.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(), EffectEditor::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 AudioUnitEditor::mEventListenerRef
private

Definition at line 67 of file AudioUnitEditor.h.

◆ mInstance

AudioUnitInstance& AudioUnitEditor::mInstance
private

◆ mIsGraphical

const bool AudioUnitEditor::mIsGraphical
private

Definition at line 71 of file AudioUnitEditor.h.

Referenced by IsGraphicalUI().

◆ mParameterValues

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

Definition at line 75 of file AudioUnitEditor.h.

Referenced by EventListener().

◆ mpControl

AUControl* const AudioUnitEditor::mpControl {}
private

Definition at line 68 of file AudioUnitEditor.h.

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

◆ mToUpdate

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

Definition at line 70 of file AudioUnitEditor.h.

Referenced by EventListener(), and OnIdle().


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