/*=============================================================================
	CAAudioHardwareDevice.h

	$Log: CAAudioHardwareDevice.h,v $
	Revision 1.12  2005/01/19 02:48:12  jcm10
	add HasClockDomain()
	
	Revision 1.11  2004/11/06 02:37:37  jcm10
	add support for some new Tiger properties
	
	Revision 1.10  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.9  2003/11/19 00:01:25  jcm10
	add support for accessing the related devices property
	
	Revision 1.8  2003/07/18 22:55:53  jcm10
	add support for setting the IsRunning property
	
	Revision 1.7  2003/07/18 00:33:01  jcm10
	add support for the iSub controls
	
	Revision 1.6  2003/06/18 22:09:20  jcm10
	add IsControlEnabled methods
	
	Revision 1.5  2003/06/05 19:08:33  jcm10
	add StartIOProcAtTime
	
	Revision 1.4  2003/06/04 22:34:59  jcm10
	adjust to the StartAtTime API change
	
	Revision 1.3  2003/05/29 18:08:12  jcm10
	implement GetNearestStartTime()
	
	Revision 1.2  2003/05/28 19:42:37  jcm10
	the value of kAudioDevicePropertyConfigurationApplication is a bundle ID rather than a path
	
	Revision 1.1  2003/05/23 19:06:50  jcm10
	first checked in
	
	Revision 1.11  2003/05/06 18:42:40  jcm10
	add support for displaying/manipulating the IOProc format
	
	Revision 1.10  2003/04/03 01:39:49  jcm10
	add GetCurrentTime and TranslateTime
	
	Revision 1.9  2003/02/17 20:54:04  jcm10
	add Get/SetIOProcStreamUsage()
	
	Revision 1.8  2003/02/07 22:54:59  jcm10
	fix the format stuff
	
	Revision 1.7  2003/02/05 02:58:17  jcm10
	make the controls tab work in the device window
	
	Revision 1.6  2003/02/04 02:38:41  jcm10
	preliminary support for the controls list
	
	Revision 1.5  2003/01/30 22:31:31  jcm10
	make the Streams tab of the Device window work
	
	Revision 1.4  2003/01/29 19:33:40  jcm10
	make everything on the device window's info tab work
	
	Revision 1.3  2003/01/25 02:59:12  jcm10
	hook up hog mode and mixability items
	
	Revision 1.2  2003/01/24 03:25:43  jcm10
	add file player window
	
	Revision 1.1  2002/11/27 22:33:09  jcm10
	first checked in
	
	Revision 0.0  Wed Nov 20 2002 18:05:08 US/Pacific  moorf
	Created
		
	$NoKeywords: $
=============================================================================*/
#if !defined(__CAAudioHardwareDevice_h__)
#define __CAAudioHardwareDevice_h__

//=============================================================================
//	Includes
//=============================================================================

//	System Includes
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <CoreAudio/CoreAudio.h>
	#include <CoreFoundation/CoreFoundation.h>
	#include <sys/types.h>
#else
	#include <CoreAudio.h>
	#include <CoreFoundation.h>
#endif

//=============================================================================
//	Types
//=============================================================================

typedef	UInt8	CAAudioHardwareDeviceSectionID;
#define	kAudioDeviceSectionInput	((CAAudioHardwareDeviceSectionID)0x01)
#define	kAudioDeviceSectionOutput	((CAAudioHardwareDeviceSectionID)0x00)
#define	kAudioDeviceSectionGlobal	((CAAudioHardwareDeviceSectionID)0x00)
#define	kAudioDeviceSectionWildcard	((CAAudioHardwareDeviceSectionID)0xFF)

//=============================================================================
//	CAAudioHardwareDevice
//=============================================================================

class CAAudioHardwareDevice
{

//	Construction/Destruction
public:
					CAAudioHardwareDevice(AudioDeviceID inAudioDeviceID);
					~CAAudioHardwareDevice();

//	General Operations
public:
	AudioDeviceID	GetAudioDeviceID() const { return mAudioDeviceID; }
	CFStringRef		CopyName() const;
	CFStringRef		CopyManufacturer() const;
	CFStringRef		CopyOwningPlugInBundleID() const;
	CFStringRef		CopyUID() const;
	bool			HasModelUID() const;
	CFStringRef		CopyModelUID() const;
	CFStringRef		CopyConfigurationApplicationBundleID() const;
	UInt32			GetTransportType() const;
	bool			CanBeDefaultDevice(CAAudioHardwareDeviceSectionID inSection, bool inIsSystem = false) const;
	
	bool			HasDevicePlugInStatus() const;
	OSStatus		GetDevicePlugInStatus() const;
	
	bool			IsAlive() const;
	bool			IsRunning() const;
	void			SetIsRunning(bool inIsRunning);
	bool			IsRunningSomewhere() const;
	
	pid_t			GetHogModeOwner() const;
	bool			TakeHogMode();
	void			ReleaseHogMode();
	
	bool			SupportsChangingMixability() const;
	bool			IsMixable() const;
	void			SetIsMixable(bool inIsMixable);
	
	bool			HasIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const;
	bool			GetIsConnectedStatus(CAAudioHardwareDeviceSectionID inSection) const;
	
	bool			HasPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection) const;
	void			GetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32& outLeft, UInt32& outRight) const;
	void			SetPreferredStereoChannels(CAAudioHardwareDeviceSectionID inSection, UInt32 inLeft, UInt32 inRight);
	
	UInt32			GetNumberRelatedDevices() const;
	AudioDeviceID   GetRelatedDeviceByIndex(UInt32 inIndex) const;
	void			GetRelatedDevices(UInt32& ioNumberRelatedDevices, AudioDeviceID* outRelatedDevices) const;
	
//	IO Operations
public:
	UInt32			GetLatency(CAAudioHardwareDeviceSectionID inSection) const;
	UInt32			GetSafetyOffset(CAAudioHardwareDeviceSectionID inSection) const;
	
	bool			HasClockDomain() const;
	UInt32			GetClockDomain() const;
	bool			HasClockSourceControl() const;
	bool			ClockSourceControlIsSettable() const;
	UInt32			GetCurrentClockSourceID() const;
	void			SetCurrentClockSourceByID(UInt32 inID);
	UInt32			GetNumberAvailableClockSources() const;
	UInt32			GetAvailableClockSourceByIndex(UInt32 inIndex) const;
	void			GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const;
	CFStringRef		CopyClockSourceNameForID(UInt32 inID) const;

	bool			HasDataSourceControl(CAAudioHardwareDeviceSectionID inSection) const;
	bool			DataSourceControlIsSettable(CAAudioHardwareDeviceSectionID inSection) const;
	UInt32			GetCurrentDataSourceID(CAAudioHardwareDeviceSectionID inSection) const;
	void			SetCurrentDataSourceByID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID);
	UInt32			GetNumberAvailableDataSources(CAAudioHardwareDeviceSectionID inSection) const;
	UInt32			GetAvailableDataSourceByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const;
	void			GetAvailableDataSources(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberSources, UInt32* outSources) const;
	CFStringRef		CopyDataSourceNameForID(CAAudioHardwareDeviceSectionID inSection, UInt32 inID) const;

	Float64			GetActualSampleRate() const;
	Float64			GetNominalSampleRate() const;
	void			SetNominalSampleRate(Float64 inSampleRate);
	bool			IsValidNominalSampleRate(Float64 inSampleRate) const;
	UInt32			GetNumberNominalSampleRateRanges() const;
	void			GetNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const;
	void			GetNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const;
	
	UInt32			GetIOBufferSize() const;
	void			SetIOBufferSize(UInt32 inBufferSize);
	bool			UsesVariableIOBufferSizes() const;
	UInt32			GetMaximumVariableIOBufferSize() const;
	void			GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const;

	void			AddIOProc(AudioDeviceIOProc inIOProc, void* inClientData);
	void			RemoveIOProc(AudioDeviceIOProc inIOProc);
	
	void			StartIOProc(AudioDeviceIOProc inIOProc);
	void			StartIOProcAtTime(AudioDeviceIOProc inIOProc, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware);
	void			StopIOProc(AudioDeviceIOProc inIOProc);
	
	void			GetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, bool* outStreamUsage) const;
	void			SetIOProcStreamUsage(AudioDeviceIOProc inIOProc, CAAudioHardwareDeviceSectionID inSection, const bool* inStreamUsage);

//	Time Operations
public:
	void			GetCurrentTime(AudioTimeStamp& outTime);
	void			TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime);
	void			GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware);

//	Stream Operations
public:
	UInt32			GetNumberStreams(CAAudioHardwareDeviceSectionID inSection) const;
	void			GetStreams(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamID* outStreamList) const;
	AudioStreamID	GetStreamByIndex(CAAudioHardwareDeviceSectionID inSection, UInt32 inIndex) const;
	
	bool			HasSection(CAAudioHardwareDeviceSectionID inSection) const { return GetNumberStreams(inSection) > 0; }
	UInt32			GetTotalNumberChannels(CAAudioHardwareDeviceSectionID inSection) const;

//	Format Operations
public:
	void			GetCurrentIOProcFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const;
	void			GetCurrentPhysicalFormats(CAAudioHardwareDeviceSectionID inSection, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const;

//	Control Operations
public:
	bool			HasVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			VolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	Float32			GetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	Float32			GetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	void			SetVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue);
	void			SetVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue);
	Float32			GetVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const;
	Float32			GetVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const;
	
	bool			HasMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			MuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			GetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	void			SetMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue);
	
	bool			HasPlayThruControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			PlayThruControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			GetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	void			SetPlayThruControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue);
	
	bool			HasISubOwnershipControl() const;
	bool			ISubOwnershipControlIsSettable() const;
	bool			GetISubOwnershipControlValue() const;
	void			SetISubOwnershipControlValue(bool inValue);
	
	bool			HasSubMuteControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			SubMuteControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			GetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	void			SetSubMuteControlValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, bool inValue);
	
	bool			HasSubVolumeControl(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	bool			SubVolumeControlIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	Float32			GetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	Float32			GetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection) const;
	void			SetSubVolumeControlScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue);
	void			SetSubVolumeControlDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue);
	Float32			GetSubVolumeControlScalarForDecibelValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const;
	Float32			GetSubVolumeControlDecibelForScalarValue(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, Float32 inValue) const;
	
//	Property Operations
public:
	bool			HasProperty(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const;
	bool			PropertyIsSettable(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const;
	
	UInt32			GetPropertyDataSize(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID) const;
	void			GetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32& ioDataSize, void* outData) const;
	void			SetPropertyData(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen = NULL);
	
	void			AddPropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc, void* inClientData);
	void			RemovePropertyListener(UInt32 inChannel, CAAudioHardwareDeviceSectionID inSection, AudioHardwarePropertyID inPropertyID, AudioDevicePropertyListenerProc inListenerProc);

//	Utility Operations
public:
	static void		GetNameForTransportType(UInt32 inTransportType, char* outName);

//	Implementation
private:
	AudioDeviceID	mAudioDeviceID;

};

#endif
