//-------------------------------------------------------------------------------- // // File: AppleUSBAudioEngine.h // // Contains: Support for the USB Audio Class Stream Interface. // // Technology: Mac OS X // //-------------------------------------------------------------------------------- #ifndef _APPLEUSBAUDIOENGINE_H #define _APPLEUSBAUDIOENGINE_H #include #include #include #include #include #include #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 // Don't make NUM_FRAME_LISTS * NUM_FRAMES_PER_LIST smaller than 375ms or else the HAL will have problems #define NUM_FRAME_LISTS 40 #if FIXEDSIZEPACKETS #define NUM_FRAMES_PER_LIST 10 #else #define NUM_FRAMES_PER_LIST 64 #endif #define NUM_FRAME_LISTS_TO_QUEUE 10 #define MAX_WRITE_RETRIES 10 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 readHandler (void * object, void * frameListIndex, IOReturn result, IOUSBIsocFrame * pFrames); static void sampleRateHandler (void * target, void * parameter, IOReturn result, IOUSBIsocFrame * pFrames); static void writeHandler (void * object, void * parameter, IOReturn result, IOUSBIsocFrame * pFrames); static IOReturn iSubAttachChangeHandler (IOService *target, IOAudioControl *passThruControl, SInt32 oldValue, SInt32 newValue); protected: UInt64 theFirstFrame; UInt64 nextSynchReadFrame; IOUSBIsocFrame * theFrames; IOUSBIsocFrame theSampleRateFrame; IOUSBIsocFrame theStartFrame; IOUSBIsocCompletion * usbCompletion; IOUSBIsocCompletion theStartCompletion; IOUSBIsocCompletion sampleRateCompletion; IOSyncer * signal; AppleUSBAudioDevice * usbAudioDevice; IOUSBInterface * streamInterface; IOUSBInterface * previousInterface; IOUSBPipe * thePipe; IOUSBPipe * theAssociatedPipe; IOMemoryDescriptor ** soundBuffer; IOMemoryDescriptor * theStartBufferDescriptor; IOMemoryDescriptor * neededSampleRate; FrameListWriteInfo * pendingFrameListWriteInfo; IONotifier * streamNotifier; OSObject * interfaceVendor; OSObject * interfaceProduct; OSObject * deviceReleaseNumber; OSObject * configurationValue; OSObject * interfaceNumber; void * readBuffer; void * theStartBuffer; thread_call_t pendingFrameListCall; thread_call_t iSubTeardownThreadCall; thread_call_t iSubOpenThreadCall; IOAudioSampleRate curSampleRate; 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. UInt64 startTime; UInt64 previousWrappedReadUSBFrame; UInt32 theStartBufferSize; UInt32 previous; UInt32 previousClippedToFrame; UInt32 theMaxPacket; UInt32 frameListSize; UInt32 readFrameListSize; UInt32 bufferOffset; UInt32 aveSampleRateBuf; // only needs to be 3 bytes for the 10.14 value, but this is more convenient UInt32 averageSampleRate; UInt32 sum; // This is the number of samples we have sent in the previous frames in this period UInt32 sampleNum; // The number of the frame that we are currently sending, it goes between 1 and 1000 UInt32 numFrameLists; UInt32 numFramesPerList; UInt32 numFrameListsToQueue; UInt32 currentFrameList; UInt32 bufferSize; UInt32 bytesPerSampleFrame; UInt32 safetyOffset; UInt16 samplesThisFrame; UInt8 ourInterfaceNumber; UInt8 shouldStop; UInt8 alternateInterfaceID; UInt8 refreshInterval; UInt8 framesUntilRefresh; UInt8 direction; 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; // aml 2.21.02 adding extra state for 4th order with phase comp filter PreviousValues filterState2; PreviousValues phaseCompState; float srcPhase; // aml 3.4.02 float srcState; // aml 3.6.02 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 PrepareFrameLists (UInt32 numFrameLists, UInt8 sampleSize, UInt8 numChannels); IOReturn SetSampleRate (USBAudioConfigObject *usbAudio, UInt32 sampleRate); IOReturn AddAvailableFormatsFromDevice (USBAudioConfigObject *usbAudio); UInt32 CalculateNumSamplesPerFrameList (UInt32 sampleRate, UInt32 numFrames, UInt32 theNumFrameLists = 1); 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); virtual void CoalesceInputSamples (UInt32 numBytesToCoalesce); 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 */