AUPublic/AUBase/ComponentBase.cpp
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Part of Core Audio AUBase Classes |
*/ |
#include "ComponentBase.h" |
#include "CAXException.h" |
#if TARGET_OS_MAC |
pthread_mutex_t ComponentInitLocker::sComponentOpenMutex = PTHREAD_MUTEX_INITIALIZER; |
pthread_once_t ComponentInitLocker::sOnce = PTHREAD_ONCE_INIT; |
void ComponentInitLocker::InitComponentInitLocker() |
{ |
// have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP |
pthread_mutexattr_t attr; |
pthread_mutexattr_init(&attr); |
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); |
pthread_mutex_init(&sComponentOpenMutex, &attr); |
pthread_mutexattr_destroy(&attr); |
} |
#elif TARGET_OS_WIN32 |
CAGuard ComponentInitLocker::sComponentOpenGuard("sComponentOpenGuard"); |
#endif |
ComponentBase::EInstanceType ComponentBase::sNewInstanceType; |
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc); |
#if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_WIN32 |
static OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc); |
#endif |
ComponentBase::ComponentBase(AudioComponentInstance inInstance) |
: mComponentInstance(inInstance), |
mInstanceType(sNewInstanceType) |
{ |
GetComponentDescription(); |
} |
ComponentBase::~ComponentBase() |
{ |
} |
void ComponentBase::PostConstructor() |
{ |
} |
void ComponentBase::PreDestructor() |
{ |
} |
#define ACPI ((AudioComponentPlugInInstance *)self) |
#define ACImp ((ComponentBase *)&ACPI->mInstanceStorage) |
OSStatus ComponentBase::AP_Open(void *self, AudioUnit compInstance) |
{ |
OSStatus result = noErr; |
try { |
ComponentInitLocker lock; |
ComponentBase::sNewInstanceType = ComponentBase::kAudioComponentInstance; |
ComponentBase *cb = (ComponentBase *)(*ACPI->mConstruct)(&ACPI->mInstanceStorage, compInstance); |
cb->PostConstructor(); // allows base class to do additional initialization |
// once the derived class is fully constructed |
result = noErr; |
} |
COMPONENT_CATCH |
if (result) |
delete ACPI; |
return result; |
} |
OSStatus ComponentBase::AP_Close(void *self) |
{ |
OSStatus result = noErr; |
try { |
if (ACImp) { |
ACImp->PreDestructor(); |
(*ACPI->mDestruct)(&ACPI->mInstanceStorage); |
free(self); |
} |
} |
COMPONENT_CATCH |
return result; |
} |
#if !CA_USE_AUDIO_PLUGIN_ONLY |
OSStatus ComponentBase::Version() |
{ |
return 0x00000001; |
} |
OSStatus ComponentBase::ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This) |
{ |
if (This == NULL) return kAudio_ParamError; |
OSStatus result = noErr; |
switch (p->what) { |
case kComponentCloseSelect: |
This->PreDestructor(); |
delete This; |
break; |
case kComponentVersionSelect: |
result = This->Version(); |
break; |
case kComponentCanDoSelect: |
switch (GetSelectorForCanDo(p)) { |
case kComponentOpenSelect: |
case kComponentCloseSelect: |
case kComponentVersionSelect: |
case kComponentCanDoSelect: |
return 1; |
default: |
return 0; |
} |
default: |
result = badComponentSelector; |
break; |
} |
return result; |
} |
SInt16 ComponentBase::GetSelectorForCanDo(ComponentParameters *params) |
{ |
if (params->what != kComponentCanDoSelect) return 0; |
#if TARGET_CPU_X86 |
SInt16 sel = params->params[0]; |
#elif TARGET_CPU_X86_64 |
SInt16 sel = params->params[1]; |
#elif TARGET_CPU_PPC |
SInt16 sel = (params->params[0] >> 16); |
#else |
SInt16 sel = params->params[0]; |
#endif |
return sel; |
/* |
printf ("flags:%d, paramSize: %d, what: %d\n\t", params->flags, params->paramSize, params->what); |
for (int i = 0; i < params->paramSize; ++i) { |
printf ("[%d]:%d(0x%x), ", i, params->params[i], params->params[i]); |
} |
printf("\n\tsel:%d\n", sel); |
*/ |
} |
#endif |
#if CA_DO_NOT_USE_AUDIO_COMPONENT |
static OSStatus ComponentBase_GetComponentDescription (const AudioComponentInstance & inInstance, AudioComponentDescription &outDesc); |
#endif |
AudioComponentDescription ComponentBase::GetComponentDescription() const |
{ |
AudioComponentDescription desc; |
OSStatus result = 1; |
if (IsPluginObject()) { |
ca_require_noerr(result = CB_GetComponentDescription (mComponentInstance, &desc), home); |
} |
#if !CA_USE_AUDIO_PLUGIN_ONLY |
else { |
ca_require_noerr(result = CMgr_GetComponentDescription (mComponentInstance, &desc), home); |
} |
#endif |
home: |
if (result) |
memset (&desc, 0, sizeof(AudioComponentDescription)); |
return desc; |
} |
#if CA_USE_AUDIO_PLUGIN_ONLY |
// everything we need is there and we should be linking against it |
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) |
{ |
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance); |
if (comp) |
return AudioComponentGetDescription(comp, outDesc); |
return kAudio_ParamError; |
} |
#elif !TARGET_OS_WIN32 |
// these are the direct dependencies on ComponentMgr calls that an AU |
// that is a component mgr is dependent on |
// these are dynamically loaded so that these calls will work on Leopard |
#include <dlfcn.h> |
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) |
{ |
typedef AudioComponent (*AudioComponentInstanceGetComponentProc) (AudioComponentInstance); |
static AudioComponentInstanceGetComponentProc aciGCProc = NULL; |
typedef OSStatus (*AudioComponentGetDescriptionProc)(AudioComponent, AudioComponentDescription *); |
static AudioComponentGetDescriptionProc acGDProc = NULL; |
static int doneInit = 0; |
if (doneInit == 0) { |
doneInit = 1; |
void* theImage = dlopen("/System/Library/Frameworks/AudioUnit.framework/AudioUnit", RTLD_LAZY); |
if (theImage != NULL) |
{ |
aciGCProc = (AudioComponentInstanceGetComponentProc)dlsym (theImage, "AudioComponentInstanceGetComponent"); |
if (aciGCProc) { |
acGDProc = (AudioComponentGetDescriptionProc)dlsym (theImage, "AudioComponentGetDescription"); |
} |
} |
} |
OSStatus result = kAudio_UnimplementedError; |
if (acGDProc && aciGCProc) { |
AudioComponent comp = (*aciGCProc)(inInstance); |
if (comp) |
result = (*acGDProc)(comp, outDesc); |
} |
#if !CA_USE_AUDIO_PLUGIN_ONLY |
else { |
result = CMgr_GetComponentDescription (inInstance, outDesc); |
} |
#endif |
return result; |
} |
#if !CA_USE_AUDIO_PLUGIN_ONLY |
// these are the direct dependencies on ComponentMgr calls that an AU |
// that is a component mgr is dependent on |
// these are dynamically loaded |
#include <CoreServices/CoreServices.h> |
#include <AudioUnit/AudioUnit.h> |
#include "CAXException.h" |
#include "ComponentBase.h" |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
// Component Manager |
// Used for fast dispatch with audio units |
typedef Handle (*GetComponentInstanceStorageProc)(ComponentInstance aComponentInstance); |
static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL; |
typedef OSErr (*GetComponentInfoProc)(Component, ComponentDescription *, void*, void*, void*); |
static GetComponentInfoProc sGetComponentInfoProc = NULL; |
typedef void (*SetComponentInstanceStorageProc)(ComponentInstance, Handle); |
static SetComponentInstanceStorageProc sSetComponentInstanceStorageProc = NULL; |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
static void CSInitOnce(void* /*unused*/) |
{ |
void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY); |
if (!theImage) return; |
sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage"); |
sGetComponentInfoProc = (GetComponentInfoProc)dlsym (theImage, "GetComponentInfo"); |
sSetComponentInstanceStorageProc = (SetComponentInstanceStorageProc) dlsym(theImage, "SetComponentInstanceStorage"); |
} |
#if TARGET_OS_MAC |
#include <dispatch/dispatch.h> |
static dispatch_once_t sCSInitOnce = 0; |
static void CSInit () |
{ |
dispatch_once_f(&sCSInitOnce, NULL, CSInitOnce); |
} |
#else |
static void CSInit () |
{ |
static int sDoCSLoad = 1; |
if (sDoCSLoad) { |
sDoCSLoad = 0; |
CSInitOnce(NULL); |
} |
} |
#endif |
OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) |
{ |
CSInit(); |
if (sGetComponentInfoProc) |
return (*sGetComponentInfoProc)((Component)inInstance, (ComponentDescription*)outDesc, NULL, NULL, NULL); |
return kAudio_UnimplementedError; |
} |
Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance) |
{ |
CSInit(); |
if (sGetComponentInstanceStorageProc) |
return (*sGetComponentInstanceStorageProc)(aComponentInstance); |
return NULL; |
} |
void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage) |
{ |
CSInit(); |
if (sSetComponentInstanceStorageProc) |
(*sSetComponentInstanceStorageProc)(aComponentInstance, theStorage); |
} |
#endif // !CA_USE_AUDIO_PLUGIN_ONLY |
#else |
//#include "ComponentManagerDependenciesWin.h" |
// everything we need is there and we should be linking against it |
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) |
{ |
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance); |
if (comp) |
return AudioComponentGetDescription(comp, outDesc); |
return kAudio_ParamError; |
} |
#endif |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-02-19