Exemple #1
0
void	CAHALAudioDevice::DestroyIOProcID(AudioDeviceIOProcID inIOProcID)
{
	OSStatus theError = AudioDeviceDestroyIOProcID(mObjectID, inIOProcID);
	ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::DestroyIOProcID: got an error destroying the IOProc ID");
}
void	CAHALAudioDevice::GetCurrentTime(AudioTimeStamp& outTime)
{
	OSStatus theError = AudioDeviceGetCurrentTime(mObjectID, &outTime);
	ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::GetCurrentTime: got an error getting the current time");
}
void	CAHALAudioDevice::TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime)
{
	OSStatus theError = AudioDeviceTranslateTime(mObjectID, &inTime, &outTime);
	ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::TranslateTime: got an error translating time");
}
Exemple #4
0
void	HLAudioFile::GetFormat(AudioStreamBasicDescription& outFormat) const
{
	ThrowIf(!mPrepared, CAException(fnOpnErr), "HLAudioFile::GetFormat: file hasn't been prepared yet");

	outFormat = mFormat;
}
void	CAHALAudioDevice::StopIOProc(AudioDeviceIOProcID inIOProcID)
{
	OSStatus theError = AudioDeviceStop(mObjectID, inIOProcID);
	ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StopIOProc: got an error stopping an IOProc");
}
Exemple #6
0
void	HLAudioFile::SetRawByteSize(SInt64 inSize)
{
	//	can't touch this file outside of the AudioFile API
	DebugMessage("HLAudioFile::SetRawByteSize: can't do that");
	throw CAException(paramErr);
}
Exemple #7
0
void	HLAudioFile::WriteRawBytes(SInt64 inOffset, UInt32& ioNumberBytes, void* inData, bool inCache)
{
	//	can't touch this file outside of the AudioFile API
	DebugMessage("HLAudioFile::WriteRawBytes: can't do that");
	throw CAException(paramErr);
}
void	HLFileSystemObject::SetNameExtension(CFStringRef inNameExtension)
{
	//	the FSRef for a file can change after renaming,
	//	so don't allow it to be done while the file is open
	ThrowIf(IsOpenForReading() || IsOpenForWriting(), CAException(fBsyErr), "HLFileSystemObject::SetNameExtension: can't change the file name extension of an open file");
	
	//	make a raw unicode string out of the CFString containing the new extension
	CACFString theExtension(inNameExtension, false);
	UInt32 theExtensionLength = 255;
	UniChar	theExtensionString[255];
	theExtension.GetUnicodeString(theExtensionString, theExtensionLength);

	//	get the file name from the catalog info
	HFSUniStr255 theNameString;
	OSStatus theError = FSGetCatalogInfo(&mFSRef, kFSCatInfoNone, NULL, &theNameString, NULL, NULL);
	ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetNameExtension: couldn't get the catalog information");
	
	//	use Launch Services to find the start of the extension
	UniCharCount theExtensionStart = 0;
	LSGetExtensionInfo(theNameString.length, theNameString.unicode, &theExtensionStart);
	
	UInt32 theCharsToCopy;
	if(theExtensionStart != kLSInvalidExtensionIndex)
	{
		//	there already was an extension, so replace it
		
		//	figure out how many characters worth of extension can fit
		theCharsToCopy = 255UL - theExtensionStart;
		
		//	range it against the actual length of the extension
		theCharsToCopy = theExtensionLength < theCharsToCopy ? theExtensionLength : theCharsToCopy;
		
		//	copy the extension
		memcpy(&theNameString.unicode[theExtensionStart], theExtensionString, theCharsToCopy * sizeof(UniChar));
		
		//	update the length of the name string
		theNameString.length = theExtensionStart + theCharsToCopy;

		//	save off the current FSRef, since it may change
		FSRef theOldFSRef;
		memcpy(&theOldFSRef, &mFSRef, sizeof(FSRef));

		//	rename the file, getting us the new FSRef
		theError = FSRenameUnicode(&theOldFSRef, theNameString.length, theNameString.unicode, kTextEncodingUnknown, &mFSRef);
		ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetName: couldn't rename the file");
	}
	else if(theNameString.length < 254)
	{
		//	there isn't an extension yet, and there's room for at least two characters
		
		//	make a raw unicode string with the period
		CFRange thePeriodRange = { 0, 1 };
		UniChar	thePeriodString[255];
		CFStringGetCharacters(HLFileSystemCFStringConstants::sNameExtensionDelimiter, thePeriodRange, thePeriodString);
		
		//	copy it at the end of the string
		theNameString.unicode[theNameString.length] = thePeriodString[0];
		
		//	update the length
		theNameString.length += 1;
		
		//	figure out how many characters worth of extension can fit
		theCharsToCopy = 255UL - theNameString.length;

		//	range it against the actual length of the extension
		theCharsToCopy = theExtensionLength < theCharsToCopy ? theExtensionLength : theCharsToCopy;

		//	copy the extension
		memcpy(&theNameString.unicode[theNameString.length], theExtensionString, theCharsToCopy * sizeof(UniChar));

		//	update the length of the name string
		theNameString.length += theCharsToCopy;

		//	save off the current FSRef, since it may change
		FSRef theOldFSRef;
		memcpy(&theOldFSRef, &mFSRef, sizeof(FSRef));

		//	rename the file, getting us the new FSRef
		theError = FSRenameUnicode(&theOldFSRef, theNameString.length, theNameString.unicode, kTextEncodingUnknown, &mFSRef);
		ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetName: couldn't rename the file");
	}
}
void	HLFileSystemObject::GetParentFSRef(FSRef& outFSRef) const
{
	OSStatus theError = FSGetCatalogInfo(&mFSRef, kFSCatInfoNone, NULL, NULL, NULL, &outFSRef);
	ThrowIfError(theError, CAException(theError), "HLFileSystemObject::GetParentFSRef: couldn't get the catalog info");
}
Exemple #10
0
bool	CAGuard::WaitFor(UInt64 inNanos)
{
	bool theAnswer = false;

#if TARGET_OS_MAC
	ThrowIf(!pthread_equal(pthread_self(), mOwner), CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");

	#if	Log_TimedWaits
		DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
	#endif

	struct timespec	theTimeSpec;
	static const UInt64	kNanosPerSecond = 1000000000ULL;
	if(inNanos >= kNanosPerSecond)
	{
		theTimeSpec.tv_sec = static_cast<UInt32>(inNanos / kNanosPerSecond);
		theTimeSpec.tv_nsec = static_cast<UInt32>(inNanos % kNanosPerSecond);
	}
	else
	{
		theTimeSpec.tv_sec = 0;
		theTimeSpec.tv_nsec = static_cast<UInt32>(inNanos);
	}
	
	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
		UInt64	theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
	#endif

	mOwner = 0;

	#if	Log_WaitOwnership
		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p is waiting on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
	#endif

	OSStatus theError = pthread_cond_timedwait_relative_np(&mCondVar, &mMutex, &theTimeSpec);
	ThrowIf((theError != 0) && (theError != ETIMEDOUT), CAException(theError), "CAGuard::WaitFor: Wait got an error");
	mOwner = pthread_self();
	
	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
		UInt64	theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
	#endif
	
	#if	Log_TimedWaits
		DebugMessageN1("CAGuard::WaitFor: waited  %.0f", (Float64)(theEndNanos - theStartNanos));
	#endif
	
	#if	Log_Latency
		DebugMessageN1("CAGuard::WaitFor: latency  %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
	#endif
	
	#if	Log_Average_Latency
		++mAverageLatencyCount;
		mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
		if(mAverageLatencyCount >= 50)
		{
			DebugMessageN2("CAGuard::WaitFor: average latency  %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
			mAverageLatencyCount = 0;
			mAverageLatencyAccumulator = 0.0;
		}
	#endif

	#if	Log_WaitOwnership
		DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p waited on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
	#endif

	theAnswer = theError == ETIMEDOUT;
#elif TARGET_OS_WIN32
	ThrowIf(GetCurrentThreadId() != mOwner, CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");

	#if	Log_TimedWaits
		DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
	#endif

	//	the time out is specified in milliseconds(!)
	UInt32 theWaitTime = static_cast<UInt32>(inNanos / 1000000ULL);

	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
		UInt64	theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
	#endif

	mOwner = 0;

	#if	Log_WaitOwnership
		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu is waiting on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
	#endif
	
	ReleaseMutex(mMutex);
	HANDLE theHandles[] = { mMutex, mEvent };
	OSStatus theError = WaitForMultipleObjects(2, theHandles, true, theWaitTime);
	ThrowIf((theError != WAIT_OBJECT_0) && (theError != WAIT_TIMEOUT), CAException(GetLastError()), "CAGuard::WaitFor: Wait got an error");
	mOwner = GetCurrentThreadId();
	ResetEvent(mEvent);
	
	#if	Log_TimedWaits || Log_Latency || Log_Average_Latency
		UInt64	theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
	#endif
	
	#if	Log_TimedWaits
		DebugMessageN1("CAGuard::WaitFor: waited  %.0f", (Float64)(theEndNanos - theStartNanos));
	#endif
	
	#if	Log_Latency
		DebugMessageN1("CAGuard::WaitFor: latency  %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
	#endif
	
	#if	Log_Average_Latency
		++mAverageLatencyCount;
		mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
		if(mAverageLatencyCount >= 50)
		{
			DebugMessageN2("CAGuard::WaitFor: average latency  %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
			mAverageLatencyCount = 0;
			mAverageLatencyAccumulator = 0.0;
		}
	#endif

	#if	Log_WaitOwnership
		DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu waited on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
	#endif

	theAnswer = theError == WAIT_TIMEOUT;
#endif

	return theAnswer;
}
Exemple #11
0
bool	CAMutex::Try(bool& outWasLocked)
{
	bool theAnswer = false;
	outWasLocked = false;

#if TARGET_OS_MAC
	pthread_t theCurrentThread = pthread_self();
	if(!pthread_equal(theCurrentThread, mOwner))
	{
		//	this means the current thread doesn't already own the lock
		#if	Log_Ownership
			DebugPrintfRtn(DebugPrintfFile, "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
		#endif

		//	go ahead and call trylock to see if we can lock it.
		int theError = pthread_mutex_trylock(&mMutex);
		if(theError == 0)
		{
			//	return value of 0 means we successfully locked the lock
			mOwner = theCurrentThread;
			theAnswer = true;
			outWasLocked = true;
	
			#if	Log_Ownership
				DebugPrintfRtn(DebugPrintfFile, "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
			#endif
		}
		else if(theError == EBUSY)
		{
			//	return value of EBUSY means that the lock was already locked by another thread
			theAnswer = false;
			outWasLocked = false;
	
			#if	Log_Ownership
				DebugPrintfRtn(DebugPrintfFile, "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
			#endif
		}
		else
		{
			//	any other return value means something really bad happenned
			ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
		}
	}
	else
	{
		//	this means the current thread already owns the lock
		theAnswer = true;
		outWasLocked = false;
	}
#elif TARGET_OS_WIN32
	if(mOwner != GetCurrentThreadId())
	{
		//	this means the current thread doesn't own the lock
		#if	Log_Ownership
			DebugPrintfRtn(DebugPrintfFile, "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
		#endif
		
		//	try to acquire the mutex
		OSStatus theError = WaitForSingleObject(mMutex, 0);
		if(theError == WAIT_OBJECT_0)
		{
			//	this means we successfully locked the lock
			mOwner = GetCurrentThreadId();
			theAnswer = true;
			outWasLocked = true;
	
			#if	Log_Ownership
				DebugPrintfRtn(DebugPrintfFile, "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
			#endif
		}
		else if(theError == WAIT_TIMEOUT)
		{
			//	this means that the lock was already locked by another thread
			theAnswer = false;
			outWasLocked = false;
	
			#if	Log_Ownership
				DebugPrintfRtn(DebugPrintfFile, "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
			#endif
		}
		else
		{
			//	any other return value means something really bad happenned
			ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
		}
	}
	else
	{
		//	this means the current thread already owns the lock
		theAnswer = true;
		outWasLocked = false;
	}
#endif
	
	return theAnswer;
}
Exemple #12
0
void	SDP_PlugIn::DeviceSetPropertyData(UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void* inPropertyData)
{
	switch(inPropertyID)
	{
		case kSampleDriverPlugInDevicePropertyFoo:
			{
				//	make sure the size is right
				ThrowIf(inPropertyDataSize != DeviceGetPropertyDataSize(inChannel, isInput, inPropertyID), CAException(kAudioHardwareBadPropertySizeError), "SDP_PlugIn::DeviceSetPropertyData: wrong data size for kSampleDriverPlugInDevicePropertyFoo");
				
				//	get the new value
				UInt32 theValue = *static_cast<const UInt32*>(inPropertyData);
				
				//	tell the driver about it
				SetFoo(mHostInfo.mIOAudioEngine, theValue);
			}
			break;
		
		default:
			HP_DriverPlugIn::DeviceSetPropertyData(inChannel, isInput, inPropertyID, inPropertyDataSize, inPropertyData);
			break;
	};
}
Exemple #13
0
void	SDP_PlugIn::DeviceGetPropertyData(UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData) const
{
	switch(inPropertyID)
	{
		case kSampleDriverPlugInDevicePropertyFoo:
			{
				//	make sure the size is right
				ThrowIf(ioPropertyDataSize != DeviceGetPropertyDataSize(inChannel, isInput, inPropertyID), CAException(kAudioHardwareBadPropertySizeError), "SDP_PlugIn::DeviceGetPropertyData: wrong data size for kSampleDriverPlugInDevicePropertyFoo");
				
				//	set the return value
				*((UInt32*)outPropertyData) = GetFoo(mHostInfo.mIOAudioEngine);
			}
			break;
		
		default:
			HP_DriverPlugIn::DeviceGetPropertyData(inChannel, isInput, inPropertyID, ioPropertyDataSize, outPropertyData);
			break;
	};
}
Exemple #14
0
void	SHP_PlugIn::GetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32& ioDataSize, void* outData) const
{
	switch(inAddress.mSelector)
	{
		case kAudioObjectPropertyName:
			ThrowIf(ioDataSize != GetPropertyDataSize(inAddress, inQualifierDataSize, inQualifierData), CAException(kAudioHardwareBadPropertySizeError), "SHP_PlugIn::GetPropertyData: wrong data size for kAudioObjectPropertyName");
			*static_cast<CFStringRef*>(outData) = CFSTR("com.apple.audio.SampleHardwarePlugIn");
			CFRetain(*static_cast<CFStringRef*>(outData));
			break;
			
		default:
			HP_HardwarePlugIn::GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, ioDataSize, outData);
			break;
	};
}