mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
162 lines
5.6 KiB
Objective-C
162 lines
5.6 KiB
Objective-C
/*!
|
|
@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
|