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

Manages and interacts with an AudioUnit, providing operations on audio effects. More...

#include <AudioUnitWrapper.h>

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

Classes

class  ParameterInfo
 Encapsulates parameter information for an AudioUnit. More...
 

Public Types

using Parameters = PackedArray::Ptr< const AudioUnitParameterID >
 
using ParameterVisitor = std::function< bool(const ParameterInfo &pi, AudioUnitParameterID ID) >
 Return value: if true, continue visiting. More...
 

Public Member Functions

 AudioUnitWrapper (AudioComponent component, Parameters *pParameters)
 
template<typename T >
OSStatus GetFixedSizeProperty (AudioUnitPropertyID inID, T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
 
template<typename T >
OSStatus GetVariableSizeProperty (AudioUnitPropertyID inID, PackedArray::Ptr< T > &pObject, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
 
template<typename T >
OSStatus SetProperty (AudioUnitPropertyID inID, const T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
 
void ForEachParameter (ParameterVisitor visitor) const
 
bool LoadPreset (const EffectDefinitionInterface &effect, const RegistryPath &group, EffectSettings &settings) const
 
bool LoadFactoryPreset (const EffectDefinitionInterface &effect, int id, EffectSettings *pSettings) const
 
std::pair< CF_ptr< CFDataRef >, TranslatableStringMakeBlob (const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings, const wxCFStringRef &cfname, bool binary) const
 Obtain dump of the setting state of an AudioUnit instance. More...
 
TranslatableString InterpretBlob (AudioUnitEffectSettings &settings, const wxString &group, const wxMemoryBuffer &buf) const
 Interpret the dump made before by MakeBlob. More...
 
bool FetchSettings (AudioUnitEffectSettings &settings, bool fetchValues, bool fetchPreset=false) const
 May allocate memory, so should be called only in the main thread. More...
 
bool StoreSettings (const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings) const
 
bool CreateAudioUnit ()
 
AudioUnit GetAudioUnit () const
 
AudioComponent GetComponent () const
 
const ParametersGetParameters () const
 
bool SetRateAndChannels (double sampleRate, const wxString &identifier)
 

Static Public Member Functions

static AudioUnitEffectSettingsGetSettings (EffectSettings &settings)
 
static const AudioUnitEffectSettingsGetSettings (const EffectSettings &settings)
 
static bool MoveSettingsContents (AudioUnitEffectSettings &&src, AudioUnitEffectSettings &dst, bool merge)
 Copy, then clear the optionals in src. More...
 

Protected Attributes

const AudioComponent mComponent
 
AudioUnitCleanup< AudioUnit, AudioComponentInstanceDispose > mUnit
 
Parameters mOwnParameters
 
ParametersmParameters
 
unsigned mAudioIns { 2 }
 
unsigned mAudioOuts { 2 }
 

Detailed Description

Manages and interacts with an AudioUnit, providing operations on audio effects.

This class hosts the functionality for managing AudioUnit settings, presets, and parameters, allowing manipulation of audio processing units.

Definition at line 90 of file AudioUnitWrapper.h.

Member Typedef Documentation

◆ Parameters

using AudioUnitWrapper::Parameters = PackedArray::Ptr<const AudioUnitParameterID>

Definition at line 92 of file AudioUnitWrapper.h.

◆ ParameterVisitor

using AudioUnitWrapper::ParameterVisitor = std::function< bool(const ParameterInfo &pi, AudioUnitParameterID ID) >

Return value: if true, continue visiting.

Definition at line 142 of file AudioUnitWrapper.h.

Constructor & Destructor Documentation

◆ AudioUnitWrapper()

AudioUnitWrapper::AudioUnitWrapper ( AudioComponent  component,
Parameters pParameters 
)
inline
Parameters
pParametersif non-null, use those; else, fetch from the AudioUnit

Definition at line 101 of file AudioUnitWrapper.h.

102 : mComponent{ component }
103 , mParameters{ pParameters ? *pParameters : mOwnParameters }
104 {
105 }
Parameters & mParameters
const AudioComponent mComponent
Parameters mOwnParameters

Member Function Documentation

◆ CreateAudioUnit()

bool AudioUnitWrapper::CreateAudioUnit ( )

Definition at line 265 of file AudioUnitWrapper.cpp.

266{
267 AudioUnit unit{};
268 auto result = AudioComponentInstanceNew(mComponent, &unit);
269 if (!result) {
270 mUnit.reset(unit);
273 kAudioUnitProperty_ParameterList, mOwnParameters);
274 }
275
276 return (!result && unit != nullptr);
277}
OSStatus GetVariableSizeProperty(AudioUnitPropertyID inID, PackedArray::Ptr< T > &pObject, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
AudioUnitCleanup< AudioUnit, AudioComponentInstanceDispose > mUnit

References GetVariableSizeProperty(), mComponent, mOwnParameters, mParameters, and mUnit.

Referenced by AudioUnitInstance::AudioUnitInstance(), and AudioUnitEffectBase::InitializePlugin().

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

◆ FetchSettings()

bool AudioUnitWrapper::FetchSettings ( AudioUnitEffectSettings settings,
bool  fetchValues,
bool  fetchPreset = false 
) const

May allocate memory, so should be called only in the main thread.

Definition at line 149 of file AudioUnitWrapper.cpp.

151{
152 settings.mPresetNumber = {};
153 if (fetchPreset) {
154 AUPreset preset{};
155 if (!GetFixedSizeProperty(kAudioUnitProperty_PresentPreset, preset))
156 // Only want factory preset number, not a user preset (<0)
157 if (preset.presetNumber >= 0)
158 settings.mPresetNumber = { preset.presetNumber };
159 }
160
161 // Fetch values from the AudioUnit into AudioUnitEffectSettings,
162 // keeping the cache up-to-date␓ after state changes in the AudioUnit
164 [this, &settings, fetchValues]
165 (const ParameterInfo &pi, AudioUnitParameterID ID) {
166 // Always make a slot, even for parameter IDs that are known but
167 // not gettable from the instance now. Example: AUGraphicEQ when
168 // you choose 10 bands; the values for bands 10 ... 30 are undefined
169 // but the parameter IDs are known
170 auto &slot = settings.values[ID];
171 slot.reset();
172 if (fetchValues) {
173 AudioUnitParameterValue value;
174 if (!pi.mName ||
175 AudioUnitGetParameter(
176 mUnit.get(), ID, kAudioUnitScope_Global, 0, &value)) {
177 // Probably failed because of invalid parameter which can happen
178 // if a plug-in is in a certain mode that doesn't contain the
179 // parameter. In any case, just ignore it.
180 }
181 else
182 slot.emplace(settings.Intern(*pi.mName), value);
183 }
184 return true;
185 });
186 return true;
187}
ReverbSettings preset
Definition: ReverbBase.cpp:25
static Settings & settings()
Definition: TrackInfo.cpp:51
OSStatus GetFixedSizeProperty(AudioUnitPropertyID inID, T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
void ForEachParameter(ParameterVisitor visitor) const

References ForEachParameter(), GetFixedSizeProperty(), mUnit, MIR::anonymous_namespace{MirUtils.cpp}::pi, preset, and settings().

Referenced by AudioUnitEditor::FetchSettingsFromInstance(), InterpretBlob(), LoadFactoryPreset(), AudioUnitInstance::MakeMessage(), and AudioUnitEffectBase::MakeSettings().

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

◆ ForEachParameter()

void AudioUnitWrapper::ForEachParameter ( ParameterVisitor  visitor) const

Definition at line 317 of file AudioUnitWrapper.cpp.

318{
319 if (!mParameters)
320 return;
321 for (const auto &ID : mParameters)
322 if (ParameterInfo pi{ mUnit.get(), ID };
323 !visitor(pi, ID))
324 break;
325}

References mParameters, mUnit, and MIR::anonymous_namespace{MirUtils.cpp}::pi.

Referenced by FetchSettings(), StoreSettings(), and AudioUnitEffectBase::SupportsAutomation().

Here is the caller graph for this function:

◆ GetAudioUnit()

AudioUnit AudioUnitWrapper::GetAudioUnit ( ) const
inline

Definition at line 182 of file AudioUnitWrapper.h.

182{ return mUnit.get(); }

References mUnit.

Referenced by AudioUnitInstance::EventListener(), and AudioUnitEditor::Notify().

Here is the caller graph for this function:

◆ GetComponent()

AudioComponent AudioUnitWrapper::GetComponent ( ) const
inline

Definition at line 183 of file AudioUnitWrapper.h.

183{ return mComponent; }

References mComponent.

◆ GetFixedSizeProperty()

template<typename T >
OSStatus AudioUnitWrapper::GetFixedSizeProperty ( AudioUnitPropertyID  inID,
T &  property,
AudioUnitScope  inScope = kAudioUnitScope_Global,
AudioUnitElement  inElement = 0 
) const
inline

Definition at line 109 of file AudioUnitWrapper.h.

112 {
113 // Supply mUnit.get() to the non-member function
115 inID, property, inScope, inElement);
116 }
OSStatus GetFixedSizeProperty(AudioUnit unit, AudioUnitPropertyID inID, T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0)

References AudioUnitUtils::GetFixedSizeProperty(), and mUnit.

Referenced by FetchSettings(), AudioUnitEffectBase::GetFactoryPresets(), AudioUnitInstance::InitialBlockSize(), AudioUnitEffectBase::InitializePlugin(), LoadFactoryPreset(), and MakeBlob().

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

◆ GetParameters()

const Parameters & AudioUnitWrapper::GetParameters ( ) const
inline

Definition at line 184 of file AudioUnitWrapper.h.

185 { return mParameters; }

References mParameters.

◆ GetSettings() [1/2]

const AudioUnitEffectSettings & AudioUnitWrapper::GetSettings ( const EffectSettings settings)
static

Definition at line 36 of file AudioUnitWrapper.cpp.

36 {
37 return GetSettings(const_cast<EffectSettings &>(settings));
38}
static AudioUnitEffectSettings & GetSettings(EffectSettings &settings)
Externalized state of a plug-in.

References GetSettings(), and settings().

Here is the call graph for this function:

◆ GetSettings() [2/2]

AudioUnitEffectSettings & AudioUnitWrapper::GetSettings ( EffectSettings settings)
static

Definition at line 27 of file AudioUnitWrapper.cpp.

27 {
28 auto pSettings = settings.cast<AudioUnitEffectSettings>();
29 // Assume the settings object ultimately came from AudioUnitEffect's
30 // MakeSettings or copying of that
31 assert(pSettings);
32 return *pSettings;
33}
Represents a cached copy of the state stored in an AudioUnit, but can outlive the original AudioUnit.

References settings().

Referenced by AudioUnitEffectBase::ChoosePresetKey(), AudioUnitEffect::ExportPresets(), AudioUnitEditor::FetchSettingsFromInstance(), GetSettings(), AudioUnitEffect::ImportPresets(), LoadFactoryPreset(), LoadPreset(), AudioUnitEffectBase::LoadSettings(), AudioUnitEffectBase::MigrateOldConfigFile(), AudioUnitEditor::OnIdle(), AudioUnitInstance::ProcessInitialize(), AudioUnitEffectBase::SaveSettings(), AudioUnitEffectBase::SaveUserPreset(), and AudioUnitEditor::StoreSettingsToInstance().

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

◆ GetVariableSizeProperty()

template<typename T >
OSStatus AudioUnitWrapper::GetVariableSizeProperty ( AudioUnitPropertyID  inID,
PackedArray::Ptr< T > &  pObject,
AudioUnitScope  inScope = kAudioUnitScope_Global,
AudioUnitElement  inElement = 0 
) const
inline

Definition at line 120 of file AudioUnitWrapper.h.

124 {
126 inID, pObject, inScope, inElement);
127 }
OSStatus GetVariableSizeProperty(AudioUnit unit, AudioUnitPropertyID inID, PackedArray::Ptr< T > &pObject, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0)

References AudioUnitUtils::GetVariableSizeProperty(), and mUnit.

Referenced by CreateAudioUnit(), and AudioUnitEffectBase::GetChannelCounts().

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

◆ InterpretBlob()

TranslatableString AudioUnitWrapper::InterpretBlob ( AudioUnitEffectSettings settings,
const wxString &  group,
const wxMemoryBuffer &  buf 
) const

Interpret the dump made before by MakeBlob.

Parameters
grouponly for formatting error messages
Returns
an error message

Definition at line 279 of file AudioUnitWrapper.cpp.

282{
283 size_t bufLen = buf.GetDataLen();
284 if (!bufLen)
285 return XO("Failed to decode \"%s\" preset").Format(group);
286
287 // Create a CFData object that references the decoded preset
288 const auto bufPtr = static_cast<const uint8_t *>(buf.GetData());
289 CF_ptr<CFDataRef> data{ CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
290 bufPtr, bufLen, kCFAllocatorNull)
291 };
292 if (!data)
293 return XO("Failed to convert \"%s\" preset to internal format")
294 .Format(group);
295
296 // Convert it back to a property list
297 CF_ptr<CFPropertyListRef> content{
298 CFPropertyListCreateWithData(kCFAllocatorDefault,
299 data.get(), kCFPropertyListImmutable, nullptr,
300 // TODO might retrieve more error information
301 nullptr)
302 };
303 if (!content)
304 return XO("Failed to create property list for \"%s\" preset")
305 .Format(group);
306
307 // Finally, update the properties and parameters
308 if (SetProperty(kAudioUnitProperty_ClassInfo, content.get()))
309 return XO("Failed to set class info for \"%s\" preset").Format(group);
310
311 // Repopulate the AudioUnitEffectSettings from the change of state in
312 // the AudioUnit, and include the preset
313 FetchSettings(settings, true, true);
314 return {};
315}
XO("Cut/Copy/Paste")
OSStatus SetProperty(AudioUnitPropertyID inID, const T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0) const
bool FetchSettings(AudioUnitEffectSettings &settings, bool fetchValues, bool fetchPreset=false) const
May allocate memory, so should be called only in the main thread.

References FetchSettings(), SetProperty(), settings(), and XO().

Referenced by AudioUnitEffectBase::Import(), and LoadPreset().

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

◆ LoadFactoryPreset()

bool AudioUnitWrapper::LoadFactoryPreset ( const EffectDefinitionInterface effect,
int  id,
EffectSettings pSettings 
) const

Definition at line 351 of file AudioUnitWrapper.cpp.

354{
355 if (pSettings) {
356 // Issue 3441: Some factory presets of some effects do not reassign all
357 // controls. So first put controls into a default state, not contaminated
358 // by previous importing or other loading of settings into this wrapper.
359 if (!LoadPreset(effect, FactoryDefaultsGroup(), *pSettings))
360 return false;
361 }
362
363 // Retrieve the list of factory presets
364 CF_ptr<CFArrayRef> array;
365 if (GetFixedSizeProperty(kAudioUnitProperty_FactoryPresets, array) ||
366 id < 0 || id >= CFArrayGetCount(array.get()))
367 return false;
368
369 // Mutate the scratch pad AudioUnit in this wrapper
370 if (SetProperty(kAudioUnitProperty_PresentPreset,
371 *static_cast<const AUPreset*>(CFArrayGetValueAtIndex(array.get(), id))))
372 return false;
373
374 if (pSettings) {
375 // Repopulate the AudioUnitEffectSettings from the change of state in
376 // the AudioUnit
377 if (!FetchSettings(GetSettings(*pSettings), true, true))
378 return false;
379 }
380
381 return true;
382}
const RegistryPath & FactoryDefaultsGroup()
Component of a configuration key path, for default state of MakeSettings()
bool LoadPreset(const EffectDefinitionInterface &effect, const RegistryPath &group, EffectSettings &settings) const

References FactoryDefaultsGroup(), FetchSettings(), GetFixedSizeProperty(), GetSettings(), LoadPreset(), and SetProperty().

Referenced by AudioUnitEffectBase::LoadFactoryPreset(), AudioUnitEffectBase::LoadSettings(), and StoreSettings().

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

◆ LoadPreset()

bool AudioUnitWrapper::LoadPreset ( const EffectDefinitionInterface effect,
const RegistryPath group,
EffectSettings settings 
) const

Definition at line 327 of file AudioUnitWrapper.cpp.

329{
330 // Retrieve the preset
331 wxString parms;
332 if (!GetConfig(effect, PluginSettings::Private, group, PRESET_KEY, parms,
333 wxEmptyString)) {
334 // Commented "CurrentSettings" gets tried a lot and useless messages appear
335 // in the log
336 //wxLogError(wxT("Preset key \"%s\" not found in group \"%s\""), PRESET_KEY, group);
337 return false;
338 }
339
340 // Decode it, complementary to what SaveBlobToConfig did
341 auto error =
342 InterpretBlob(GetSettings(settings), group, wxBase64Decode(parms));
343 if (!error.empty()) {
344 wxLogError(error.Debug());
345 return false;
346 }
347
348 return true;
349}
#define PRESET_KEY
bool GetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, Value &var, const Value &defval)
TranslatableString InterpretBlob(AudioUnitEffectSettings &settings, const wxString &group, const wxMemoryBuffer &buf) const
Interpret the dump made before by MakeBlob.

References PluginSettings::GetConfig(), GetSettings(), InterpretBlob(), PRESET_KEY, PluginSettings::Private, and settings().

Referenced by LoadFactoryPreset(), and AudioUnitEffectBase::LoadPreset().

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

◆ MakeBlob()

std::pair< CF_ptr< CFDataRef >, TranslatableString > AudioUnitWrapper::MakeBlob ( const EffectDefinitionInterface effect,
const AudioUnitEffectSettings settings,
const wxCFStringRef &  cfname,
bool  binary 
) const

Obtain dump of the setting state of an AudioUnit instance.

Parameters
binaryif false, then produce XML serialization instead; but AudioUnits does not need to be told the format again to reinterpret the blob
Returns
smart pointer to data, and an error message

Definition at line 385 of file AudioUnitWrapper.cpp.

388{
389 // This is a const function of AudioUnitEffect, but it mutates
390 // an AudioUnit object (mUnit.get()) to accomplish its work. But that
391 // should be the "scratchpad" unit only, not real instance state.
392
393 // Update state of the unit from settings
394 StoreSettings(effect, settings);
395
396 CF_ptr<CFDataRef> data;
397 TranslatableString message;
398
399 // Define the preset property and set it in the audio unit
400 if (SetProperty(
401 kAudioUnitProperty_PresentPreset, AudioUnitUtils::UserPreset{ cfname }))
402 message = XO("Failed to set preset name");
403
404 // Now retrieve the preset content
405 else if (CF_ptr<CFPropertyListRef> content;
406 GetFixedSizeProperty(kAudioUnitProperty_ClassInfo, content))
407 message = XO("Failed to retrieve preset content");
408
409 // And convert it to serialized XML data
410 else if (data.reset(CFPropertyListCreateData(kCFAllocatorDefault,
411 content.get(),
412 (binary ? PRESET_FORMAT : kCFPropertyListXMLFormat_v1_0), 0,
413 // TODO might retrieve more error information
414 nullptr));
415 !data)
416 message = XO("Failed to convert property list to XML data");
417
418 // Nothing to do if we don't have any data
419 else if (auto length = CFDataGetLength(data.get()); length == 0)
420 // Caller might not treat this as error, becauase data is non-null
421 message = XO("XML data is empty after conversion");
422
423 return { move(data), message };
424}
#define PRESET_FORMAT
Holds a msgid for the translation catalog; may also bind format arguments.
bool StoreSettings(const EffectDefinitionInterface &effect, const AudioUnitEffectSettings &settings) const

References GetFixedSizeProperty(), PRESET_FORMAT, SetProperty(), settings(), StoreSettings(), and XO().

Referenced by AudioUnitEffectBase::Export(), and AudioUnitEffectBase::SavePreset().

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

◆ MoveSettingsContents()

bool AudioUnitWrapper::MoveSettingsContents ( AudioUnitEffectSettings &&  src,
AudioUnitEffectSettings dst,
bool  merge 
)
static

Copy, then clear the optionals in src.

Definition at line 240 of file AudioUnitWrapper.cpp.

242{
243 // Do an in-place rewrite of dst, avoiding allocations
244 auto &dstMap = dst.values;
245 auto dstIter = dstMap.begin(), dstEnd = dstMap.end();
246 auto &srcMap = src.values;
247 for (auto &[key, oValue] : srcMap) {
248 while (dstIter != dstEnd && dstIter->first != key)
249 ++dstIter;
250 if (dstIter == dstEnd)
251 break;
252 auto &[dstKey, dstOValue] = *dstIter;
253 assert(dstKey == key);
254 if (oValue) {
255 dstOValue.emplace(*oValue);
256 oValue.reset();
257 }
258 else if (!merge)
259 // Don't accumulate non-nulls only, but copy the nulls
260 dstOValue.reset();
261 }
262 return true;
263}
static const AudacityProject::AttachedObjects::RegisteredFactory key

References key, and AudioUnitEffectSettings::values.

Referenced by anonymous_namespace{AudioUnitInstance.cpp}::AudioUnitMessage::Assign(), and anonymous_namespace{AudioUnitInstance.cpp}::AudioUnitMessage::Merge().

Here is the caller graph for this function:

◆ SetProperty()

template<typename T >
OSStatus AudioUnitWrapper::SetProperty ( AudioUnitPropertyID  inID,
const T &  property,
AudioUnitScope  inScope = kAudioUnitScope_Global,
AudioUnitElement  inElement = 0 
) const
inline

Definition at line 131 of file AudioUnitWrapper.h.

134 {
135 // Supply mUnit.get() to the non-member function
137 inID, property, inScope, inElement);
138 }
OSStatus SetProperty(AudioUnit unit, AudioUnitPropertyID inID, const T &property, AudioUnitScope inScope=kAudioUnitScope_Global, AudioUnitElement inElement=0)

References mUnit, and AudioUnitUtils::SetProperty().

Referenced by AudioUnitInstance::BypassEffect(), InterpretBlob(), LoadFactoryPreset(), MakeBlob(), AudioUnitInstance::ProcessInitialize(), and SetRateAndChannels().

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

◆ SetRateAndChannels()

bool AudioUnitWrapper::SetRateAndChannels ( double  sampleRate,
const wxString &  identifier 
)

Definition at line 426 of file AudioUnitWrapper.cpp.

428{
430 // Float64 mSampleRate;
432
433 // UInt32 mFormatID;
434 kAudioFormatLinearPCM,
435
436 // UInt32 mFormatFlags;
437 (kAudioFormatFlagsNativeFloatPacked |
438 kAudioFormatFlagIsNonInterleaved),
439
440 // UInt32 mBytesPerPacket;
441 sizeof(float),
442
443 // UInt32 mFramesPerPacket;
444 1,
445
446 // UInt32 mBytesPerFrame;
447 sizeof(float),
448
449 // UInt32 mChannelsPerFrame;
450 0,
451
452 // UInt32 mBitsPerChannel;
453 sizeof(float) * 8,
454 };
455
456 unsigned one = 1u;
457 const struct Info{
458 unsigned &nChannels;
459 AudioUnitScope scope;
460 const char *const msg; // used only in log messages
461 } infos[]{
462 { one, kAudioUnitScope_Global, "global" },
463 { mAudioIns, kAudioUnitScope_Input, "input" },
464 { mAudioOuts, kAudioUnitScope_Output, "output" },
465 };
466 for (const auto &[nChannels, scope, msg] : infos) {
467 if (nChannels) {
468 if (SetProperty(kAudioUnitProperty_SampleRate, sampleRate, scope)) {
469 wxLogError("%ls Didn't accept sample rate on %s\n",
470 // Exposing internal name only in logging
471 identifier.wx_str(), msg);
472 return false;
473 }
474 if (scope != kAudioUnitScope_Global) {
475 bool failed = true;
476 ++nChannels;
477 do {
478 --nChannels;
479 streamFormat.mChannelsPerFrame = nChannels;
480 failed = SetProperty(kAudioUnitProperty_StreamFormat,
481 streamFormat, scope);
482 } while(failed && nChannels > 0);
483 if (failed) {
484 wxLogError("%ls didn't accept stream format on %s\n",
485 // Exposing internal name only in logging
486 identifier.wx_str(), msg);
487 return false;
488 }
489 }
490 }
491 }
492 return true;
493}
static CommandContext::TargetFactory::SubstituteInUnique< InteractiveOutputTargets > scope

References mAudioIns, mAudioOuts, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, anonymous_namespace{wxCommandTargets.cpp}::scope, and SetProperty().

Referenced by AudioUnitEffectBase::InitializePlugin(), and AudioUnitInstance::ProcessInitialize().

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

◆ StoreSettings()

bool AudioUnitWrapper::StoreSettings ( const EffectDefinitionInterface effect,
const AudioUnitEffectSettings settings 
) const

Definition at line 189 of file AudioUnitWrapper.cpp.

191{
192 // This is a const member function inherited by AudioUnitEffect, though it
193 // mutates the AudioUnit object (mUnit.get()). This is necessary for the
194 // AudioUnitEffect (an EffectPlugin) to compute the "blob" of settings state
195 // for export or to save settings in the config file, which the SDK later
196 // reinterprets.
197 // So consider mUnit a mutable scratch pad object. This doesn't really make
198 // the AudioUnitEffect stateful.
199
200 // First restore factory preset if it applies
201 if (settings.mPresetNumber) {
202 // Mutate the scratch AudioUnit, don't pass settings
203 LoadFactoryPreset(effect, *settings.mPresetNumber, nullptr);
204 // Then go on to reapply some slider changes that might have been done
205 // after a change of preset
206 }
207
208 // Update parameter values in the AudioUnit from const
209 // AudioUnitEffectSettings
210 // Allow two passes; because sometimes the re-assignability of one parameter
211 // depends on first doing it for another parameter, but the other is later
212 // in the iteration. For instance, for AUGraphicEQ, parameter ID 10000
213 // (decimal) determines 10 or 31 bands, but while the effect is still set
214 // for 10, then assignment to the last 21 sliders fails.
215 for (auto pass : {0, 1}) {
217 ] (const ParameterInfo &pi, AudioUnitParameterID ID) {
218 if (pi.mName) {
219 if (auto iter = settings.values.find(ID);
220 iter != settings.values.end() && iter->second.has_value()
221 ){
222 if (AudioUnitSetParameter(mUnit.get(), ID,
223 kAudioUnitScope_Global, 0, iter->second->second, 0)) {
224 // Probably failed because of an invalid parameter when
225 // a plug-in is in a certain mode that doesn't contain
226 // the parameter.
227 }
228 }
229 else {
230 // Leave parameters that are in the AudioUnit, but not known in
231 // settings, unchanged
232 }
233 }
234 return true;
235 });
236 }
237 return true;
238}
bool LoadFactoryPreset(const EffectDefinitionInterface &effect, int id, EffectSettings *pSettings) const

References ForEachParameter(), LoadFactoryPreset(), MIR::anonymous_namespace{MirUtils.cpp}::pi, and settings().

Referenced by MakeBlob(), AudioUnitInstance::ProcessInitialize(), and AudioUnitEditor::StoreSettingsToInstance().

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

Member Data Documentation

◆ mAudioIns

unsigned AudioUnitWrapper::mAudioIns { 2 }
protected

◆ mAudioOuts

unsigned AudioUnitWrapper::mAudioOuts { 2 }
protected

◆ mComponent

const AudioComponent AudioUnitWrapper::mComponent
protected

◆ mOwnParameters

Parameters AudioUnitWrapper::mOwnParameters
protected

Definition at line 194 of file AudioUnitWrapper.h.

Referenced by CreateAudioUnit().

◆ mParameters

Parameters& AudioUnitWrapper::mParameters
protected

◆ mUnit

AudioUnitCleanup<AudioUnit, AudioComponentInstanceDispose> AudioUnitWrapper::mUnit
protected

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