AppleUSBAudioEngine.h [plain text]
//--------------------------------------------------------------------------------
//
//	File:		AppleUSBAudioEngine.h
//
//	Contains:	Support for the USB Audio Class Stream Interface.
//
//	Technology:	Mac OS X
//
//--------------------------------------------------------------------------------

#ifndef _APPLEUSBAUDIOENGINE_H
#define _APPLEUSBAUDIOENGINE_H

#define NEWUSB					TRUE

#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/audio/IOAudioEngine.h>
#include <IOKit/audio/IOAudioStream.h>
#include <IOKit/usb/IOUSBPipe.h>
#include <IOKit/usb/IOUSBDevice.h>
#include <IOKit/usb/IOUSBInterface.h>

#include "USBAudioObject.h"
#include "AppleiSubEngine.h"
#include "AppleUSBAudioClip.h"

class AppleUSBAudioDevice;

//	-----------------------------------------------------------------

#define	kSampleRate_44100				44100
#define kDefaultSamplingRate			kSampleRate_44100
#define	kBitDepth_16bits				16
#define	kChannelDepth_MONO				1
#define	kChannelDepth_STEREO			2

#define kMinimumFrameOffset				1


#define RECORD_NUM_USB_FRAME_LISTS				128
#define RECORD_NUM_USB_FRAMES_PER_LIST			2
#define RECORD_NUM_USB_FRAME_LISTS_TO_QUEUE		64

#define PLAY_NUM_USB_FRAME_LISTS				4
#define PLAY_NUM_USB_FRAMES_PER_LIST			64
#define PLAY_NUM_USB_FRAME_LISTS_TO_QUEUE		2

class IOSyncer;
class AppleUSBAudioEngine;

typedef struct FrameListWriteInfo {
    AppleUSBAudioEngine *				audioEngine;
    UInt32								frameListNum;
    UInt32								retryCount;
} FrameListWriteInfo;

class AppleUSBAudioEngine : public IOAudioEngine {
    friend class AppleUSBAudioDevice;

    OSDeclareDefaultStructors (AppleUSBAudioEngine);

public:
    virtual bool init (OSDictionary *properties);
    virtual void free ();
    virtual bool initHardware (IOService *provider);
    virtual bool start (IOService *provider);
    virtual void stop (IOService *provider);
	virtual bool requestTerminate (IOService * provider, IOOptionBits options);
    virtual bool terminate (IOOptionBits options = 0);

    virtual IOReturn performAudioEngineStart ();
    virtual IOReturn performAudioEngineStop ();
    
    virtual IOAudioEngineState _setState (IOAudioEngineState newState);

	static void sampleRateHandler (void * target, void * parameter, IOReturn result, IOUSBIsocFrame * pFrames);

#if NEWUSB
    static void readHandler (void * object, void * frameListIndex, IOReturn result, IOUSBLowLatencyIsocFrame * pFrames);
    static void writeHandler (void * object, void * parameter, IOReturn result, IOUSBLowLatencyIsocFrame * pFrames);
#else
    static void readHandler (void * object, void * frameListIndex, IOReturn result, IOUSBIsocFrame * pFrames);
    static void writeHandler (void * object, void * parameter, IOReturn result, IOUSBIsocFrame * pFrames);
#endif

	static IOReturn iSubAttachChangeHandler (IOService *target, IOAudioControl *passThruControl, SInt32 oldValue, SInt32 newValue);

protected:
	UInt64								usbFrameToQueueAt;
	UInt64					nextSynchReadFrame;
#if NEWUSB
	IOUSBLowLatencyIsocFrame *			theUSBIsocFrames;
	IOUSBLowLatencyIsocFrame			theStartFrame;
#else
	IOUSBIsocFrame *					theUSBIsocFrames;
	IOUSBIsocFrame						theStartFrame;
#endif
	IOUSBIsocFrame			theSampleRateFrame;
#if NEWUSB
	IOUSBLowLatencyIsocCompletion *		usbCompletion;
#else
	IOUSBIsocCompletion *	usbCompletion;
#endif
	IOUSBIsocCompletion		sampleRateCompletion;
	IOUSBInterface *		streamInterface;
	IOUSBInterface *		previousInterface;
	IOUSBPipe *				thePipe;
	IOUSBPipe *				theAssociatedPipe;
	IOSyncer *							signal;
	AppleUSBAudioDevice *				usbAudioDevice;
	IOMemoryDescriptor **				soundBufferDescriptors;
	IOMemoryDescriptor *	theStartBufferDescriptor;
	IOMemoryDescriptor *	neededSampleRate;
	IOVirtualRange						theWrapRanges[2];
	IONotifier *			streamNotifier;
	OSObject *				interfaceVendor;
	OSObject *				interfaceProduct;
	OSObject *				deviceReleaseNumber;
	OSObject *				configurationValue;
	OSObject *				interfaceNumber;
	void *					readBuffer;
	void *					theStartBuffer;
	UInt32 *							aveSampleRateBuf;		// only needs to be 3 bytes for the 10.14 value
#if !NEWUSB
	UInt64								expectedBusFrame;		// For output, the frame on which we expect to get our next USB isoc completion
																// For input, the frame on which we last received a USB isoc completion and
																// wrapped the sample buffer.
#endif
	thread_call_t			iSubTeardownThreadCall;
	thread_call_t			iSubOpenThreadCall;
	IOAudioSampleRate		curSampleRate;
	UInt32								previouslyPreparedBufferOffset;
	UInt32								safeToEraseTo;
	UInt32								lastSafeErasePoint;
	UInt32					theStartBufferSize;
	UInt32					previous;
	UInt32					previousClippedToFrame;
	UInt32					theMaxPacket;
	UInt32								readUSBFrameListSize;
	UInt32					bufferOffset;
	UInt32					averageSampleRate;
	UInt32					sum;					// This is the number of samples we have sent in the previous frames in this period
	UInt32								numUSBFrameLists;
	UInt32								numUSBFramesPerList;
	UInt32								numUSBFrameListsToQueue;
	UInt32					currentFrameList;
	UInt32					bufferSize;
	UInt32					bytesPerSampleFrame;
	UInt32					safetyOffset;
	UInt32								fractionalSamplesRemaining;
	UInt16					samplesThisFrame;
	UInt8					ourInterfaceNumber;
	UInt8					shouldStop;
	UInt8					alternateInterfaceID;
	UInt8					refreshInterval;
	UInt8					framesUntilRefresh;
	UInt8					direction;
	Boolean								inCompletion;
	Boolean					usbStreamRunning;
	Boolean					notifyDeviceOfStop;
	Boolean					startingEngine;
	Boolean					startiSub;
	Boolean					justResetClipPosition;		// aml 3.29.02 added to match AOA
	Boolean					gotRequestClose;
	Boolean					gotStopCall;
	Boolean					iSubIsOpen;
	Boolean					terminatingDriver;
	IOAudioStream *			mainStream;

	// For iSub
	IOMemoryDescriptor *	iSubBufferMemory;
	UInt32					iSubLoopCount;
	SInt32					iSubBufferOffset;		// Where we are writing to in the iSub buffer
	IOService *				ourProvider;
	IONotifier *			iSubEngineNotifier;
	IOAudioToggleControl *	iSubAttach;
	AppleiSubEngine *		iSubEngine;
	AppleiSubEngine *		oldiSubEngine;
	float *					lowFreqSamples;
	float *					highFreqSamples;
	PreviousValues				filterState;
	PreviousValues				filterState2;
	PreviousValues				phaseCompState;
	float					srcPhase;			 	
	float					srcState;			 	
	Boolean					needToSync;

	static inline IOFixed IOUFixedDivide(UInt32 a, UInt32 b)
	{
		return (IOFixed)((((UInt64) a) << 16) / ((UInt64) b));
	}

	static inline UInt32 IOUFixedMultiply(UInt32 a, UInt32 b)
	{
		return (UInt32)((((UInt64) a) * ((UInt64) b)) >> 16);
	}

	void	GetDeviceInfo (void);
	IOReturn	PrepareWriteFrameList (UInt32 usbFrameListIndex);
	IOReturn	PrepareAndReadFrameLists (UInt8 sampleSize, UInt8 numChannels, UInt32 usbFrameListIndex);
	IOReturn	SetSampleRate (USBAudioConfigObject *usbAudio, UInt32 sampleRate);
	IOReturn	AddAvailableFormatsFromDevice (USBAudioConfigObject *usbAudio);
	IOReturn	CheckForAssociatedEndpoint (USBAudioConfigObject *usbAudio);

    static bool audioDevicePublished (AppleUSBAudioEngine *audioEngine, void *ref, IOService *newService);
    static bool	iSubEnginePublished (AppleUSBAudioEngine * usbAudioEngineObject, void * refCon, IOService * newService);

	virtual bool willTerminate (IOService * provider, IOOptionBits options);

	virtual OSString * getGlobalUniqueID ();
    virtual IOReturn readFrameList (UInt32 frameListNum);
    virtual IOReturn writeFrameList (UInt32 frameListNum);

    virtual IOReturn startUSBStream ();
    virtual IOReturn stopUSBStream ();

	static IOReturn iSubCloseAction (OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
	static IOReturn iSubOpenAction (OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
	static void iSubTeardown (AppleUSBAudioEngine *usbAudioEngine, thread_call_t iSubTeardownThreadCall);
	static void iSubOpen (AppleUSBAudioEngine *usbAudioEngineObject);
	virtual void iSubTeardownConnection (void);

    virtual UInt32 getCurrentSampleFrame (void);

    virtual IOAudioStreamDirection getDirection (void);
    virtual void *getSampleBuffer (void);
	virtual UInt32 getSampleBufferSize (void);

#if NEWUSB
	virtual void CoalesceInputSamples (UInt32 numBytesToCoalesce, IOUSBLowLatencyIsocFrame * pFrames);
#else
	virtual void CoalesceInputSamples (UInt32 numBytesToCoalesce, IOUSBIsocFrame * pFrames);
#endif

	virtual void resetClipPosition (IOAudioStream *audioStream, UInt32 clipSampleFrame);
    virtual IOReturn clipOutputSamples (const void *mixBuf, void *sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
	virtual IOReturn convertInputSamples (const void *sampleBuf, void *destBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);

    virtual IOReturn performFormatChange (IOAudioStream *audioStream, const IOAudioStreamFormat *newFormat, const IOAudioSampleRate *newSampleRate);
	void CalculateSamplesPerFrame (UInt32 sampleRate, UInt16 * averageFrameSize, UInt16 * additionalSampleFrameFreq);
};

#endif /* _APPLEUSBAUDIOENGINE_H */

Generated by GNU enscript 1.6.4.