Audacity 3.2.0
AudioUnitEffectsModule.cpp
Go to the documentation of this file.
1/*!********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file AudioUnitEffectsModule.cpp
6
7 Dominic Mazzoni
8 Leland Lucius
9
10 Paul Licameli split from AudioUnitEffect.
11
12**********************************************************************/
13
14#if USE_AUDIO_UNITS
16
17#include "AudioUnitEffect.h"
18#include "ModuleManager.h"
19#include <wx/log.h>
20#include <wx/tokenzr.h>
21
22#include "wxArrayStringEx.h"
23#include <wx/osx/core/private.h>
24
25static const struct
26{
30}
31BlackList[] =
32{
33 { 'appl', 'augn', 'afpl' }, // Apple: AUAudioFilePlayer
34 { 'appl', 'augn', 'sspl' }, // Apple: AUScheduledSoundPlayer
35 { 'appl', 'augn', 'ttsp' }, // Apple: AUSpeechSynthesis
36 { 'appl', 'augn', 'nrcv' }, // Apple: AUNetReceive
37 { 'appl', 'aumx', '3dmx' }, // Apple: AUMixer3D
38 { 'appl', 'aumx', 'mspl' }, // Apple: AUMultiSplitter
39 { 'appl', 'aumx', 'mcmx' }, // Apple: AUMultiChannelMixer
40 { 'appl', 'aumx', 'mxmx' }, // Apple: AUMatrixMixer
41 { 'appl', 'aumx', 'smxr' }, // Apple: AUMixer
42 { 'Ignt', 'aufx', 'PTQX' }, // Ignite Amps PTEq-X
43};
44
45// ============================================================================
46// Module registration entry point
47//
48// This is the symbol that Audacity looks for when the module is built as a
49// dynamic library.
50//
51// When the module is builtin to Audacity, we use the same function, but it is
52// declared static so as not to clash with other builtin modules.
53// ============================================================================
55{
56 // Create and register the importer
57 // Trust the module manager not to leak this
58 return std::make_unique<AudioUnitEffectsModule>();
59}
60
61// ============================================================================
62// Register this as a builtin module
63// ============================================================================
64DECLARE_BUILTIN_PROVIDER(AudioUnitEffectsBuiltin);
65
67//
68// AudioUnitEffectsModule
69//
71
72
73namespace
74{
75
76wxString FromOSType(OSType type)
77{
78 OSType rev = (type & 0xff000000) >> 24 |
79 (type & 0x00ff0000) >> 8 |
80 (type & 0x0000ff00) << 8 |
81 (type & 0x000000ff) << 24;
82
83 return wxString::FromUTF8(reinterpret_cast<char *>(&rev), 4);
84}
85
86OSType ToOSType(const wxString & type)
87{
88 wxCharBuffer buf = type.ToUTF8();
89
90 OSType rev = ((unsigned char)buf.data()[0]) << 24 |
91 ((unsigned char)buf.data()[1]) << 16 |
92 ((unsigned char)buf.data()[2]) << 8 |
93 ((unsigned char)buf.data()[3]);
94
95 return rev;
96}
97
98AudioComponent FindAudioUnit(const PluginPath & path,
99 wxString & name)
100{
101 wxStringTokenizer tokens(path, wxT("/"));
102
103 AudioComponentDescription desc;
104
105 desc.componentManufacturer = ToOSType(tokens.GetNextToken());
106 desc.componentType = ToOSType(tokens.GetNextToken());
107 desc.componentSubType = ToOSType(tokens.GetNextToken());
108 desc.componentFlags = 0;
109 desc.componentFlagsMask = 0;
110
111 name = tokens.GetNextToken();
112 return AudioComponentFindNext(NULL, &desc);
113}
114
115}
116
118{
119}
120
122{
123}
124
125// ============================================================================
126// ComponentInterface implementation
127// ============================================================================
128
130{
131 return {};
132}
133
135{
136 /* i18n-hint: Audio Unit is the name of an Apple audio software protocol */
137 return XO("Audio Unit Effects");
138}
139
141{
142 return XO("The Audacity Team");
143}
144
146{
147 // This "may" be different if this were to be maintained as a separate DLL
149}
150
152{
153 return XO("Provides Audio Unit Effects support to Audacity");
154}
155
156// ============================================================================
157// PluginProvider implementation
158// ============================================================================
159
161{
162 static FileExtensions result{{ _T("au") }};
163 return result;
164}
165
167{
168 // Nothing to do here
169 return true;
170}
171
173{
174 // Nothing to do here
175 return;
176}
177
179{
180#if USE_AUDIO_UNITS
182#else
183 return {};
184#endif
185}
186
188{
189}
190
192{
193 PluginPaths effects;
194
195 LoadAudioUnitsOfType(kAudioUnitType_Effect, effects);
196 LoadAudioUnitsOfType(kAudioUnitType_Generator, effects);
197 LoadAudioUnitsOfType(kAudioUnitType_Mixer, effects);
198 LoadAudioUnitsOfType(kAudioUnitType_MusicEffect, effects);
199 LoadAudioUnitsOfType(kAudioUnitType_Panner, effects);
200
201 return effects;
202}
203
205 const PluginPath & path, TranslatableString &errMsg,
206 const RegistrationCallback &callback)
207{
208 errMsg = {};
209 wxString name;
210 AudioComponent component = FindAudioUnit(path, name);
211 if (component == NULL)
212 {
213 errMsg = XO("Could not find component");
214 return 0;
215 }
216
217 AudioUnitEffect effect(path, name, component);
218 if (!effect.InitializePlugin())
219 {
220 // TODO: Is it worth it to discriminate all the ways SetHost might
221 // return false?
222 errMsg = XO("Could not initialize component");
223 return 0;
224 }
225
226 if (callback)
227 {
228 callback(this, &effect);
229 }
230
231 return 1;
232}
233
234std::unique_ptr<ComponentInterface>
236{
237 // Acquires a resource for the application.
238 if (wxString name; auto component = FindAudioUnit(path, name)) {
239 auto result = std::make_unique<AudioUnitEffect>(path, name, component);
240 result->FullyInitializePlugin();
241 return result;
242 }
243 return nullptr;
244}
245
247{
248 wxString unused;
249 return FindAudioUnit(path, unused) != nullptr;
250}
251
252// ============================================================================
253// AudioUnitEffectsModule implementation
254// ============================================================================
255
257 PluginPaths & effects)
258{
259 AudioComponentDescription desc;
260 AudioComponent component;
261
262 desc.componentType = inAUType;
263 desc.componentSubType = 0;
264 desc.componentManufacturer = 0;
265 desc.componentFlags = 0;
266 desc.componentFlagsMask = 0;
267
268 component = AudioComponentFindNext(NULL, &desc);
269 while (component != NULL)
270 {
271 OSStatus result;
272 AudioComponentDescription found;
273
274 result = AudioComponentGetDescription(component, &found);
275 if (result == noErr)
276 {
277 CFStringRef cfName{};
278 result = AudioComponentCopyName(component, &cfName);
279 CF_ptr<CFStringRef> uName{ cfName };
280 if (result == noErr) {
281 wxString path;
282
283 path.Printf(wxT("%-4.4s/%-4.4s/%-4.4s/%s"),
284 FromOSType(found.componentManufacturer),
285 FromOSType(found.componentType),
286 FromOSType(found.componentSubType),
287 wxCFStringRef::AsString(cfName));
288
289 for (int i = 0; i < WXSIZEOF(BlackList); ++i) {
290 if (BlackList[i].componentType == found.componentType &&
291 BlackList[i].componentSubType == found.componentSubType &&
292 BlackList[i].componentManufacturer ==
293 found.componentManufacturer) {
294 wxLogDebug(wxT("Blacklisted AU skipped: %s"), path);
295 result = !noErr;
296 break;
297 }
298 }
299 if (result == noErr)
300 effects.push_back(path);
301 }
302 }
303 component = AudioComponentFindNext(component, &desc);
304 }
305}
306
307#endif
wxT("CloseDown"))
#define AUDIOUNITEFFECTS_VERSION
#define AUDIOUNITEFFECTS_FAMILY
DECLARE_PROVIDER_ENTRY(AudacityModule)
OSType componentManufacturer
OSType componentType
DECLARE_BUILTIN_PROVIDER(AudioUnitEffectsBuiltin)
OSType componentSubType
static const struct @14 BlackList[]
const TranslatableString name
Definition: Distortion.cpp:82
const TranslatableString desc
Definition: ExportPCM.cpp:58
std::vector< PluginPath > PluginPaths
Definition: Identifier.h:215
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
#define XO(s)
Definition: Internat.h:31
An Effect class that handles a wide range of effects. ??Mac only??
const FileExtensions & GetFileExtensions() override
File types associated with this protocol.
void Terminate() override
Called just prior to deletion to allow releasing any resources.
bool CheckPluginExist(const PluginPath &path) const override
Performs plugin/module existence check, still plugin may fail to load. Implementation should avoid lo...
EffectFamilySymbol GetOptionalFamilySymbol() override
A symbol identifying the family of plug-ins provided by this.
wxString GetVersion() const override
PluginPaths FindModulePaths(PluginManagerInterface &pm) override
void LoadAudioUnitsOfType(OSType inAUType, PluginPaths &effects)
bool Initialize() override
Called immediately after creation. Let provider initialize.
ComponentInterfaceSymbol GetSymbol() const override
void AutoRegisterPlugins(PluginManagerInterface &pm) override
Called so that a provider of a static set of plug-ins can register them.
PluginPath GetPath() const override
VendorSymbol GetVendor() const override
unsigned DiscoverPluginsAtPath(const PluginPath &path, TranslatableString &errMsg, const RegistrationCallback &callback) override
std::unique_ptr< ComponentInterface > LoadPlugin(const PluginPath &path) override
Load the plug-in at a path reported by DiscoverPluginsAtPath.
TranslatableString GetDescription() const override
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
std::function< const PluginID &(PluginProvider *, ComponentInterface *) > RegistrationCallback
Further expand a path reported by FindModulePaths.
Holds a msgid for the translation catalog; may also bind format arguments.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
AudioComponent FindAudioUnit(const PluginPath &path, wxString &name)