void HP_Stream::PropertiesChanged(UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[]) const { // note that we need to be sure that the object state mutex is not held while we call the listeners bool ownsStateMutex = false; CAMutex* theObjectStateMutex = const_cast<HP_Object*>(this)->GetObjectStateMutex(); if(theObjectStateMutex != NULL) { ownsStateMutex = theObjectStateMutex->IsOwnedByCurrentThread(); if(ownsStateMutex) { theObjectStateMutex->Unlock(); } } for(UInt32 theIndex = 0; theIndex < inNumberAddresses; ++theIndex) { OSStatus theError = AudioHardwareStreamPropertyChanged(mPlugIn->GetInterface(), mOwningDevice->GetObjectID(), mObjectID, inAddresses[theIndex].mElement, inAddresses[theIndex].mSelector); AssertNoError(theError, "HP_Stream::PropertiesChanged: got an error calling the input listeners"); } // re-lock the mutex if((theObjectStateMutex != NULL) && ownsStateMutex) { theObjectStateMutex->Lock(); } }
static OSStatus HP_HardwarePlugIn_DeviceGetPropertyInfo(AudioHardwarePlugInRef inSelf, AudioDeviceID inDeviceID, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32* outSize, Boolean* outWritable) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_DeviceGetPropertyInfo: no plug-in"); // find the device for the given ID HP_Device* theDevice = HP_Object::GetDeviceByID(inDeviceID); ThrowIfNULL(theDevice, CAException(kAudioHardwareBadDeviceError), "HP_HardwarePlugIn_DeviceGetPropertyInfo: no device with given ID"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inDeviceID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); // re-find the object for the given ID since it may have changed while we blocked waiting for the lock theDevice = HP_Object::GetDeviceByID(inDeviceID); ThrowIfNULL(theDevice, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_DeviceGetPropertyInfo: no device with given ID after locking"); } // construct a property address CAPropertyAddress theAddress(inPropertyID, isInput == 0 ? kAudioDevicePropertyScopeOutput : kAudioDevicePropertyScopeInput, inChannel); // do the work ThrowIf(!theDevice->HasProperty(theAddress), CAException(kAudioHardwareUnknownPropertyError), "HP_HardwarePlugIn_DeviceGetPropertyInfo: no such property"); if(outSize != NULL) { *outSize = theDevice->GetPropertyDataSize(theAddress, 0, NULL); } if(outWritable != NULL) { *outWritable = theDevice->IsPropertySettable(theAddress) ? 1 : 0; } } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
static OSStatus HP_HardwarePlugIn_StreamGetPropertyInfo(AudioHardwarePlugInRef inSelf, AudioStreamID inStreamID, UInt32 inChannel, AudioDevicePropertyID inPropertyID, UInt32* outSize, Boolean* outWritable) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_StreamGetPropertyInfo: no plug-in"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inStreamID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); } // find the stream for the given ID HP_Stream* theStream = HP_Object::GetStreamByID(inStreamID); ThrowIfNULL(theStream, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_StreamGetPropertyInfo: no device with given ID after locking"); // construct a property address CAPropertyAddress theAddress(inPropertyID, kAudioObjectPropertyScopeGlobal, inChannel); // do the work ThrowIf(!theStream->HasProperty(theAddress), CAException(kAudioHardwareUnknownPropertyError), "HP_HardwarePlugIn_StreamGetPropertyInfo: no such property"); if(outSize != NULL) { *outSize = theStream->GetPropertyDataSize(theAddress, 0, NULL); } if(outWritable != NULL) { *outWritable = theStream->IsPropertySettable(theAddress) ? 1 : 0; } } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
static OSStatus HP_HardwarePlugIn_StreamGetProperty(AudioHardwarePlugInRef inSelf, AudioStreamID inStreamID, UInt32 inChannel, AudioDevicePropertyID inPropertyID, UInt32* ioPropertyDataSize, void* outPropertyData) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_StreamGetProperty: no plug-in"); ThrowIfNULL(ioPropertyDataSize, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_StreamGetProperty: no data size"); // find the stream for the given ID HP_Stream* theStream = HP_Object::GetStreamByID(inStreamID); ThrowIfNULL(theStream, CAException(kAudioHardwareBadStreamError), "HP_HardwarePlugIn_StreamGetProperty: no stream with given ID"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inStreamID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); // re-find the object for the given ID since it may have changed while we blocked waiting for the lock theStream = HP_Object::GetStreamByID(inStreamID); ThrowIfNULL(theStream, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_StreamGetProperty: no device with given ID after locking"); } // construct a property address CAPropertyAddress theAddress(inPropertyID, kAudioObjectPropertyScopeGlobal, inChannel); // do the work theStream->GetPropertyData(theAddress, 0, NULL, *ioPropertyDataSize, outPropertyData); } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
static OSStatus HP_HardwarePlugIn_ObjectGetPropertyData(AudioHardwarePlugInRef inSelf, AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32* ioDataSize, void* outData) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectGetPropertyData: no plug-in"); ThrowIfNULL(inAddress, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectGetPropertyData: no address"); ThrowIfNULL(ioDataSize, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectGetPropertyData: no info about the size of the property data"); // find the object for the given ID HP_Object* theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectGetPropertyData: no object with given ID"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inObjectID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); // re-find the object for the given ID since it may have changed while we blocked waiting for the lock theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectGetPropertyData: no object with given ID after locking"); } // do the work theObject->GetPropertyData(*inAddress, inQualifierDataSize, inQualifierData, *ioDataSize, outData); } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
static OSStatus HP_HardwarePlugIn_ObjectIsPropertySettable(AudioHardwarePlugInRef inSelf, AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, Boolean* outIsSettable) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectIsPropertySettable: no plug-in"); ThrowIfNULL(inAddress, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectIsPropertySettable: no address"); ThrowIfNULL(outIsSettable, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectIsPropertySettable: no place to store return value"); // find the object for the given ID HP_Object* theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectIsPropertySettable: no object with given ID"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inObjectID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); // re-find the object for the given ID since it may have changed while we blocked waiting for the lock theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectIsPropertySettable: no object with given ID after locking"); } // do the work *outIsSettable = theObject->IsPropertySettable(*inAddress); } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
static Boolean HP_HardwarePlugIn_ObjectHasProperty(AudioHardwarePlugInRef inSelf, AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress) { Boolean theAnswer = false; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectHasProperty: no plug-in"); ThrowIfNULL(inAddress, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_ObjectHasProperty: no address"); // find the object for the given ID HP_Object* theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectHasProperty: no object with given ID"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inObjectID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); // re-find the object for the given ID since it may have changed while we blocked waiting for the lock theObject = HP_Object::GetObjectByID(inObjectID); ThrowIfNULL(theObject, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_ObjectHasProperty: no object with given ID after locking"); } // do the work theAnswer = theObject->HasProperty(*inAddress); } catch(const CAException& inException) { theAnswer = false; } catch(...) { theAnswer = false; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theAnswer; }
static OSStatus HP_HardwarePlugIn_DeviceGetProperty(AudioHardwarePlugInRef inSelf, AudioDeviceID inDeviceID, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32* ioPropertyDataSize, void* outPropertyData) { OSStatus theError = kAudioHardwareNoError; CAMutex* theObjectStateMutex = NULL; bool theObjectStateMutexNeedsUnlocking = false; try { // check the function arguments ThrowIfNULL(inSelf, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_DeviceGetProperty: no plug-in"); ThrowIfNULL(ioPropertyDataSize, CAException(kAudioHardwareIllegalOperationError), "HP_HardwarePlugIn_DeviceGetProperty: no data size"); // get the object state mutex theObjectStateMutex = HP_Object::GetObjectStateMutexByID(inDeviceID); // lock the mutex if(theObjectStateMutex != NULL) { theObjectStateMutexNeedsUnlocking = theObjectStateMutex->Lock(); } // find the device for the given ID HP_Device* theDevice = HP_Object::GetDeviceByID(inDeviceID); ThrowIfNULL(theDevice, CAException(kAudioHardwareBadObjectError), "HP_HardwarePlugIn_DeviceGetProperty: no device with given ID after locking"); // construct a property address CAPropertyAddress theAddress(inPropertyID, isInput == 0 ? kAudioDevicePropertyScopeOutput : kAudioDevicePropertyScopeInput, inChannel); // do the work theDevice->GetPropertyData(theAddress, 0, NULL, *ioPropertyDataSize, outPropertyData); } catch(const CAException& inException) { theError = inException.GetError(); } catch(...) { theError = kAudioHardwareUnspecifiedError; } // unlock the object state mutex if we need to if((theObjectStateMutex != NULL) && theObjectStateMutexNeedsUnlocking) { theObjectStateMutex->Unlock(); } return theError; }
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // SendNotification() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void ScheduledOutputNotificationProc::SendNotification(UInt64 sequenceNumberOfBufferThatWasOutput, UInt64 outputHostTime) { CAMutex* objectStateMutex = mOwningStream.GetObjectStateMutex(); bool objectStateMutexNeedsUnlocking = false; try { if (objectStateMutex != NULL) objectStateMutexNeedsUnlocking = objectStateMutex->Lock(); if (mScheduledOutputNotificationProc.scheduledOutputNotificationProc) (mScheduledOutputNotificationProc.scheduledOutputNotificationProc)(sequenceNumberOfBufferThatWasOutput, outputHostTime, mScheduledOutputNotificationProc.scheduledOutputNotificationRefCon); } catch (...) { } if (objectStateMutexNeedsUnlocking) objectStateMutex->Unlock(); }
void HP_Object::PropertiesChanged(UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[]) const { // note that we need to be sure that the object state mutex is not held while we call the listeners bool ownsStateMutex = false; CAMutex* theObjectStateMutex = const_cast<HP_Object*>(this)->GetObjectStateMutex(); if(theObjectStateMutex != NULL) { ownsStateMutex = theObjectStateMutex->IsOwnedByCurrentThread(); if(ownsStateMutex) { theObjectStateMutex->Unlock(); } } OSStatus theError = AudioObjectPropertiesChanged(mPlugIn->GetInterface(), mObjectID, inNumberAddresses, inAddresses); AssertNoError(theError, "HP_Object::PropertiesChanged: got an error calling the listeners"); // re-lock the mutex if((theObjectStateMutex != NULL) && ownsStateMutex) { theObjectStateMutex->Lock(); } }