Example #1
0
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();
	}
Example #10
0
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();
	}
}