forked from juce-framework/JUCE
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ComponentBase.h
162 lines (132 loc) · 5.59 KB
/
ComponentBase.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*!
@file AudioUnitSDK/ComponentBase.h
@copyright © 2000-2021 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_ComponentBase_h
#define AudioUnitSDK_ComponentBase_h
// module
#include <AudioUnitSDK/AUUtility.h>
// OS
#include <AudioToolbox/AudioUnit.h>
// std
#include <array>
#include <mutex>
#include <new>
namespace ausdk {
/*!
@class ComponentBase
@brief Base class for implementing an `AudioComponentInstance`.
*/
class ComponentBase {
public:
/// Construct given an AudioComponentInstance, typically from APFactory::Constuct.
explicit ComponentBase(AudioComponentInstance inInstance);
virtual ~ComponentBase() = default;
ComponentBase(const ComponentBase&) = delete;
ComponentBase(ComponentBase&&) = delete;
ComponentBase& operator=(const ComponentBase&) = delete;
ComponentBase& operator=(ComponentBase&&) = delete;
/// Called from dispatchers after constructing an instance.
void DoPostConstructor();
/// Called from dispatchers before destroying an instance.
void DoPreDestructor();
/// Obtain the wrapped `AudioComponentInstance` (underlying type of `AudioUnit`, `AudioCodec`,
/// and others).
[[nodiscard]] AudioComponentInstance GetComponentInstance() const noexcept
{
return mComponentInstance;
}
/// Return the instance's `AudioComponentDescription`.
[[nodiscard]] AudioComponentDescription GetComponentDescription() const;
/// Component dispatch method.
static OSStatus AP_Open(void* self, AudioComponentInstance compInstance);
/// Component dispatch method.
static OSStatus AP_Close(void* self);
/// A mutex which is held during `Open`, since some AU's and the Component Manager itself
/// are not thread-safe against globals.
static std::recursive_mutex& InitializationMutex();
protected:
// subclasses are free to to override these methods to add functionality
virtual void PostConstructor() {}
virtual void PreDestructor() {}
// these methods, however, are reserved for override only within this SDK
virtual void PostConstructorInternal() {}
virtual void PreDestructorInternal() {}
private:
AudioComponentInstance mComponentInstance;
};
/*!
@class AudioComponentPlugInInstance
@brief Object which implements an AudioComponentPlugInInterface for the framework, and
which holds the C++ implementation object.
*/
struct AudioComponentPlugInInstance {
// The AudioComponentPlugInInterface must remain first
AudioComponentPlugInInterface mPlugInInterface;
void* (*mConstruct)(void* memory, AudioComponentInstance ci);
void (*mDestruct)(void* memory);
std::array<void*, 2> mPad; // pad to a 16-byte boundary (in either 32 or 64 bit mode)
UInt32
mInstanceStorage; // the ACI implementation object is constructed into this memory
// this member is just a placeholder. it is aligned to a 16byte boundary
};
/*!
@class APFactory
@tparam APMethodLookup A class (e.g. AUBaseLookup) which provides a method selector lookup
function.
@tparam Implementor The class which implements the full plug-in (AudioUnit) interface.
@brief Provides an AudioComponentFactoryFunction and a convenience wrapper for
AudioComponentRegister.
*/
template <class APMethodLookup, class Implementor>
class APFactory {
public:
static void* Construct(void* memory, AudioComponentInstance compInstance)
{
return new (memory) Implementor(compInstance); // NOLINT manual memory management
}
static void Destruct(void* memory) { static_cast<Implementor*>(memory)->~Implementor(); }
// This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance.
// The actual implementation object is not created until Open().
static AudioComponentPlugInInterface* Factory(const AudioComponentDescription* /* inDesc */)
{
auto* const acpi = // NOLINT owning memory
static_cast<AudioComponentPlugInInstance*>(malloc( // NOLINT manual memory management
offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor)));
acpi->mPlugInInterface.Open = ComponentBase::AP_Open;
acpi->mPlugInInterface.Close = ComponentBase::AP_Close;
acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup;
acpi->mPlugInInterface.reserved = nullptr;
acpi->mConstruct = Construct;
acpi->mDestruct = Destruct;
acpi->mPad[0] = nullptr;
acpi->mPad[1] = nullptr;
return &acpi->mPlugInInterface;
}
// This is for runtime registration (not for plug-ins loaded from bundles).
static AudioComponent Register(
UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags = 0)
{
const AudioComponentDescription desc = { type, subtype, manuf, flags, 0 };
return AudioComponentRegister(&desc, name, vers, Factory);
}
};
#ifndef AUSDK_EXPORT
#if __GNUC__
#define AUSDK_EXPORT __attribute__((visibility("default"))) // NOLINT
#else
#warning export?
#endif
#endif
/// Macro to generate the factory function for the specified Audio Component. Factory is an
/// APFactory such as AUBaseFactory. Class is the name of the final ComponentBase class which
/// implements instances of the class.
#define AUSDK_COMPONENT_ENTRY(FactoryType, Class) /* NOLINT macro */ \
AUSDK_EXPORT \
extern "C" void* Class##Factory(const AudioComponentDescription* inDesc); \
extern "C" void* Class##Factory(const AudioComponentDescription* inDesc) \
{ \
return FactoryType<Class>::Factory(inDesc); /* NOLINT parens */ \
}
} // namespace ausdk
#endif // AudioUnitSDK_ComponentBase_h