1/*
2 * Copyright (c) 1998-2010 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23/*!
24 * @header IOAudioEngine
25 */
26
27#ifndef _IOKIT_IOAUDIOENGINE_H
28#define _IOKIT_IOAUDIOENGINE_H
29
30#include <IOKit/IOService.h>
31
32#ifndef IOAUDIOFAMILY_SELF_BUILD
33#include <IOKit/audio/IOAudioTypes.h>
34#else
35#include "IOAudioTypes.h"
36#endif
37#include <IOKit/IOBufferMemoryDescriptor.h>
38
39class OSDictionary;
40class OSCollection;
41class OSOrderedSet;
42class IOAudioEngineUserClient;
43class IOAudioDevice;
44class IOAudioStream;
45class IOAudioControl;
46class IOCommandGate;
47
48#define IOAUDIOENGINE_DEFAULT_NUM_ERASES_PER_BUFFER	4
49
50/*!
51 * @typedef IOAudioEnginePosition
52 * @abstract Represents a position in an audio audio engine.
53 * @discussion This position is based on the sample frame within a
54 *  loop around the sample buffer, and the loop count which starts at 0 when the audio engine
55 *  begins playback.
56 * @field fSampleFrame The sample frame within the buffer - starts at 0.
57 * @field fLoopCount The number of times the ring buffer has looped.
58 */
59typedef struct {
60    UInt32	fSampleFrame;
61    UInt32	fLoopCount;
62} IOAudioEnginePosition;
63
64#define CMP_IOAUDIOENGINEPOSITION(p1, p2) \
65    (((p1)->fLoopCount > (p2)->fLoopCount) ? 1 :	\
66        ((p1)->fLoopCount == (p2)->fLoopCount) && ((p1)->fSampleFrame > (p2)->fSampleFrame) ? 1 :	\
67            ((p1)->fLoopCount == (p2)->fLoopCount) && ((p1)->fSampleFrame == (p2)->fSampleFrame) ? 0 : -1)
68
69#define IOAUDIOENGINEPOSITION_IS_ZERO(p1) (((p1)->fLoopCount == 0) && ((p1)->fSampleFrame == 0))
70
71/*!
72 * @class IOAudioEngine
73 * @abstract Abstract base class for a single audio audio / I/O engine.
74 * @discussion An IOAudioEngine is defined by a single I/O engine to transfer data to
75 *  or from one or more sample buffers.  Each sample buffer is represented by a single IOAudioStream
76 *  instance.  A single IOAudioEngine must contain at least one IOAudioStream, but has no upper
77 *  limit on the number of IOAudioStreams it may contain.  An IOAudioEngine instance may contain
78 *  both input and output IOAudioStreams.
79 *
80 *  An audio driver must subclass IOAudioEngine in order to provide certain services.  An
81 *  IOAudioEngine subclass must start and stop the I/O engine when requested.  The I/O
82 *  engine should be continuously running and loop around from end to beginning.  While the audio
83 *  engine is running, it must take a timestamp as the sample buffer(s) wrap around and start at
84 *  the beginning.  The CoreAudio.framework uses the timestamp to calculate the exact position of
85 *  the audio engine.  An IOAudioEngine subclass must implement getCurrentSampleFrame() to provide
86 *  a sample position on demand.  Finally, an IOAudioEngine subclass must provide clipping and
87 *  format conversion routines to go to/from the CoreAudio.framework's native float format.
88 *
89 *  If multiple stream formats or sample rates are allowed, the IOAudioEngine
90 *  subclass must provide support for changing the hardware when a format or sample rate is
91 *  changed.
92 *
93 *  There are several attributes associated with a single IOAudioEngine:
94 *
95 *  The IOAudioEngine superclass provides a shared status buffer that contains all of the dynamic pieces
96 *  of information about the audio engine (type IOAudioEngineStatus).  It runs an erase process on
97 *  all of the output streams.  The erase head is used to zero out the mix and sample buffers after
98 *  the samples have been played.  Additionally, the IOAudioEngine superclass handles the
99 *  communication with the CoreAudio.framework and makes the decision to start and stop the
100 *  audio engine when it detects it is in use.
101 *
102 *  In order for an audio device to play back or record sound, an IOAudioEngine subclass must be created.
103 *  The subclass must initialize all of the necessary hardware resources to prepare for starting the
104 *  audio I/O engine.  It typically will perform these tasks in the initHardware() method.  A subclass
105 *  may also implement a stop() method which is called as the driver is being torn down.  This is
106 *  typically called in preparation of removing the device from the system for removable devices.
107 *
108 *  In addition to initializing the necessary hardware, there are a number of other tasks an
109 *  IOAudioEngine must do during initHardware().  It must create the necessary IOAudioStream objects
110 *  to match the device capabilities.  Each IOAudioStream must be added using addAudioStream().  It
111 *  also should create the IOAudioControls needed to control the various attributes of the audio engine:
112 *  output volume, mute, input gain, input selection, analog passthru.  To do that, addDefaultAudioControl()
113 *  should be called with each IOAudioControl to be attached to the IOAudioEngine.  In order to provide
114 *  for proper synchronization, the latency of the audio engine should be specified with setSampleLatency().
115 *  This value represents the latency between the timestamp taken at the beginning of the buffer and
116 *  when the audio is actually played (or recorded) by the device.  If a device is block based or if
117 *  there is a need to keep the CoreAudio.framework a certain number of samples ahead of (or behind for
118 *  input) the I/O head, that value should be specified using setSampleOffset().  If this is not specified
119 *  the CoreAudio.framework may attempt to get as close to the I/O head as possible.
120 *
121 *  The following fields in the shared IOAudioEngineStatus struct must be maintained by the subclass
122 *  implementation:
123 *  <pre>
124 *  <t>  fCurrentLoopCount - the number of times the sample buffer has wrapped around to the beginning
125 *  <t>  fLastLoopTime - timestamp of the most recent time that the I/O engine looped back to the
126 *  beginning of the sample buffer
127 *  </pre>
128 *  It is critically important that the fLastLoopTime field be as accurate as possible.  It is
129 *  the basis for the entire timer and synchronization mechanism used by the audio system.
130 *
131 *  At init time, the IOAudioEngine subclass must call setNumSampleFramesPerBuffer() to indicate how large
132 *  each of the sample buffers are (measured in sample frames).  Within a single IOAudioEngine, all sample
133 *  buffers must be the same size and be running at the same sample rate.  If different buffers/streams can
134 *  be run at different rates, separate IOAudioEngines should be used.  The IOAudioEngine subclass must
135 *  also call setSampleRate() at init time to indicate the starting sample rate of the device.
136 *
137 */
138
139class IOAudioEngine : public IOService
140{
141    OSDeclareAbstractStructors(IOAudioEngine)
142
143    friend class IOAudioEngineUserClient;
144    friend class IOAudioDevice;
145    friend class IOAudioStream;
146
147public:
148    /*! @var gSampleRateWholeNumberKey */
149    static const OSSymbol	*gSampleRateWholeNumberKey;
150    /*! @var gSampleRateFractionKey */
151    static const OSSymbol	*gSampleRateFractionKey;
152
153    /*! @var numSampleFramesPerBuffer */
154    UInt32			numSampleFramesPerBuffer;
155
156    /*! @var sampleRate
157     *  The current sample rate of the audio engine in samples per second. */
158    IOAudioSampleRate			sampleRate;
159
160    /*! @var numErasesPerBuffer
161     *  The number of times the erase head get scheduled to run for each
162     *   cycle of the audio engine. */
163    UInt32			numErasesPerBuffer;
164    /*! @var runEraseHead
165     *  Set to true if the erase head is to run when the audio engine is running.  This is the case if there are any output streams. */
166    bool			runEraseHead;
167
168    /*! @var audioEngineStopPosition
169     *  When all clients have disconnected, this is set to one buffer length past the
170    *    current audio engine position at the time.  Then when the stop position is reached, the audio engine
171    *    is stopped */
172    IOAudioEnginePosition	audioEngineStopPosition;
173
174    /*! @var isRegistered
175     *  Internal state variable to keep track or whether registerService() has been called. */
176    bool			isRegistered;
177    /*! @var configurationChangeInProgress
178     *  Set to true after beginConfigurationChange() and false upon a
179    *    subsequent call to completeConfigurationChange() or cancelConfigurationChange(). */
180    bool			configurationChangeInProgress;
181
182    /*! @var state
183     *  The current state of the IOAudioEngine - running, stopped, paused. */
184    IOAudioEngineState		state;
185
186    /*! @var status
187     *  Status struct shared with the CoreAudio.framework. */
188    IOAudioEngineStatus *	status;
189
190    /*! @var audioDevice
191     *  The IOAudioDevice instance to which the IOAudioEngine belongs. */
192    IOAudioDevice *		audioDevice;
193
194    /*! @var workLoop
195     *  The IOWorkLoop for the audio driver - shared with the IOAudioDevice. */
196    IOWorkLoop 			*workLoop;
197    /*! @var commandGate
198     *  The IOCommandGate for this audio engine - attached to the driver's IOWorkLoop. */
199    IOCommandGate		*commandGate;
200
201    /*! @var inputStreams
202     *  An OSSet of all of the input IOAudioStreams attached to this IOAudioEngine. */
203    OSOrderedSet 	*inputStreams;
204    UInt32			maxNumInputChannels;
205    /*! @var outputStreams
206     *  An OSSet of all of the output IOAudioStreams attached to this IOAudioEngine. */
207    OSOrderedSet	*outputStreams;
208    UInt32			maxNumOutputChannels;
209    /*! @var userClients
210     *  An OSSet of all of the currently connected user clients. */
211    OSSet			*userClients;
212    /*! @var defaultAudioControls
213     *  All of the IOAudioControls that affect this audio engine. */
214    OSSet			*defaultAudioControls;
215
216    /*! @var numActiveUserClients
217     *  A total of the active user clients - those that are currently playing or
218     *    recording audio. */
219    UInt32			numActiveUserClients;
220    UInt32			sampleOffset;				// used for input and output if inputSampleOffset is not set, if inputSampleOffset is set used as output only
221
222    UInt32			index;
223    bool			duringStartup;
224
225protected:
226
227    /*!
228     * @var deviceStartedAudioEngine
229     *  Used by the IOAudioDevice to determine responsibility for shutting
230     *  the audio engine down when it is no longer needed.
231     */
232    bool			deviceStartedAudioEngine;
233
234protected:
235    struct ExpansionData {
236		UInt32								pauseCount;
237		IOBufferMemoryDescriptor			*statusDescriptor;
238		IOBufferMemoryDescriptor			*bytesInInputBufferArrayDescriptor;
239		IOBufferMemoryDescriptor			*bytesInOutputBufferArrayDescriptor;
240		UInt32								mixClipOverhead;
241		OSArray								*streams;
242	    UInt32								inputSampleOffset;
243		UInt32								commandGateStatus;			// <rdar://8518215>
244		SInt32								commandGateUsage;			// <rdar://8518215>
245	};
246
247    ExpansionData   *reserved;
248
249//	static UInt32	sInstanceCount;
250
251public:
252	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 0);
253    virtual IOReturn performFormatChange(IOAudioStream *audioStream, const IOAudioStreamFormat *newFormat, const IOAudioStreamFormatExtension *formatExtension, const IOAudioSampleRate *newSampleRate);
254	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 1);
255	virtual IOBufferMemoryDescriptor * getStatusDescriptor();
256	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 2);
257	virtual IOReturn getNearestStartTime(IOAudioStream *audioStream, IOAudioTimeStamp *ioTimeStamp, bool isInput);
258	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 3);
259	virtual IOBufferMemoryDescriptor * getBytesInInputBufferArrayDescriptor();
260	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 4);
261	virtual IOBufferMemoryDescriptor * getBytesInOutputBufferArrayDescriptor();
262	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 5);
263    /*!
264	 * @function eraseOutputSamples
265     * @abstract This function allows for the actual erasing of the mix and sample buffer to be overridden by
266	 * a child class.
267	 * @param mixBuf Pointer to the IOAudioFamily allocated mix buffer.
268	 * @param sampleBuf Pointer to the child class' sample buffer.
269	 * @param firstSampleFrame Index to the first sample frame to erase.
270	 * @param numSampleFrames Number of sample frames to erase.
271	 * @param streamFormat Format of the data to be erased.
272	 * @param audioStream Pointer to stream object that corresponds to the sample buffer being erased.
273	 * @result Must return kIOReturnSuccess if the samples have been erased.
274     */
275	virtual IOReturn eraseOutputSamples(const void *mixBuf, void *sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
276	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 6);
277    /*!
278	 * @function setClockIsStable
279     * @abstract This function sets a flag that CoreAudio uses to select its sample rate tracking algorithm.  Set
280	 * this to TRUE unless that results in dropped audio.  If the driver is experiencing unexplained dropouts
281	 * setting this FALSE might help.
282	 * @param clockIsStable TRUE tells CoreAudio to use an agressive PLL to quickly lock to the engine's sample rate
283	 * while FALSE tells CoreAudio to adjust more slowly to perceived sample rate changes that might just be the
284	 * result of an unstable clock.
285     */
286	virtual void setClockIsStable(bool clockIsStable);
287
288	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 7);
289	/*!
290     * @function setMixClipOverhead
291     * @abstract Used to tell IOAudioFamily when the watchdog timer must fire by.
292     * @discussion setMixClipOverhead allows an audio engine to tell IOAudioFamily how much time
293	 * an engine will take to mix and clip its samples, in percent.
294	 * The default value is 10, meaning 10%.  This will cause IOAudioFamily to make
295	 * the watchdog timer fire when there is just over 10% of the time to complete
296	 * a buffer set left (e.g. 51 samples when the HAL is using a buffer size of 512
297	 * samples).
298     * @param newMixClipOverhead How much time per buffer should be made available for the
299	 * mix and clip routines to run.  Valid values are 1 through 99, inclusive.
300     * @result return no error
301	*/
302	virtual void setMixClipOverhead(UInt32 newMixClipOverhead);
303
304	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 8);
305    /*!
306	 * @function setClockDomain
307     * @abstract Sets a property that CoreAudio uses to determine how devices are synchronized.  If an audio device can tell that it is
308	 * synchronized to another engine, it should set this value to that engine's clock domain.  If an audio device can be a clock master, it may publish
309	 * its own clock domain for other devices to use.
310	 * @param clockDomain is the unique ID of another engine that this engine realizes it is synchronized to, use the default value kIOAudioNewClockDomain
311	 * to have IOAudioEngine create a unique clock domain.
312     */
313	virtual void setClockDomain(UInt32 clockDomain = kIOAudioNewClockDomain);
314
315	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 9);
316    /*!
317	 * @function convertInputSamplesVBR
318     * @abstract Override this method if you want to return a different number of sample frames than was requested.
319     */
320	virtual IOReturn convertInputSamplesVBR(const void *sampleBuf, void *destBuf, UInt32 firstSampleFrame, UInt32 &numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
321
322	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 10);
323    /*!
324	 * @function setInputSampleOffset
325     * @abstract set the offset CoreAudio will read from off the current read pointer
326	 * @param numSamples size of offset in sample
327	 */
328    virtual void setInputSampleOffset(UInt32 numSamples);
329
330	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 11);
331    /*!
332	 * @function setOutputSampleOffset
333     * @abstract set the offset CoreAudio will write at off the current write pointer
334	 * @param numSamples size of offset in sample
335	 */
336    virtual void setOutputSampleOffset(UInt32 numSamples);
337
338protected:
339
340	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 12);
341    virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioEngineUserClient **newUserClient, OSDictionary *properties);
342
343public:
344
345	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 13);
346	/*!
347	 * @function setAttributeForConnection
348	 * @abstract Generic method to set some attribute of the audio engine, specific to one connection.
349	 * @discussion IOAudioEngine subclasses may implement this method to allow arbitrary attribute/value pairs to be set, specific to one connection.
350	 * @param attribute Defines the attribute to be set.
351	 * @param value The new value for the attribute.
352	 * @result an IOReturn code.
353	 */
354
355    virtual IOReturn setAttributeForConnection( SInt32 connectIndex, UInt32 attribute, uintptr_t value );
356
357	// OSMetaClassDeclareReservedUsed(IOAudioEngine, 14);
358	/*! @function getAttributeForConnection
359	 * @abstract Generic method to retrieve some attribute of the audio engine, specific to one connection.
360	 * @discussion IOAudioEngine subclasses may implement this method to allow arbitrary attribute/value pairs to be returned, specific to one connection.
361	 * @param attribute Defines the attribute to be returned. Some defined attributes are:<br>
362	 * @param value Returns the value for the attribute.
363	 * @result an IOReturn code.
364	 */
365
366    virtual IOReturn getAttributeForConnection( SInt32 connectIndex, UInt32 attribute, uintptr_t * value );
367
368private:
369	OSMetaClassDeclareReservedUsed(IOAudioEngine, 0);
370	OSMetaClassDeclareReservedUsed(IOAudioEngine, 1);
371	OSMetaClassDeclareReservedUsed(IOAudioEngine, 2);
372	OSMetaClassDeclareReservedUsed(IOAudioEngine, 3);
373	OSMetaClassDeclareReservedUsed(IOAudioEngine, 4);
374	OSMetaClassDeclareReservedUsed(IOAudioEngine, 5);
375	OSMetaClassDeclareReservedUsed(IOAudioEngine, 6);
376	OSMetaClassDeclareReservedUsed(IOAudioEngine, 7);
377	OSMetaClassDeclareReservedUsed(IOAudioEngine, 8);
378	OSMetaClassDeclareReservedUsed(IOAudioEngine, 9);
379	OSMetaClassDeclareReservedUsed(IOAudioEngine, 10);
380	OSMetaClassDeclareReservedUsed(IOAudioEngine, 11);
381	OSMetaClassDeclareReservedUsed(IOAudioEngine, 12);
382	OSMetaClassDeclareReservedUsed(IOAudioEngine, 13);
383	OSMetaClassDeclareReservedUsed(IOAudioEngine, 14);
384
385	OSMetaClassDeclareReservedUnused(IOAudioEngine, 15);
386	OSMetaClassDeclareReservedUnused(IOAudioEngine, 16);
387	OSMetaClassDeclareReservedUnused(IOAudioEngine, 17);
388	OSMetaClassDeclareReservedUnused(IOAudioEngine, 18);
389	OSMetaClassDeclareReservedUnused(IOAudioEngine, 19);
390	OSMetaClassDeclareReservedUnused(IOAudioEngine, 20);
391	OSMetaClassDeclareReservedUnused(IOAudioEngine, 21);
392	OSMetaClassDeclareReservedUnused(IOAudioEngine, 22);
393	OSMetaClassDeclareReservedUnused(IOAudioEngine, 23);
394	OSMetaClassDeclareReservedUnused(IOAudioEngine, 24);
395	OSMetaClassDeclareReservedUnused(IOAudioEngine, 25);
396	OSMetaClassDeclareReservedUnused(IOAudioEngine, 26);
397	OSMetaClassDeclareReservedUnused(IOAudioEngine, 27);
398	OSMetaClassDeclareReservedUnused(IOAudioEngine, 28);
399	OSMetaClassDeclareReservedUnused(IOAudioEngine, 29);
400	OSMetaClassDeclareReservedUnused(IOAudioEngine, 30);
401	OSMetaClassDeclareReservedUnused(IOAudioEngine, 31);
402	OSMetaClassDeclareReservedUnused(IOAudioEngine, 32);
403	OSMetaClassDeclareReservedUnused(IOAudioEngine, 33);
404	OSMetaClassDeclareReservedUnused(IOAudioEngine, 34);
405	OSMetaClassDeclareReservedUnused(IOAudioEngine, 35);
406	OSMetaClassDeclareReservedUnused(IOAudioEngine, 36);
407	OSMetaClassDeclareReservedUnused(IOAudioEngine, 37);
408	OSMetaClassDeclareReservedUnused(IOAudioEngine, 38);
409	OSMetaClassDeclareReservedUnused(IOAudioEngine, 39);
410	OSMetaClassDeclareReservedUnused(IOAudioEngine, 40);
411	OSMetaClassDeclareReservedUnused(IOAudioEngine, 41);
412	OSMetaClassDeclareReservedUnused(IOAudioEngine, 42);
413	OSMetaClassDeclareReservedUnused(IOAudioEngine, 43);
414	OSMetaClassDeclareReservedUnused(IOAudioEngine, 44);
415	OSMetaClassDeclareReservedUnused(IOAudioEngine, 45);
416	OSMetaClassDeclareReservedUnused(IOAudioEngine, 46);
417	OSMetaClassDeclareReservedUnused(IOAudioEngine, 47);
418
419public:
420    /*!
421     * @function createDictionaryFromSampleRate
422     * @abstract Generates a dictionary matching the given sample rate.
423     * @discussion This is an internal routine used to generate a dictionary matching the given sample rate.  It is used to generate a sample rate dictionary for the I/O Registry - used by the
424     *  CoreAudio.framework.
425     * @result Returns the newly create OSDictionary.
426     */
427    static OSDictionary *createDictionaryFromSampleRate(const IOAudioSampleRate *sampleRate, OSDictionary *rateDict = 0);
428
429    /*!
430     * @function createSampleRateFromDictionary
431     * @abstract Generates a sample rate from an OSDictionary.
432     * @discussion This is an internal routine used to generate a sample rate from an OSDictionary.  It is used to generate a sample rate give a new OSDictionary from the IORegistry - coming
433     *  from the CoreAudio.framework.
434     * @result Returns the sample rate.
435     */
436    static IOAudioSampleRate *createSampleRateFromDictionary(const OSDictionary *rateDict, IOAudioSampleRate *sampleRate = 0);
437
438    /*!
439     * @function init
440     * @abstract Performs initialization of a newly allocated IOAudioEngine.
441     * @discussion This function is responsible for initialization of all of the general attributes of
442     *  a new IOAudioEngine.  It initializes instance variables to their default
443     *  values and allocates the shared status buffer.  Subclasses will likely want to override this method
444     *  and do all of their common initialization in their implementation.  They do need to be sure to call
445     *  IOAudioEngine's implementation of init and pay attention to the return value.
446     * @param properties The default properties for the IOAudioEngine.
447     * @result Returns true if initialization was successful.
448     */
449    virtual bool init(OSDictionary *properties);
450
451    /*!
452     * @function free
453     * @abstract Frees all of the resources allocated by the IOAudioEngine.
454     * @discussion Do not call this directly.  This is called automatically by the system when the instance's
455     *  refcount goes to 0.  To decrement the refcount, call release() on the object.
456     */
457    virtual void free();
458
459    /*!
460     * @function getWorkLoop
461     * @abstract Returns the IOWorkLoop for the driver.
462     */
463    virtual IOWorkLoop *getWorkLoop() const;
464
465    /*!
466     * @function getCommandGate
467     * @abstract Returns the IOCommandGate for this IOAudioEngine.
468     */
469    virtual IOCommandGate *getCommandGate() const;
470
471    /*!
472     * @function start
473     * @abstract A simple cover function for start(IOService *, IOAudioDevice *) that assumes the provider
474     *  is the IOAudioDevice.
475     * @discussion Subclasses will want to override start(IOService *, IOAudioDevice *) rather than this
476     *  one.
477     * @param provider The service provider for the IOAudioEngine (the IOAudioDevice in this case).
478     * @result Returns true if the IOAudioEngine was successfully started.
479     */
480    virtual bool start(IOService *provider);
481
482    /*!
483     * @function start
484     * @abstract Standard IOKit start() routine called to start an IOService.
485     * @discussion This function is called in order to prepare the IOAudioEngine for use.  It does NOT
486     *  mean that the audio I/O engine itself should be started.  This implementation gets the IOWorkLoop
487     *  from the IOAudioDevice and allocates an IOCommandGate.  Finally it calls initHardware() in which
488     *  all of the subclass-specific device initialization should be done.  Upon return from initHardware()
489     *  all IOAudioStreams should be created and added to the audio engine.  Also, all IOAudioControls
490     *  for this IOAudioEngine should be created and attached.
491     * @param provider The service provider for the IOAudioEngine.
492     * @param device The IOAudioDevice to which this IOAudioEngine belongs.
493     * @result Returns true if the service was successfully started.
494     */
495    virtual bool start(IOService *provider, IOAudioDevice *device);
496
497    /*!
498     * @function initHardware
499     * @abstract This function is called by start() to provide a convenient place for the subclass to
500     *  perform its hardware initialization.
501     * @discussion Upon return from this function, all IOAudioStreams and IOAudioControls should be created
502     *  and the audio engine should be ready to be started when a client requests that playback begin.
503     * @function provider The service provider numb for this audio engine - typically the IOAudioDevice.
504     * @result Returns true if the hardware was successfully initialized.
505     */
506    virtual bool initHardware(IOService *provider);
507
508    /*!
509     * @function stop
510     * @abstract Stops the service and prepares for the driver to be terminated.
511     * @discussion This function is called before the driver is terminated and usually means that the device
512     *  has been removed from the system.
513     * @param provider The service provider for the IOAudioEngine.
514     */
515    virtual void stop(IOService *provider);
516
517    /*!
518     * @function registerService
519     * @abstract Called when this audio engine is ready to begin vending services.
520     * @discussion This function is called by IOAudioDevice::activateAudioEngine() once the audio engine
521     *  has been fully initialized and is ready to begin audio playback.
522     * @param options
523     */
524    virtual void registerService(IOOptionBits options = 0);
525
526    virtual void setAudioDevice(IOAudioDevice *device);
527    virtual void setIndex(UInt32 index);
528
529    virtual void setDescription(const char *description);
530
531    /*!
532     * @function newUserClient
533     * @abstract Requests a new user client object for this service.
534     * @discussion This function is called automatically by I/O Kit when a user process attempts
535     *  to connect to this service.  It allocates a new IOAudioEngineUserClient object and increments
536     *  the number of connections for this audio engine.  If this is the first user client for this IOAudioEngine,
537     *  it calls startAudioEngine().  There is no need to call this function directly.
538	 *  A derived class that requires overriding of newUserClient should override the version with the properties
539	 *  parameter for Intel targets, and without the properties parameter for PPC targets.  The #if __i386__ directive
540	 *  can be used to select between the two behaviors.
541     * @param task The task requesting the new user client.
542     * @param securityID Optional security paramater passed in by the client - ignored.
543     * @param type Optional user client type passed in by the client - ignored.
544     * @param handler The new IOUserClient * must be stored in this param on a successful completion.
545     * @param properties A dictionary of additional properties for the connection.
546     * @result Returns kIOReturnSuccess on success.  May also result kIOReturnError or kIOReturnNoMemory.
547     */
548    virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, IOUserClient **handler);
549    virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, OSDictionary *properties, IOUserClient **handler);
550
551    /*!
552     * @function addAudioStream
553     * @abstract Adds an IOAudioStream to the audio engine.
554     * @discussion This function is called by the driver to add an IOAudioStream to the audio engine.  This must be called at least once to make sure the audio engine has at least one IOAudioStream.
555     * @param stream The IOAudioStream to be added.
556     * @result Returns kIOReturnSuccess if the stream was successfully added.
557     */
558    virtual IOReturn addAudioStream(IOAudioStream *stream);
559
560    virtual IOAudioStream *getAudioStream(IOAudioStreamDirection direction, UInt32 channelID);
561
562    virtual void lockAllStreams();
563    virtual void unlockAllStreams();
564
565    virtual void updateChannelNumbers();
566
567    /*!
568     * @function resetStatusBuffer
569     * @abstract Resets the status buffer to its default values.
570     * @discussion This is called during startAudioEngine() and resumeAudioEngine() to clear out the status buffer
571     *  in preparation of starting up the I/O engine.  There is no need to call this directly.
572     */
573    virtual void resetStatusBuffer();
574
575    /*!
576     * @function clearAllSampleBuffers
577     * @abstract Zeros out all of the sample and mix buffers associated with the IOAudioEngine
578     * @discussion This is called during resumeAudioEngine() since the audio engine gets started back at the
579     *  beginning of the sample buffer.
580     */
581    virtual void clearAllSampleBuffers();
582
583    /*!
584     * @function getCurrentSampleFrame
585     * @abstract Gets the current sample frame from the IOAudioEngine subclass.
586     * @result
587     */
588    virtual UInt32 getCurrentSampleFrame() = 0;
589
590    /*!
591     * @function startAudioEngine
592     * @abstract Starts the audio I/O engine.
593     * @discussion This method is called automatically when the audio engine is placed into use the first time.
594     *  This must be overridden by the subclass.  No call to the superclass's implementation is
595     *  necessary.  The subclass's implementation must start up the audio I/O engine.  This includes any audio
596     *  engine that needs to be started as well as any interrupts that need to be enabled.  Upon successfully
597     *  starting the engine, the subclass's implementation must call setState(kIOAudioEngineRunning).  If
598     *  it has also checked the state using getState() earlier in the implementation, the stateLock must be
599     *  acquired for the entire initialization process (using IORecursiveLockLock(stateLock) and
600     *  IORecursiveLockUnlock(stateLock)) to ensure that the state remains consistent.  See the general class
601     *  comments for an example.
602     * @result Must return kIOReturnSuccess on a successful start of the engine.
603     */
604    virtual IOReturn startAudioEngine();
605
606    /*!
607     * @function stopAudioEngine
608     * @abstract Stops the audio I/O engine.
609     * @discussion This method is called automatically when the last client disconnects from this audio engine.
610     *  It must be overridden by the subclass.  No call to the superclass's implementation is necessary.
611     *  The subclass's implementation must stop the audio I/O engine.  The audio engine (if it exists) should
612     *  be stopped and any interrupts disabled.  Upon successfully stopping the engine, the subclass must call
613     *  setState(kAudioEngineStopped).  If it has also checked the state using getState() earlier in the
614     *  implementation, the stateLock must be acquired for the entire initialization process (using
615     *  IORecursiveLockLock(stateLock) and IORecursiveLockUnlock(stateLock)) to ensure that the state remains
616     *  consistent.
617     * @result Must return kIOReturnSuccess on a successful stop of the engine.
618     */
619    virtual IOReturn stopAudioEngine();
620    virtual IOReturn pauseAudioEngine();
621    virtual IOReturn resumeAudioEngine();
622
623    /*!
624     * @function performAudioEngineStart
625     * @abstract Called to start the audio I/O engine
626     * @discussion This method is called by startAudioEngine().  This must be overridden by the subclass.
627	 *	No call to the superclass' implementation is necessary.  The subclass' implementation must start up the
628	 *	audio I/O engine.  This includes any audio engine that needs to be started as well as any interrupts
629	 *	that need to be enabled.
630     * @result Must return kIOReturnSuccess on a successful start of the engine.
631     */
632    virtual IOReturn performAudioEngineStart();
633
634    /*!
635     * @function performAudioEngineStop
636     * @abstract Called to stop the audio I/O engine
637     * @discussion This method is called by stopAudioEngine() and pauseAudioEngine.
638     *  This must be overridden by the subclass.  No call to the superclass' implementation is
639     *  necessary.  The subclass' implementation must stop the audio I/O engine.  This includes any audio
640     *  engine that needs to be stopped as well as any interrupts that need to be disabled.
641     * @result Must return kIOReturnSuccess on a successful stop of the engine.
642     */
643    virtual IOReturn performAudioEngineStop();
644
645    /*!
646     * @function getState
647     * @abstract Returns the current state of the IOAudioEngine.
648     * @discussion If this method is called in preparation for calling setState(), the stateLock must
649     *  be acquired before the first call to getState() and held until after the last call to setState().
650     *  Be careful not to return from the code acquiring the lock while the lock is being held.  That
651     *  will cause a deadlock situation.
652     * @result The current state of the IOAudioEngine: kIOAudioEngineRunning, kIOAudioEngineStopped.
653     */
654    virtual IOAudioEngineState getState();
655
656    /*!
657     * @function getSampleRate
658     * @abstract Returns the sample rate of the IOAudioEngine in samples per second.
659     */
660    virtual const IOAudioSampleRate *getSampleRate();
661
662    virtual IOReturn hardwareSampleRateChanged(const IOAudioSampleRate *sampleRate);
663
664    /*!
665     * @function getRunEraseHead
666     * @abstract Returns true if the audio engine will run the erase head when the audio engine is running.
667     */
668    virtual bool getRunEraseHead();
669
670    /*!
671     * @function getStatus
672     * @abstract Returns a pointer to the shared status buffer.
673     */
674    virtual const IOAudioEngineStatus *getStatus();
675
676    /*!
677     * @function timerCallback
678     * @abstract A static method used as a callback for the IOAudioDevice timer services.
679     * @discussion This method implements the IOAudioDevice::TimerEvent type.
680     * @param arg1 The IOAudioEngine that is the target of the event.
681     * @param device The IOAudioDevice that sent the timer event.
682     */
683    static void timerCallback(OSObject *arg1, IOAudioDevice *device);
684
685    /*!
686     * @function timerFired
687     * @abstract Indicates the timer has fired.
688     * @discussion This method is called by timerCallback to indicate the timer has fired.  This method calls performErase() and performFlush() to do erase head processing and
689     *  audio engine flushing each time the timer event fires.
690     */
691    virtual void timerFired();
692
693    /*!
694     * @function getTimerInterval
695     * @abstract Gets the timer interval for use by the timer event.
696     * @discussion This method is called each time the timer event is enabled through addTimer().  The default
697     *  implementation is set to return a value such that the timer event runs n times each cycle of the audio
698     *  engine through the sample buffer.  The value n is stored as the instance variable: numErasesPerBuffer.
699     *  The default value of numErasesPerBuffer is set to IOAUDIOENGINE_DEFAULT_NUM_ERASES_PER_BUFFER which is 4.
700     *  A subclass may change the value of numErasesPerBuffer or override getTimerInterval.  If it is overridden,
701     *  the subclass should call the superclass's implementation, compare its interval with the superclass's and
702     *  return the smaller of the two.
703     * @result Returns the interval for the timer event.
704     */
705    virtual AbsoluteTime getTimerInterval();
706
707    /*!
708     * @function performErase
709     * @abstract Performs erase head processing.
710     * @discussion This method is called automatically each time the timer event fires and erases the sample
711     *  buffer and mix buffer from the previous location up to the current location of the audio engine.
712     */
713    virtual void performErase();
714
715    /*!
716     * @function performFlush
717     * @abstract Performs the flush operation.
718     * @discussion This method is called automatically each time the timer event fires.  It stops the audio engine
719     *  if there are no more clients and the audio engine is passed the latest flush ending position.
720     */
721    virtual void performFlush();
722
723    virtual void stopEngineAtPosition(IOAudioEnginePosition *endingPosition);
724
725    virtual IOReturn mixOutputSamples(const void *sourceBuf, void *mixBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
726    virtual IOReturn clipOutputSamples(const void *mixBuf, void *sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
727    virtual void resetClipPosition(IOAudioStream *audioStream, UInt32 clipSampleFrame);
728    virtual IOReturn convertInputSamples(const void *sampleBuf, void *destBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
729
730    virtual void takeTimeStamp(bool incrementLoopCount = true, AbsoluteTime *timestamp = NULL);
731    virtual IOReturn getLoopCountAndTimeStamp(UInt32 *loopCount, AbsoluteTime *timestamp);
732
733    virtual IOReturn calculateSampleTimeout(AbsoluteTime *sampleInterval, UInt32 numSampleFrames, IOAudioEnginePosition *startingPosition, AbsoluteTime *wakeupTime);
734
735    virtual IOReturn performFormatChange(IOAudioStream *audioStream, const IOAudioStreamFormat *newFormat, const IOAudioSampleRate *newSampleRate);
736
737    virtual void beginConfigurationChange();
738    virtual void completeConfigurationChange();
739    virtual void cancelConfigurationChange();
740
741    virtual IOReturn addDefaultAudioControl(IOAudioControl *defaultAudioControl);
742    virtual IOReturn removeDefaultAudioControl(IOAudioControl *defaultAudioControl);
743    virtual void removeAllDefaultAudioControls();
744
745    virtual OSString *getGlobalUniqueID();
746    virtual OSString *getLocalUniqueID();
747
748protected:
749
750    /*!
751     * @function initKeys
752     * @abstract Generates the OSSymbols with the keys.
753     * @discussion Do not call this directly.  This is an internal initialization routine.
754     */
755    static void initKeys();
756
757    virtual void setNumSampleFramesPerBuffer(UInt32 numSampleFrames);
758    virtual UInt32 getNumSampleFramesPerBuffer();
759
760    /*!
761     * @function setState
762     * @abstract Indicates that the audio engine is in the specified state.
763     * @discussion This method simply sets the internal state of the audio engine to the specified state.  It does not
764     *  affect a change to the state.  It does however keep other internal state-related attributes consistent.
765     *  For example, it enables or disables the timer as needed when the state changes to running or stopped.
766     * @param newState The state the audio engine is in.
767     * @result Returns the old state.
768     */
769    virtual IOAudioEngineState setState(IOAudioEngineState newState);
770
771    /*!
772     * @function setSampleRate
773     * @abstract Records the sample rate of the audio engine.
774     * @discussion  This method must be called during initialization of a new audio engine to record the audio engine's
775     *  initial sample rate.  It also is intended to be used to record changes to the sample rate during use.
776     *  Currently changing sample rates after the audio engine has been started is not supported.
777     *  It may require that the sample buffers be re-sized.  This will be available in an upcoming release.
778     * @param newSampleRate The sample rate of the audio engine in samples per second.
779     */
780    virtual void setSampleRate(const IOAudioSampleRate *newSampleRate);
781
782    /*!
783     * @function setSampleLatency
784     * @abstract Sets the sample latency for the audio engine.
785     * @discussion The sample latency represents the number of samples ahead of the playback head
786     *  that it is safe to write into the sample buffer.  The audio device API will never write
787     *  closer to the playback head than the number of samples specified.  For input audio engines
788     *  the number of samples is behind the record head.
789     */
790    virtual void setSampleLatency(UInt32 numSamples);
791    virtual void setOutputSampleLatency(UInt32 numSamples);
792    virtual void setInputSampleLatency(UInt32 numSamples);
793    virtual void setSampleOffset(UInt32 numSamples);
794
795    /*!
796     * @function setRunEraseHead
797     * @abstract Tells the audio engine whether or not to run the erase head.
798     * @discussion By default, output audio engines run the erase head and input audio engines do not.  This method can
799     *  be called after setDirection() is called in order to change the default behavior.
800     * @param runEraseHead The audio engine will run the erase head if this value is true.
801     */
802    virtual void setRunEraseHead(bool runEraseHead);
803
804    /*!
805     * @function clientClosed
806     * @abstract Called automatically when a user client closes its connection to the audio engine.
807     * @discussion This method decrements the number of connections to the audio engine and if they reach
808     *  zero, the audio engine is called with a call to stopAudioEngine().  This method should not be called directly.
809     * @param client The user client that has disconnected.
810     */
811    virtual void clientClosed(IOAudioEngineUserClient *client);
812
813    /*!
814     * @function addTimer
815     * @abstract Enables the timer event for the audio engine.
816     * @discussion There is a timer event needed by the IOAudioEngine for processing the erase head
817     *  and performing flushing operations. When the timer fires, the method timerFired() is ultimately
818     *  called which in turn calls performErase() and performFlush().  This is called automatically
819     *  to enable the timer event for this audio engine.  It is called by setState() when the audio engine state
820     *  is set to kIOAudioEngineRunning.  When the timer is no longer needed, removeTimer() is called.
821     *  There is no need to call this directly.
822     */
823    virtual void addTimer();
824
825    /*!
826     * @function removeTimer
827     * @abstract Disables the timer event for the audio engine.
828     * @discussion  This method is called automatically to disable the timer event for this audio engine.
829     *  There is need to call it directly.  This method is called by setState() when the audio engine state
830     *  is changed from kIOAudioEngineRunning to one of the stopped states.
831     */
832    virtual void removeTimer();
833
834    virtual void sendFormatChangeNotification(IOAudioStream *audioStream);
835    virtual void sendNotification(UInt32 notificationType);
836
837    virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioEngineUserClient **newUserClient);
838
839	static IOReturn _addUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);		// <rdar://7529580>
840    static IOReturn addUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
841	static IOReturn _removeUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);	// <rdar://7529580>
842    static IOReturn removeUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
843    static IOReturn detachUserClientsAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
844
845    virtual IOReturn addUserClient(IOAudioEngineUserClient *newUserClient);
846    virtual IOReturn removeUserClient(IOAudioEngineUserClient *userClient);
847    virtual IOReturn detachUserClients();
848
849    virtual IOReturn startClient(IOAudioEngineUserClient *userClient);
850    virtual IOReturn stopClient(IOAudioEngineUserClient *userClient);
851
852    virtual IOReturn incrementActiveUserClients();
853    virtual IOReturn decrementActiveUserClients();
854
855    virtual void detachAudioStreams();
856	void setWorkLoopOnAllAudioControls(IOWorkLoop *wl);
857
858	static inline void lockStreamForIO(IOAudioStream *stream);
859	static inline void unlockStreamForIO(IOAudioStream *stream);
860
861	// These aren't virtual by design
862	UInt32 getNextStreamID(IOAudioStream * newStream);
863	IOAudioStream * getStreamForID(UInt32 streamID);
864
865	static void setCommandGateUsage(IOAudioEngine *engine, bool increment);		// <rdar://8518215>
866
867};
868
869#endif /* _IOKIT_IOAUDIOENGINE_H */
870