Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Trunk/i386/include/IOKit/audio/IOAudioEngine.h

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_BUFFER4
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 UInt32fSampleFrame;
61 UInt32fLoopCount;
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 UInt32numSampleFramesPerBuffer;
155
156 /*! @var sampleRate
157 * The current sample rate of the audio engine in samples per second. */
158 IOAudioSampleRatesampleRate;
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 UInt32numErasesPerBuffer;
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 boolrunEraseHead;
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 IOAudioEnginePositionaudioEngineStopPosition;
173
174 /*! @var isRegistered
175 * Internal state variable to keep track or whether registerService() has been called. */
176 boolisRegistered;
177 /*! @var configurationChangeInProgress
178 * Set to true after beginConfigurationChange() and false upon a
179 * subsequent call to completeConfigurationChange() or cancelConfigurationChange(). */
180 boolconfigurationChangeInProgress;
181
182 /*! @var state
183 * The current state of the IOAudioEngine - running, stopped, paused. */
184 IOAudioEngineStatestate;
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 UInt32maxNumInputChannels;
205 /*! @var outputStreams
206 * An OSSet of all of the output IOAudioStreams attached to this IOAudioEngine. */
207 OSOrderedSet*outputStreams;
208 UInt32maxNumOutputChannels;
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 UInt32numActiveUserClients;
220 UInt32sampleOffset;// used for input and output if inputSampleOffset is not set, if inputSampleOffset is set used as output only
221
222 UInt32index;
223 boolduringStartup;
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 booldeviceStartedAudioEngine;
233
234protected:
235 struct ExpansionData {
236UInt32pauseCount;
237IOBufferMemoryDescriptor*statusDescriptor;
238IOBufferMemoryDescriptor*bytesInInputBufferArrayDescriptor;
239IOBufferMemoryDescriptor*bytesInOutputBufferArrayDescriptor;
240UInt32mixClipOverhead;
241OSArray*streams;
242 UInt32inputSampleOffset;
243};
244
245 ExpansionData *reserved;
246
247//static UInt32sInstanceCount;
248
249public:
250// OSMetaClassDeclareReservedUsed(IOAudioEngine, 0);
251 virtual IOReturn performFormatChange(IOAudioStream *audioStream, const IOAudioStreamFormat *newFormat, const IOAudioStreamFormatExtension *formatExtension, const IOAudioSampleRate *newSampleRate);
252// OSMetaClassDeclareReservedUsed(IOAudioEngine, 1);
253virtual IOBufferMemoryDescriptor * getStatusDescriptor();
254// OSMetaClassDeclareReservedUsed(IOAudioEngine, 2);
255virtual IOReturn getNearestStartTime(IOAudioStream *audioStream, IOAudioTimeStamp *ioTimeStamp, bool isInput);
256// OSMetaClassDeclareReservedUsed(IOAudioEngine, 3);
257virtual IOBufferMemoryDescriptor * getBytesInInputBufferArrayDescriptor();
258// OSMetaClassDeclareReservedUsed(IOAudioEngine, 4);
259virtual IOBufferMemoryDescriptor * getBytesInOutputBufferArrayDescriptor();
260// OSMetaClassDeclareReservedUsed(IOAudioEngine, 5);
261 /*!
262 * @function eraseOutputSamples
263 * @abstract This function allows for the actual erasing of the mix and sample buffer to be overridden by
264 * a child class.
265 * @param mixBuf Pointer to the IOAudioFamily allocated mix buffer.
266 * @param sampleBuf Pointer to the child class' sample buffer.
267 * @param firstSampleFrame Index to the first sample frame to erase.
268 * @param numSampleFrames Number of sample frames to erase.
269 * @param streamFormat Format of the data to be erased.
270 * @param audioStream Pointer to stream object that corresponds to the sample buffer being erased.
271 * @result Must return kIOReturnSuccess if the samples have been erased.
272 */
273virtual IOReturn eraseOutputSamples(const void *mixBuf, void *sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
274// OSMetaClassDeclareReservedUsed(IOAudioEngine, 6);
275 /*!
276 * @function setClockIsStable
277 * @abstract This function sets a flag that CoreAudio uses to select its sample rate tracking algorithm. Set
278 * this to TRUE unless that results in dropped audio. If the driver is experiencing unexplained dropouts
279 * setting this FALSE might help.
280 * @param clockIsStable TRUE tells CoreAudio to use an agressive PLL to quickly lock to the engine's sample rate
281 * while FALSE tells CoreAudio to adjust more slowly to perceived sample rate changes that might just be the
282 * result of an unstable clock.
283 */
284virtual void setClockIsStable(bool clockIsStable);
285
286// OSMetaClassDeclareReservedUsed(IOAudioEngine, 7);
287/*!
288 * @function setMixClipOverhead
289 * @abstract Used to tell IOAudioFamily when the watchdog timer must fire by.
290 * @discussion setMixClipOverhead allows an audio engine to tell IOAudioFamily how much time
291 * an engine will take to mix and clip its samples, in percent.
292 * The default value is 10, meaning 10%. This will cause IOAudioFamily to make
293 * the watchdog timer fire when there is just over 10% of the time to complete
294 * a buffer set left (e.g. 51 samples when the HAL is using a buffer size of 512
295 * samples).
296 * @param newMixClipOverhead How much time per buffer should be made available for the
297 * mix and clip routines to run. Valid values are 1 through 99, inclusive.
298 * @result return no error
299*/
300virtual void setMixClipOverhead(UInt32 newMixClipOverhead);
301
302// OSMetaClassDeclareReservedUsed(IOAudioEngine, 8);
303 /*!
304 * @function setClockDomain
305 * @abstract Sets a property that CoreAudio uses to determine how devices are synchronized. If an audio device can tell that it is
306 * 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
307 * its own clock domain for other devices to use.
308 * @param clockDomain is the unique ID of another engine that this engine realizes it is synchronized to, use the default value kIOAudioNewClockDomain
309 * to have IOAudioEngine create a unique clock domain.
310 */
311virtual void setClockDomain(UInt32 clockDomain = kIOAudioNewClockDomain);
312
313// OSMetaClassDeclareReservedUsed(IOAudioEngine, 9);
314 /*!
315 * @function convertInputSamplesVBR
316 * @abstract Override this method if you want to return a different number of sample frames than was requested.
317 */
318virtual IOReturn convertInputSamplesVBR(const void *sampleBuf, void *destBuf, UInt32 firstSampleFrame, UInt32 &numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
319
320// OSMetaClassDeclareReservedUsed(IOAudioEngine, 10);
321 /*!
322 * @function setInputSampleOffset
323 * @abstract set the offset CoreAudio will read from off the current read pointer
324 * @param numSamples size of offset in sample
325 */
326 virtual void setInputSampleOffset(UInt32 numSamples);
327
328// OSMetaClassDeclareReservedUsed(IOAudioEngine, 11);
329 /*!
330 * @function setOutputSampleOffset
331 * @abstract set the offset CoreAudio will write at off the current write pointer
332 * @param numSamples size of offset in sample
333 */
334 virtual void setOutputSampleOffset(UInt32 numSamples);
335
336protected:
337
338// OSMetaClassDeclareReservedUsed(IOAudioEngine, 12);
339 virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioEngineUserClient **newUserClient, OSDictionary *properties);
340
341public:
342
343// OSMetaClassDeclareReservedUsed(IOAudioEngine, 13);
344/*!
345 * @function setAttributeForConnection
346 * @abstract Generic method to set some attribute of the audio engine, specific to one connection.
347 * @discussion IOAudioEngine subclasses may implement this method to allow arbitrary attribute/value pairs to be set, specific to one connection.
348 * @param attribute Defines the attribute to be set.
349 * @param value The new value for the attribute.
350 * @result an IOReturn code.
351 */
352
353 virtual IOReturn setAttributeForConnection( SInt32 connectIndex, UInt32 attribute, uintptr_t value );
354
355// OSMetaClassDeclareReservedUsed(IOAudioEngine, 14);
356/*! @function getAttributeForConnection
357 * @abstract Generic method to retrieve some attribute of the audio engine, specific to one connection.
358 * @discussion IOAudioEngine subclasses may implement this method to allow arbitrary attribute/value pairs to be returned, specific to one connection.
359 * @param attribute Defines the attribute to be returned. Some defined attributes are:<br>
360 * @param value Returns the value for the attribute.
361 * @result an IOReturn code.
362 */
363
364 virtual IOReturn getAttributeForConnection( SInt32 connectIndex, UInt32 attribute, uintptr_t * value );
365
366private:
367OSMetaClassDeclareReservedUsed(IOAudioEngine, 0);
368OSMetaClassDeclareReservedUsed(IOAudioEngine, 1);
369OSMetaClassDeclareReservedUsed(IOAudioEngine, 2);
370OSMetaClassDeclareReservedUsed(IOAudioEngine, 3);
371OSMetaClassDeclareReservedUsed(IOAudioEngine, 4);
372OSMetaClassDeclareReservedUsed(IOAudioEngine, 5);
373OSMetaClassDeclareReservedUsed(IOAudioEngine, 6);
374OSMetaClassDeclareReservedUsed(IOAudioEngine, 7);
375OSMetaClassDeclareReservedUsed(IOAudioEngine, 8);
376OSMetaClassDeclareReservedUsed(IOAudioEngine, 9);
377OSMetaClassDeclareReservedUsed(IOAudioEngine, 10);
378OSMetaClassDeclareReservedUsed(IOAudioEngine, 11);
379OSMetaClassDeclareReservedUsed(IOAudioEngine, 12);
380OSMetaClassDeclareReservedUsed(IOAudioEngine, 13);
381OSMetaClassDeclareReservedUsed(IOAudioEngine, 14);
382
383OSMetaClassDeclareReservedUnused(IOAudioEngine, 15);
384OSMetaClassDeclareReservedUnused(IOAudioEngine, 16);
385OSMetaClassDeclareReservedUnused(IOAudioEngine, 17);
386OSMetaClassDeclareReservedUnused(IOAudioEngine, 18);
387OSMetaClassDeclareReservedUnused(IOAudioEngine, 19);
388OSMetaClassDeclareReservedUnused(IOAudioEngine, 20);
389OSMetaClassDeclareReservedUnused(IOAudioEngine, 21);
390OSMetaClassDeclareReservedUnused(IOAudioEngine, 22);
391OSMetaClassDeclareReservedUnused(IOAudioEngine, 23);
392OSMetaClassDeclareReservedUnused(IOAudioEngine, 24);
393OSMetaClassDeclareReservedUnused(IOAudioEngine, 25);
394OSMetaClassDeclareReservedUnused(IOAudioEngine, 26);
395OSMetaClassDeclareReservedUnused(IOAudioEngine, 27);
396OSMetaClassDeclareReservedUnused(IOAudioEngine, 28);
397OSMetaClassDeclareReservedUnused(IOAudioEngine, 29);
398OSMetaClassDeclareReservedUnused(IOAudioEngine, 30);
399OSMetaClassDeclareReservedUnused(IOAudioEngine, 31);
400OSMetaClassDeclareReservedUnused(IOAudioEngine, 32);
401OSMetaClassDeclareReservedUnused(IOAudioEngine, 33);
402OSMetaClassDeclareReservedUnused(IOAudioEngine, 34);
403OSMetaClassDeclareReservedUnused(IOAudioEngine, 35);
404OSMetaClassDeclareReservedUnused(IOAudioEngine, 36);
405OSMetaClassDeclareReservedUnused(IOAudioEngine, 37);
406OSMetaClassDeclareReservedUnused(IOAudioEngine, 38);
407OSMetaClassDeclareReservedUnused(IOAudioEngine, 39);
408OSMetaClassDeclareReservedUnused(IOAudioEngine, 40);
409OSMetaClassDeclareReservedUnused(IOAudioEngine, 41);
410OSMetaClassDeclareReservedUnused(IOAudioEngine, 42);
411OSMetaClassDeclareReservedUnused(IOAudioEngine, 43);
412OSMetaClassDeclareReservedUnused(IOAudioEngine, 44);
413OSMetaClassDeclareReservedUnused(IOAudioEngine, 45);
414OSMetaClassDeclareReservedUnused(IOAudioEngine, 46);
415OSMetaClassDeclareReservedUnused(IOAudioEngine, 47);
416
417public:
418 /*!
419 * @function createDictionaryFromSampleRate
420 * @abstract Generates a dictionary matching the given sample rate.
421 * @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
422 * CoreAudio.framework.
423 * @result Returns the newly create OSDictionary.
424 */
425 static OSDictionary *createDictionaryFromSampleRate(const IOAudioSampleRate *sampleRate, OSDictionary *rateDict = 0);
426
427 /*!
428 * @function createSampleRateFromDictionary
429 * @abstract Generates a sample rate from an OSDictionary.
430 * @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
431 * from the CoreAudio.framework.
432 * @result Returns the sample rate.
433 */
434 static IOAudioSampleRate *createSampleRateFromDictionary(const OSDictionary *rateDict, IOAudioSampleRate *sampleRate = 0);
435
436 /*!
437 * @function init
438 * @abstract Performs initialization of a newly allocated IOAudioEngine.
439 * @discussion This function is responsible for initialization of all of the general attributes of
440 * a new IOAudioEngine. It initializes instance variables to their default
441 * values and allocates the shared status buffer. Subclasses will likely want to override this method
442 * and do all of their common initialization in their implementation. They do need to be sure to call
443 * IOAudioEngine's implementation of init and pay attention to the return value.
444 * @param properties The default properties for the IOAudioEngine.
445 * @result Returns true if initialization was successful.
446 */
447 virtual bool init(OSDictionary *properties);
448
449 /*!
450 * @function free
451 * @abstract Frees all of the resources allocated by the IOAudioEngine.
452 * @discussion Do not call this directly. This is called automatically by the system when the instance's
453 * refcount goes to 0. To decrement the refcount, call release() on the object.
454 */
455 virtual void free();
456
457 /*!
458 * @function getWorkLoop
459 * @abstract Returns the IOWorkLoop for the driver.
460 */
461 virtual IOWorkLoop *getWorkLoop() const;
462
463 /*!
464 * @function getCommandGate
465 * @abstract Returns the IOCommandGate for this IOAudioEngine.
466 */
467 virtual IOCommandGate *getCommandGate() const;
468
469 /*!
470 * @function start
471 * @abstract A simple cover function for start(IOService *, IOAudioDevice *) that assumes the provider
472 * is the IOAudioDevice.
473 * @discussion Subclasses will want to override start(IOService *, IOAudioDevice *) rather than this
474 * one.
475 * @param provider The service provider for the IOAudioEngine (the IOAudioDevice in this case).
476 * @result Returns true if the IOAudioEngine was successfully started.
477 */
478 virtual bool start(IOService *provider);
479
480 /*!
481 * @function start
482 * @abstract Standard IOKit start() routine called to start an IOService.
483 * @discussion This function is called in order to prepare the IOAudioEngine for use. It does NOT
484 * mean that the audio I/O engine itself should be started. This implementation gets the IOWorkLoop
485 * from the IOAudioDevice and allocates an IOCommandGate. Finally it calls initHardware() in which
486 * all of the subclass-specific device initialization should be done. Upon return from initHardware()
487 * all IOAudioStreams should be created and added to the audio engine. Also, all IOAudioControls
488 * for this IOAudioEngine should be created and attached.
489 * @param provider The service provider for the IOAudioEngine.
490 * @param device The IOAudioDevice to which this IOAudioEngine belongs.
491 * @result Returns true if the service was successfully started.
492 */
493 virtual bool start(IOService *provider, IOAudioDevice *device);
494
495 /*!
496 * @function initHardware
497 * @abstract This function is called by start() to provide a convenient place for the subclass to
498 * perform its hardware initialization.
499 * @discussion Upon return from this function, all IOAudioStreams and IOAudioControls should be created
500 * and the audio engine should be ready to be started when a client requests that playback begin.
501 * @function provider The service provider numb for this audio engine - typically the IOAudioDevice.
502 * @result Returns true if the hardware was successfully initialized.
503 */
504 virtual bool initHardware(IOService *provider);
505
506 /*!
507 * @function stop
508 * @abstract Stops the service and prepares for the driver to be terminated.
509 * @discussion This function is called before the driver is terminated and usually means that the device
510 * has been removed from the system.
511 * @param provider The service provider for the IOAudioEngine.
512 */
513 virtual void stop(IOService *provider);
514
515 /*!
516 * @function registerService
517 * @abstract Called when this audio engine is ready to begin vending services.
518 * @discussion This function is called by IOAudioDevice::activateAudioEngine() once the audio engine
519 * has been fully initialized and is ready to begin audio playback.
520 * @param options
521 */
522 virtual void registerService(IOOptionBits options = 0);
523
524 virtual void setAudioDevice(IOAudioDevice *device);
525 virtual void setIndex(UInt32 index);
526
527 virtual void setDescription(const char *description);
528
529 /*!
530 * @function newUserClient
531 * @abstract Requests a new user client object for this service.
532 * @discussion This function is called automatically by I/O Kit when a user process attempts
533 * to connect to this service. It allocates a new IOAudioEngineUserClient object and increments
534 * the number of connections for this audio engine. If this is the first user client for this IOAudioEngine,
535 * it calls startAudioEngine(). There is no need to call this function directly.
536 * A derived class that requires overriding of newUserClient should override the version with the properties
537 * parameter for Intel targets, and without the properties parameter for PPC targets. The #if __i386__ directive
538 * can be used to select between the two behaviors.
539 * @param task The task requesting the new user client.
540 * @param securityID Optional security paramater passed in by the client - ignored.
541 * @param type Optional user client type passed in by the client - ignored.
542 * @param handler The new IOUserClient * must be stored in this param on a successful completion.
543 * @param properties A dictionary of additional properties for the connection.
544 * @result Returns kIOReturnSuccess on success. May also result kIOReturnError or kIOReturnNoMemory.
545 */
546 virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, IOUserClient **handler);
547 virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, OSDictionary *properties, IOUserClient **handler);
548
549 /*!
550 * @function addAudioStream
551 * @abstract Adds an IOAudioStream to the audio engine.
552 * @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.
553 * @param stream The IOAudioStream to be added.
554 * @result Returns kIOReturnSuccess if the stream was successfully added.
555 */
556 virtual IOReturn addAudioStream(IOAudioStream *stream);
557
558 virtual IOAudioStream *getAudioStream(IOAudioStreamDirection direction, UInt32 channelID);
559
560 virtual void lockAllStreams();
561 virtual void unlockAllStreams();
562
563 virtual void updateChannelNumbers();
564
565 /*!
566 * @function resetStatusBuffer
567 * @abstract Resets the status buffer to its default values.
568 * @discussion This is called during startAudioEngine() and resumeAudioEngine() to clear out the status buffer
569 * in preparation of starting up the I/O engine. There is no need to call this directly.
570 */
571 virtual void resetStatusBuffer();
572
573 /*!
574 * @function clearAllSampleBuffers
575 * @abstract Zeros out all of the sample and mix buffers associated with the IOAudioEngine
576 * @discussion This is called during resumeAudioEngine() since the audio engine gets started back at the
577 * beginning of the sample buffer.
578 */
579 virtual void clearAllSampleBuffers();
580
581 /*!
582 * @function getCurrentSampleFrame
583 * @abstract Gets the current sample frame from the IOAudioEngine subclass.
584 * @result
585 */
586 virtual UInt32 getCurrentSampleFrame() = 0;
587
588 /*!
589 * @function startAudioEngine
590 * @abstract Starts the audio I/O engine.
591 * @discussion This method is called automatically when the audio engine is placed into use the first time.
592 * This must be overridden by the subclass. No call to the superclass's implementation is
593 * necessary. The subclass's implementation must start up the audio I/O engine. This includes any audio
594 * engine that needs to be started as well as any interrupts that need to be enabled. Upon successfully
595 * starting the engine, the subclass's implementation must call setState(kIOAudioEngineRunning). If
596 * it has also checked the state using getState() earlier in the implementation, the stateLock must be
597 * acquired for the entire initialization process (using IORecursiveLockLock(stateLock) and
598 * IORecursiveLockUnlock(stateLock)) to ensure that the state remains consistent. See the general class
599 * comments for an example.
600 * @result Must return kIOReturnSuccess on a successful start of the engine.
601 */
602 virtual IOReturn startAudioEngine();
603
604 /*!
605 * @function stopAudioEngine
606 * @abstract Stops the audio I/O engine.
607 * @discussion This method is called automatically when the last client disconnects from this audio engine.
608 * It must be overridden by the subclass. No call to the superclass's implementation is necessary.
609 * The subclass's implementation must stop the audio I/O engine. The audio engine (if it exists) should
610 * be stopped and any interrupts disabled. Upon successfully stopping the engine, the subclass must call
611 * setState(kAudioEngineStopped). If it has also checked the state using getState() earlier in the
612 * implementation, the stateLock must be acquired for the entire initialization process (using
613 * IORecursiveLockLock(stateLock) and IORecursiveLockUnlock(stateLock)) to ensure that the state remains
614 * consistent.
615 * @result Must return kIOReturnSuccess on a successful stop of the engine.
616 */
617 virtual IOReturn stopAudioEngine();
618 virtual IOReturn pauseAudioEngine();
619 virtual IOReturn resumeAudioEngine();
620
621 /*!
622 * @function performAudioEngineStart
623 * @abstract Called to start the audio I/O engine
624 * @discussion This method is called by startAudioEngine(). This must be overridden by the subclass.
625 *No call to the superclass' implementation is necessary. The subclass' implementation must start up the
626 *audio I/O engine. This includes any audio engine that needs to be started as well as any interrupts
627 *that need to be enabled.
628 * @result Must return kIOReturnSuccess on a successful start of the engine.
629 */
630 virtual IOReturn performAudioEngineStart();
631
632 /*!
633 * @function performAudioEngineStop
634 * @abstract Called to stop the audio I/O engine
635 * @discussion This method is called by stopAudioEngine() and pauseAudioEngine.
636 * This must be overridden by the subclass. No call to the superclass' implementation is
637 * necessary. The subclass' implementation must stop the audio I/O engine. This includes any audio
638 * engine that needs to be stopped as well as any interrupts that need to be disabled.
639 * @result Must return kIOReturnSuccess on a successful stop of the engine.
640 */
641 virtual IOReturn performAudioEngineStop();
642
643 /*!
644 * @function getState
645 * @abstract Returns the current state of the IOAudioEngine.
646 * @discussion If this method is called in preparation for calling setState(), the stateLock must
647 * be acquired before the first call to getState() and held until after the last call to setState().
648 * Be careful not to return from the code acquiring the lock while the lock is being held. That
649 * will cause a deadlock situation.
650 * @result The current state of the IOAudioEngine: kIOAudioEngineRunning, kIOAudioEngineStopped.
651 */
652 virtual IOAudioEngineState getState();
653
654 /*!
655 * @function getSampleRate
656 * @abstract Returns the sample rate of the IOAudioEngine in samples per second.
657 */
658 virtual const IOAudioSampleRate *getSampleRate();
659
660 virtual IOReturn hardwareSampleRateChanged(const IOAudioSampleRate *sampleRate);
661
662 /*!
663 * @function getRunEraseHead
664 * @abstract Returns true if the audio engine will run the erase head when the audio engine is running.
665 */
666 virtual bool getRunEraseHead();
667
668 /*!
669 * @function getStatus
670 * @abstract Returns a pointer to the shared status buffer.
671 */
672 virtual const IOAudioEngineStatus *getStatus();
673
674 /*!
675 * @function timerCallback
676 * @abstract A static method used as a callback for the IOAudioDevice timer services.
677 * @discussion This method implements the IOAudioDevice::TimerEvent type.
678 * @param arg1 The IOAudioEngine that is the target of the event.
679 * @param device The IOAudioDevice that sent the timer event.
680 */
681 static void timerCallback(OSObject *arg1, IOAudioDevice *device);
682
683 /*!
684 * @function timerFired
685 * @abstract Indicates the timer has fired.
686 * @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
687 * audio engine flushing each time the timer event fires.
688 */
689 virtual void timerFired();
690
691 /*!
692 * @function getTimerInterval
693 * @abstract Gets the timer interval for use by the timer event.
694 * @discussion This method is called each time the timer event is enabled through addTimer(). The default
695 * implementation is set to return a value such that the timer event runs n times each cycle of the audio
696 * engine through the sample buffer. The value n is stored as the instance variable: numErasesPerBuffer.
697 * The default value of numErasesPerBuffer is set to IOAUDIOENGINE_DEFAULT_NUM_ERASES_PER_BUFFER which is 4.
698 * A subclass may change the value of numErasesPerBuffer or override getTimerInterval. If it is overridden,
699 * the subclass should call the superclass's implementation, compare its interval with the superclass's and
700 * return the smaller of the two.
701 * @result Returns the interval for the timer event.
702 */
703 virtual AbsoluteTime getTimerInterval();
704
705 /*!
706 * @function performErase
707 * @abstract Performs erase head processing.
708 * @discussion This method is called automatically each time the timer event fires and erases the sample
709 * buffer and mix buffer from the previous location up to the current location of the audio engine.
710 */
711 virtual void performErase();
712
713 /*!
714 * @function performFlush
715 * @abstract Performs the flush operation.
716 * @discussion This method is called automatically each time the timer event fires. It stops the audio engine
717 * if there are no more clients and the audio engine is passed the latest flush ending position.
718 */
719 virtual void performFlush();
720
721 virtual void stopEngineAtPosition(IOAudioEnginePosition *endingPosition);
722
723 virtual IOReturn mixOutputSamples(const void *sourceBuf, void *mixBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
724 virtual IOReturn clipOutputSamples(const void *mixBuf, void *sampleBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
725 virtual void resetClipPosition(IOAudioStream *audioStream, UInt32 clipSampleFrame);
726 virtual IOReturn convertInputSamples(const void *sampleBuf, void *destBuf, UInt32 firstSampleFrame, UInt32 numSampleFrames, const IOAudioStreamFormat *streamFormat, IOAudioStream *audioStream);
727
728 virtual void takeTimeStamp(bool incrementLoopCount = true, AbsoluteTime *timestamp = NULL);
729 virtual IOReturn getLoopCountAndTimeStamp(UInt32 *loopCount, AbsoluteTime *timestamp);
730
731 virtual IOReturn calculateSampleTimeout(AbsoluteTime *sampleInterval, UInt32 numSampleFrames, IOAudioEnginePosition *startingPosition, AbsoluteTime *wakeupTime);
732
733 virtual IOReturn performFormatChange(IOAudioStream *audioStream, const IOAudioStreamFormat *newFormat, const IOAudioSampleRate *newSampleRate);
734
735 virtual void beginConfigurationChange();
736 virtual void completeConfigurationChange();
737 virtual void cancelConfigurationChange();
738
739 virtual IOReturn addDefaultAudioControl(IOAudioControl *defaultAudioControl);
740 virtual IOReturn removeDefaultAudioControl(IOAudioControl *defaultAudioControl);
741 virtual void removeAllDefaultAudioControls();
742
743 virtual OSString *getGlobalUniqueID();
744 virtual OSString *getLocalUniqueID();
745
746protected:
747
748 /*!
749 * @function initKeys
750 * @abstract Generates the OSSymbols with the keys.
751 * @discussion Do not call this directly. This is an internal initialization routine.
752 */
753 static void initKeys();
754
755 virtual void setNumSampleFramesPerBuffer(UInt32 numSampleFrames);
756 virtual UInt32 getNumSampleFramesPerBuffer();
757
758 /*!
759 * @function setState
760 * @abstract Indicates that the audio engine is in the specified state.
761 * @discussion This method simply sets the internal state of the audio engine to the specified state. It does not
762 * affect a change to the state. It does however keep other internal state-related attributes consistent.
763 * For example, it enables or disables the timer as needed when the state changes to running or stopped.
764 * @param newState The state the audio engine is in.
765 * @result Returns the old state.
766 */
767 virtual IOAudioEngineState setState(IOAudioEngineState newState);
768
769 /*!
770 * @function setSampleRate
771 * @abstract Records the sample rate of the audio engine.
772 * @discussion This method must be called during initialization of a new audio engine to record the audio engine's
773 * initial sample rate. It also is intended to be used to record changes to the sample rate during use.
774 * Currently changing sample rates after the audio engine has been started is not supported.
775 * It may require that the sample buffers be re-sized. This will be available in an upcoming release.
776 * @param newSampleRate The sample rate of the audio engine in samples per second.
777 */
778 virtual void setSampleRate(const IOAudioSampleRate *newSampleRate);
779
780 /*!
781 * @function setSampleLatency
782 * @abstract Sets the sample latency for the audio engine.
783 * @discussion The sample latency represents the number of samples ahead of the playback head
784 * that it is safe to write into the sample buffer. The audio device API will never write
785 * closer to the playback head than the number of samples specified. For input audio engines
786 * the number of samples is behind the record head.
787 */
788 virtual void setSampleLatency(UInt32 numSamples);
789 virtual void setOutputSampleLatency(UInt32 numSamples);
790 virtual void setInputSampleLatency(UInt32 numSamples);
791 virtual void setSampleOffset(UInt32 numSamples);
792
793 /*!
794 * @function setRunEraseHead
795 * @abstract Tells the audio engine whether or not to run the erase head.
796 * @discussion By default, output audio engines run the erase head and input audio engines do not. This method can
797 * be called after setDirection() is called in order to change the default behavior.
798 * @param runEraseHead The audio engine will run the erase head if this value is true.
799 */
800 virtual void setRunEraseHead(bool runEraseHead);
801
802 /*!
803 * @function clientClosed
804 * @abstract Called automatically when a user client closes its connection to the audio engine.
805 * @discussion This method decrements the number of connections to the audio engine and if they reach
806 * zero, the audio engine is called with a call to stopAudioEngine(). This method should not be called directly.
807 * @param client The user client that has disconnected.
808 */
809 virtual void clientClosed(IOAudioEngineUserClient *client);
810
811 /*!
812 * @function addTimer
813 * @abstract Enables the timer event for the audio engine.
814 * @discussion There is a timer event needed by the IOAudioEngine for processing the erase head
815 * and performing flushing operations. When the timer fires, the method timerFired() is ultimately
816 * called which in turn calls performErase() and performFlush(). This is called automatically
817 * to enable the timer event for this audio engine. It is called by setState() when the audio engine state
818 * is set to kIOAudioEngineRunning. When the timer is no longer needed, removeTimer() is called.
819 * There is no need to call this directly.
820 */
821 virtual void addTimer();
822
823 /*!
824 * @function removeTimer
825 * @abstract Disables the timer event for the audio engine.
826 * @discussion This method is called automatically to disable the timer event for this audio engine.
827 * There is need to call it directly. This method is called by setState() when the audio engine state
828 * is changed from kIOAudioEngineRunning to one of the stopped states.
829 */
830 virtual void removeTimer();
831
832 virtual void sendFormatChangeNotification(IOAudioStream *audioStream);
833 virtual void sendNotification(UInt32 notificationType);
834
835 virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioEngineUserClient **newUserClient);
836
837static IOReturn _addUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);// <rdar://7529580>
838 static IOReturn addUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
839static IOReturn _removeUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);// <rdar://7529580>
840 static IOReturn removeUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
841 static IOReturn detachUserClientsAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
842
843 virtual IOReturn addUserClient(IOAudioEngineUserClient *newUserClient);
844 virtual IOReturn removeUserClient(IOAudioEngineUserClient *userClient);
845 virtual IOReturn detachUserClients();
846
847 virtual IOReturn startClient(IOAudioEngineUserClient *userClient);
848 virtual IOReturn stopClient(IOAudioEngineUserClient *userClient);
849
850 virtual IOReturn incrementActiveUserClients();
851 virtual IOReturn decrementActiveUserClients();
852
853 virtual void detachAudioStreams();
854void setWorkLoopOnAllAudioControls(IOWorkLoop *wl);
855
856static inline void lockStreamForIO(IOAudioStream *stream);
857static inline void unlockStreamForIO(IOAudioStream *stream);
858
859// These aren't virtual by design
860UInt32 getNextStreamID(IOAudioStream * newStream);
861IOAudioStream * getStreamForID(UInt32 streamID);
862
863};
864
865#endif /* _IOKIT_IOAUDIOENGINE_H */
866

Archive Download this file

Revision: 1622