Jamoma API  0.6.0.a19
CAHALAudioDevice.cpp
1 /* Copyright 2007 Apple Inc. All Rights Reserved.
2 
3  Disclaimer: IMPORTANT: This Apple software is supplied to you by
4  Apple Inc. ("Apple") in consideration of your agreement to the
5  following terms, and your use, installation, modification or
6  redistribution of this Apple software constitutes acceptance of these
7  terms. If you do not agree with these terms, please do not use,
8  install, modify or redistribute this Apple software.
9 
10  In consideration of your agreement to abide by the following terms, and
11  subject to these terms, Apple grants you a personal, non-exclusive
12  license, under Apple's copyrights in this original Apple software (the
13  "Apple Software"), to use, reproduce, modify and redistribute the Apple
14  Software, with or without modifications, in source and/or binary forms;
15  provided that if you redistribute the Apple Software in its entirety and
16  without modifications, you must retain this notice and the following
17  text and disclaimers in all such redistributions of the Apple Software.
18  Neither the name, trademarks, service marks or logos of Apple Inc.
19  may be used to endorse or promote products derived from the Apple
20  Software without specific prior written permission from Apple. Except
21  as expressly stated in this notice, no other rights or licenses, express
22  or implied, are granted by Apple herein, including but not limited to
23  any patent rights that may be infringed by your derivative works or by
24  other works in which the Apple Software may be incorporated.
25 
26  The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
31 
32  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 //==================================================================================================
42 // Includes
43 //==================================================================================================
44 
45 // Self Include
46 #include "CAHALAudioDevice.h"
47 
48 // PublicUtility Includes
49 #include "CAAutoDisposer.h"
50 #include "CADebugMacros.h"
51 #include "CAException.h"
52 #include "CAHALAudioStream.h"
53 #include "CAHALAudioSystemObject.h"
54 #include "CAPropertyAddress.h"
55 
56 //==================================================================================================
57 // CAHALAudioDevice
58 //==================================================================================================
59 
60 CAHALAudioDevice::CAHALAudioDevice(AudioObjectID inAudioDevice)
61 :
62  CAHALAudioObject(inAudioDevice)
63 {
64 }
65 
66 CAHALAudioDevice::CAHALAudioDevice(CFStringRef inUID)
67 :
68  CAHALAudioObject(CAHALAudioSystemObject().GetAudioDeviceForUID(inUID))
69 {
70 }
71 
72 CAHALAudioDevice::~CAHALAudioDevice()
73 {
74 }
75 
76 CFStringRef CAHALAudioDevice::CopyDeviceUID() const
77 {
78  CAPropertyAddress theAddress(kAudioDevicePropertyDeviceUID);
79  return GetPropertyData_CFString(theAddress, 0, NULL);
80 }
81 
82 bool CAHALAudioDevice::HasModelUID() const
83 {
84  CAPropertyAddress theAddress(kAudioDevicePropertyModelUID);
85  return HasProperty(theAddress);
86 }
87 
88 CFStringRef CAHALAudioDevice::CopyModelUID() const
89 {
90  CAPropertyAddress theAddress(kAudioDevicePropertyModelUID);
91  return GetPropertyData_CFString(theAddress, 0, NULL);
92 }
93 
94 CFStringRef CAHALAudioDevice::CopyConfigurationApplicationBundleID() const
95 {
96  CAPropertyAddress theAddress(kAudioDevicePropertyConfigurationApplication);
97  return GetPropertyData_CFString(theAddress, 0, NULL);
98 }
99 
100 CFURLRef CAHALAudioDevice::CopyIconLocation() const
101 {
102  CFURLRef theAnswer = NULL;
103  CAPropertyAddress theAddress(kAudioDevicePropertyIcon);
104  UInt32 theSize = sizeof(CFURLRef);
105  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
106  return theAnswer;
107 }
108 
109 UInt32 CAHALAudioDevice::GetTransportType() const
110 {
111  CAPropertyAddress theAddress(kAudioDevicePropertyTransportType);
112  return GetPropertyData_UInt32(theAddress, 0, NULL);
113 }
114 
115 bool CAHALAudioDevice::CanBeDefaultDevice(bool inIsInput, bool inIsSystem) const
116 {
117  CAPropertyAddress theAddress(inIsSystem ? kAudioDevicePropertyDeviceCanBeDefaultSystemDevice : kAudioDevicePropertyDeviceCanBeDefaultDevice, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
118  return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
119 }
120 
121 bool CAHALAudioDevice::HasDevicePlugInStatus() const
122 {
123  CAPropertyAddress theAddress(kAudioDevicePropertyPlugIn);
124  return HasProperty(theAddress);
125 }
126 
127 OSStatus CAHALAudioDevice::GetDevicePlugInStatus() const
128 {
129  CAPropertyAddress theAddress(kAudioDevicePropertyPlugIn);
130  return GetPropertyData_UInt32(theAddress, 0, NULL);
131 }
132 
133 bool CAHALAudioDevice::IsAlive() const
134 {
135  CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsAlive);
136  return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
137 }
138 
139 bool CAHALAudioDevice::IsHidden() const
140 {
141  CAPropertyAddress theAddress(kAudioDevicePropertyIsHidden);
142  return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
143 }
144 
145 pid_t CAHALAudioDevice::GetHogModeOwner() const
146 {
147  pid_t theAnswer = -1;
148  CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
149  if(HasProperty(theAddress))
150  {
151  UInt32 theSize = sizeof(pid_t);
152  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
153  }
154  return theAnswer;
155 }
156 
157 bool CAHALAudioDevice::IsHogModeSettable() const
158 {
159  bool theAnswer = false;
160  CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
161  if(HasProperty(theAddress))
162  {
163  theAnswer = IsPropertySettable(theAddress);
164  }
165  return theAnswer;
166 }
167 
168 bool CAHALAudioDevice::TakeHogMode()
169 {
170  CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
171  pid_t thePID = getpid();
172  if(HasProperty(theAddress))
173  {
174  SetPropertyData(theAddress, 0, NULL, sizeof(pid_t), &thePID);
175  }
176  return thePID == getpid();
177 }
178 
179 void CAHALAudioDevice::ReleaseHogMode()
180 {
181  CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
182  if(HasProperty(theAddress))
183  {
184  pid_t thePID = -1;
185  SetPropertyData(theAddress, 0, NULL, sizeof(pid_t), &thePID);
186  }
187 }
188 
189 bool CAHALAudioDevice::HasPreferredStereoChannels(bool inIsInput) const
190 {
191  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
192  return HasProperty(theAddress);
193 }
194 
195 void CAHALAudioDevice::GetPreferredStereoChannels(bool inIsInput, UInt32& outLeft, UInt32& outRight) const
196 {
197  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
198  UInt32 theStereoPair[2] = { 0, 0 };
199  UInt32 theSize = 2 * sizeof(UInt32);
200  GetPropertyData(theAddress, 0, NULL, theSize, theStereoPair);
201  outLeft = theStereoPair[0];
202  outRight = theStereoPair[1];
203 }
204 
205 void CAHALAudioDevice::SetPreferredStereoChannels(bool inIsInput, UInt32 inLeft, UInt32 inRight)
206 {
207  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
208  UInt32 theStereoPair[2] = { inLeft, inRight };
209  SetPropertyData(theAddress, 0, NULL, 2 * sizeof(UInt32), theStereoPair);
210 }
211 
212 bool CAHALAudioDevice::HasPreferredChannelLayout(bool inIsInput) const
213 {
214  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
215  return HasProperty(theAddress);
216 }
217 
218 void CAHALAudioDevice::GetPreferredChannelLayout(bool inIsInput, AudioChannelLayout& outChannelLayout) const
219 {
220  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
221  UInt32 theSize = OffsetOf32(AudioChannelLayout, mChannelDescriptions) + GetTotalNumberChannels(inIsInput) * SizeOf32(AudioChannelDescription);
222  GetPropertyData(theAddress, 0, NULL, theSize, &outChannelLayout);
223 }
224 
225 void CAHALAudioDevice::SetPreferredStereoChannels(bool inIsInput, AudioChannelLayout& inChannelLayout)
226 {
227  CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
228  UInt32 theSize = OffsetOf32(AudioChannelLayout, mChannelDescriptions) + GetTotalNumberChannels(inIsInput) * SizeOf32(AudioChannelDescription);
229  SetPropertyData(theAddress, 0, NULL, theSize, &inChannelLayout);
230 }
231 
232 UInt32 CAHALAudioDevice::GetNumberRelatedAudioDevices() const
233 {
234  CAPropertyAddress theAddress(kAudioDevicePropertyRelatedDevices);
235  UInt32 theAnswer = 0;
236  if(HasProperty(theAddress))
237  {
238  theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
239  theAnswer /= sizeof(AudioObjectID);
240  }
241  return theAnswer;
242 }
243 
244 void CAHALAudioDevice::GetRelatedAudioDevices(UInt32& ioNumberRelatedDevices, AudioObjectID* outRelatedDevices) const
245 {
246  CAPropertyAddress theAddress(kAudioDevicePropertyRelatedDevices);
247  if(HasProperty(theAddress))
248  {
249  UInt32 theSize = ioNumberRelatedDevices * sizeof(AudioObjectID);
250  GetPropertyData(theAddress, 0, NULL, theSize, outRelatedDevices);
251  ioNumberRelatedDevices = theSize / sizeof(AudioObjectID);
252  }
253  else
254  {
255  UInt32 theSize = ioNumberRelatedDevices * sizeof(AudioObjectID);
256  memset(outRelatedDevices, 0, theSize);
257  ioNumberRelatedDevices = 0;
258  }
259 }
260 
261 AudioObjectID CAHALAudioDevice::GetRelatedAudioDeviceByIndex(UInt32 inIndex) const
262 {
263  AudioObjectID theAnswer = kAudioObjectUnknown;
264  UInt32 theNumberRelatedDevices = GetNumberRelatedAudioDevices();
265  if((theNumberRelatedDevices > 0) && (inIndex < theNumberRelatedDevices))
266  {
267  CAAutoArrayDelete<AudioObjectID> theRelatedDeviceList(theNumberRelatedDevices);
268  GetRelatedAudioDevices(theNumberRelatedDevices, theRelatedDeviceList);
269  if((theNumberRelatedDevices > 0) && (inIndex < theNumberRelatedDevices))
270  {
271  theAnswer = theRelatedDeviceList[inIndex];
272  }
273  }
274  return theAnswer;
275 }
276 
277 UInt32 CAHALAudioDevice::GetNumberStreams(bool inIsInput) const
278 {
279  CAPropertyAddress theAddress(kAudioDevicePropertyStreams, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
280  UInt32 theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
281  theAnswer /= sizeof(AudioObjectID);
282  return theAnswer;
283 }
284 
285 void CAHALAudioDevice::GetStreams(bool inIsInput, UInt32& ioNumberStreams, AudioObjectID* outStreamList) const
286 {
287  CAPropertyAddress theAddress(kAudioDevicePropertyStreams, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
288  UInt32 theSize = ioNumberStreams * sizeof(AudioObjectID);
289  GetPropertyData(theAddress, 0, NULL, theSize, outStreamList);
290  ioNumberStreams = theSize / sizeof(AudioObjectID);
291 }
292 
293 AudioObjectID CAHALAudioDevice::GetStreamByIndex(bool inIsInput, UInt32 inIndex) const
294 {
295  AudioObjectID theAnswer = kAudioObjectUnknown;
296  UInt32 theNumberStreams = GetNumberStreams(inIsInput);
297  if((theNumberStreams > 0) && (inIndex < theNumberStreams))
298  {
299  CAAutoArrayDelete<AudioObjectID> theStreamList(theNumberStreams);
300  GetStreams(inIsInput, theNumberStreams, theStreamList);
301  if((theNumberStreams > 0) && (inIndex < theNumberStreams))
302  {
303  theAnswer = theStreamList[inIndex];
304  }
305  }
306  return theAnswer;
307 }
308 
309 UInt32 CAHALAudioDevice::GetTotalNumberChannels(bool inIsInput) const
310 {
311  UInt32 theAnswer = 0;
312  CAPropertyAddress theAddress(kAudioDevicePropertyStreamConfiguration, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
313  UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
314  CAAutoFree<AudioBufferList> theBufferList(theSize);
315  GetPropertyData(theAddress, 0, NULL, theSize, theBufferList);
316  for(UInt32 theIndex = 0; theIndex < theBufferList->mNumberBuffers; ++theIndex)
317  {
318  theAnswer += theBufferList->mBuffers[theIndex].mNumberChannels;
319  }
320  return theAnswer;
321 }
322 
323 void CAHALAudioDevice::GetCurrentVirtualFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const
324 {
325  ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inIsInput));
326  for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex)
327  {
328  CAHALAudioStream theStream(GetStreamByIndex(inIsInput, theIndex));
329  theStream.GetCurrentVirtualFormat(outFormats[theIndex]);
330  }
331 }
332 
333 void CAHALAudioDevice::GetCurrentPhysicalFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const
334 {
335  ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inIsInput));
336  for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex)
337  {
338  CAHALAudioStream theStream(GetStreamByIndex(inIsInput, theIndex));
339  theStream.GetCurrentPhysicalFormat(outFormats[theIndex]);
340  }
341 }
342 
343 bool CAHALAudioDevice::IsRunning() const
344 {
345  CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsRunning);
346  UInt32 theAnswer = GetPropertyData_UInt32(theAddress, 0, NULL);
347  return theAnswer != 0;
348 }
349 
350 bool CAHALAudioDevice::IsRunningSomewhere() const
351 {
352  CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsRunningSomewhere);
353  UInt32 theAnswer = 0;
354  if(HasProperty(theAddress))
355  {
356  theAnswer = GetPropertyData_UInt32(theAddress, 0, NULL);
357  }
358  return theAnswer != 0;
359 }
360 
361 UInt32 CAHALAudioDevice::GetLatency(bool inIsInput) const
362 {
363  CAPropertyAddress theAddress(kAudioDevicePropertyLatency, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
364  return GetPropertyData_UInt32(theAddress, 0, NULL);
365 }
366 
367 UInt32 CAHALAudioDevice::GetSafetyOffset(bool inIsInput) const
368 {
369  CAPropertyAddress theAddress(kAudioDevicePropertySafetyOffset, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
370  return GetPropertyData_UInt32(theAddress, 0, NULL);
371 }
372 
373 bool CAHALAudioDevice::HasClockDomain() const
374 {
375  CAPropertyAddress theAddress(kAudioDevicePropertyClockDomain);
376  return HasProperty(theAddress);
377 }
378 
379 UInt32 CAHALAudioDevice::GetClockDomain() const
380 {
381  CAPropertyAddress theAddress(kAudioDevicePropertyClockDomain);
382  return GetPropertyData_UInt32(theAddress, 0, NULL);
383 }
384 
385 Float64 CAHALAudioDevice::GetActualSampleRate() const
386 {
387  Float64 theAnswer = 0;
388  CAPropertyAddress theAddress(kAudioDevicePropertyActualSampleRate);
389  if(HasProperty(theAddress))
390  {
391  UInt32 theSize = sizeof(Float64);
392  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
393  }
394  else
395  {
396  theAnswer = GetNominalSampleRate();
397  }
398  return theAnswer;
399 }
400 
401 Float64 CAHALAudioDevice::GetNominalSampleRate() const
402 {
403  Float64 theAnswer = 0;
404  CAPropertyAddress theAddress(kAudioDevicePropertyNominalSampleRate);
405  UInt32 theSize = sizeof(Float64);
406  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
407  return theAnswer;
408 }
409 
410 void CAHALAudioDevice::SetNominalSampleRate(Float64 inSampleRate)
411 {
412  CAPropertyAddress theAddress(kAudioDevicePropertyNominalSampleRate);
413  SetPropertyData(theAddress, 0, NULL, sizeof(Float64), &inSampleRate);
414 }
415 
416 UInt32 CAHALAudioDevice::GetNumberAvailableNominalSampleRateRanges() const
417 {
418  UInt32 theAnswer = 0;
419  CAPropertyAddress theAddress(kAudioDevicePropertyAvailableNominalSampleRates);
420  if(HasProperty(theAddress))
421  {
422  UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
423  theAnswer = theSize / sizeof(AudioValueRange);
424  }
425  return theAnswer;
426 }
427 
428 void CAHALAudioDevice::GetAvailableNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const
429 {
430  CAPropertyAddress theAddress(kAudioDevicePropertyAvailableNominalSampleRates);
431  if(HasProperty(theAddress))
432  {
433  UInt32 theSize = ioNumberRanges * sizeof(AudioValueRange);
434  GetPropertyData(theAddress, 0, NULL, theSize, outRanges);
435  ioNumberRanges = theSize / sizeof(AudioValueRange);
436  }
437  else
438  {
439  ioNumberRanges = 0;
440  }
441 }
442 
443 void CAHALAudioDevice::GetAvailableNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const
444 {
445  UInt32 theNumberRanges = GetNumberAvailableNominalSampleRateRanges();
446  ThrowIf(inIndex >= theNumberRanges, CAException(kAudioHardwareIllegalOperationError), "CAHALAudioDevice::GetAvailableNominalSampleRateRangeByIndex: index out of range");
447  CAAutoArrayDelete<AudioValueRange> theRanges(theNumberRanges);
448  GetAvailableNominalSampleRateRanges(theNumberRanges, theRanges);
449  outMinimum = theRanges[inIndex].mMinimum;
450  outMaximum = theRanges[inIndex].mMaximum;
451 }
452 
453 bool CAHALAudioDevice::IsValidNominalSampleRate(Float64 inSampleRate) const
454 {
455  bool theAnswer = false;
456  UInt32 theNumberRanges = GetNumberAvailableNominalSampleRateRanges();
457  CAAutoArrayDelete<AudioValueRange> theRanges(theNumberRanges);
458  GetAvailableNominalSampleRateRanges(theNumberRanges, theRanges);
459  for(UInt32 theIndex = 0; !theAnswer && (theIndex < theNumberRanges); ++theIndex)
460  {
461  theAnswer = (inSampleRate >= theRanges[theIndex].mMinimum) && (inSampleRate <= theRanges[theIndex].mMinimum);
462  }
463  return theAnswer;
464 }
465 
466 bool CAHALAudioDevice::IsIOBufferSizeSettable() const
467 {
468  CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
469  return IsPropertySettable(theAddress);
470 }
471 
472 UInt32 CAHALAudioDevice::GetIOBufferSize() const
473 {
474  CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
475  return GetPropertyData_UInt32(theAddress, 0, NULL);
476 }
477 
478 void CAHALAudioDevice::SetIOBufferSize(UInt32 inBufferSize)
479 {
480  CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
481  SetPropertyData(theAddress, 0, NULL, sizeof(UInt32), &inBufferSize);
482 }
483 
484 bool CAHALAudioDevice::UsesVariableIOBufferSizes() const
485 {
486  CAPropertyAddress theAddress(kAudioDevicePropertyUsesVariableBufferFrameSizes);
487  return HasProperty(theAddress);
488 }
489 
490 UInt32 CAHALAudioDevice::GetMaximumVariableIOBufferSize() const
491 {
492  CAPropertyAddress theAddress(kAudioDevicePropertyUsesVariableBufferFrameSizes);
493  return GetPropertyData_UInt32(theAddress, 0, NULL);
494 }
495 
496 bool CAHALAudioDevice::HasIOBufferSizeRange() const
497 {
498  CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSizeRange);
499  return HasProperty(theAddress);
500 }
501 
502 void CAHALAudioDevice::GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const
503 {
504  AudioValueRange theAnswer = { 0, 0 };
505  CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSizeRange);
506  UInt32 theSize = sizeof(AudioValueRange);
507  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
508  outMinimum = static_cast<UInt32>(theAnswer.mMinimum);
509  outMaximum = static_cast<UInt32>(theAnswer.mMaximum);
510 }
511 
512 AudioDeviceIOProcID CAHALAudioDevice::CreateIOProcID(AudioDeviceIOProc inIOProc, void* inClientData)
513 {
514  AudioDeviceIOProcID theAnswer = NULL;
515  OSStatus theError = AudioDeviceCreateIOProcID(mObjectID, inIOProc, inClientData, &theAnswer);
516  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::CreateIOProcID: got an error creating the IOProc ID");
517  return theAnswer;
518 }
519 
520 void CAHALAudioDevice::DestroyIOProcID(AudioDeviceIOProcID inIOProcID)
521 {
522  OSStatus theError = AudioDeviceDestroyIOProcID(mObjectID, inIOProcID);
523  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::DestroyIOProcID: got an error destroying the IOProc ID");
524 }
525 
526 void CAHALAudioDevice::StartIOProc(AudioDeviceIOProcID inIOProcID)
527 {
528  OSStatus theError = AudioDeviceStart(mObjectID, inIOProcID);
529  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StartIOProc: got an error starting an IOProc");
530 }
531 
532 void CAHALAudioDevice::StartIOProcAtTime(AudioDeviceIOProcID inIOProcID, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware)
533 {
534  UInt32 theFlags = 0;
535  if(inIsInput)
536  {
537  theFlags |= kAudioDeviceStartTimeIsInputFlag;
538  }
539  if(inIgnoreHardware)
540  {
541  theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag;
542  }
543 
544  OSStatus theError = AudioDeviceStartAtTime(mObjectID, inIOProcID, &ioStartTime, theFlags);
545  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StartIOProcAtTime: got an error starting an IOProc");
546 }
547 
548 void CAHALAudioDevice::StopIOProc(AudioDeviceIOProcID inIOProcID)
549 {
550  OSStatus theError = AudioDeviceStop(mObjectID, inIOProcID);
551  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StopIOProc: got an error stopping an IOProc");
552 }
553 
554 void CAHALAudioDevice::GetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, bool* outStreamUsage) const
555 {
556  // make an AudioHardwareIOProcStreamUsage the right size
557  UInt32 theNumberStreams = GetNumberStreams(inIsInput);
558  UInt32 theSize = sizeof(void*) + sizeof(UInt32) + (theNumberStreams * sizeof(UInt32));
559  CAAutoFree<AudioHardwareIOProcStreamUsage> theStreamUsage(theSize);
560 
561  // set it up
562  theStreamUsage->mIOProc = reinterpret_cast<void*>(inIOProcID);
563  theStreamUsage->mNumberStreams = theNumberStreams;
564 
565  // get the property
566  CAPropertyAddress theAddress(kAudioDevicePropertyIOProcStreamUsage, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
567  GetPropertyData(theAddress, 0, NULL, theSize, theStreamUsage);
568 
569  // fill out the return value
570  for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex)
571  {
572  outStreamUsage[theIndex] = (theStreamUsage->mStreamIsOn[theIndex] != 0);
573  }
574 }
575 
576 void CAHALAudioDevice::SetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, const bool* inStreamUsage)
577 {
578  // make an AudioHardwareIOProcStreamUsage the right size
579  UInt32 theNumberStreams = GetNumberStreams(inIsInput);
580  UInt32 theSize = sizeof(void*) + sizeof(UInt32) + (theNumberStreams * sizeof(UInt32));
581  CAAutoFree<AudioHardwareIOProcStreamUsage> theStreamUsage(theSize);
582 
583  // set it up
584  theStreamUsage->mIOProc = reinterpret_cast<void*>(inIOProcID);
585  theStreamUsage->mNumberStreams = theNumberStreams;
586  for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex)
587  {
588  theStreamUsage->mStreamIsOn[theIndex] = (inStreamUsage[theIndex] ? 1 : 0);
589  }
590 
591  // set the property
592  CAPropertyAddress theAddress(kAudioDevicePropertyIOProcStreamUsage, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
593  SetPropertyData(theAddress, 0, NULL, theSize, theStreamUsage);
594 }
595 
596 Float32 CAHALAudioDevice::GetIOCycleUsage() const
597 {
598  Float32 theAnswer = 0;
599  CAPropertyAddress theAddress(kAudioDevicePropertyIOCycleUsage);
600  UInt32 theSize = sizeof(Float32);
601  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
602  return theAnswer;
603 }
604 
605 void CAHALAudioDevice::SetIOCycleUsage(Float32 inValue)
606 {
607  CAPropertyAddress theAddress(kAudioDevicePropertyIOCycleUsage);
608  SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
609 }
610 
611 void CAHALAudioDevice::GetCurrentTime(AudioTimeStamp& outTime)
612 {
613  OSStatus theError = AudioDeviceGetCurrentTime(mObjectID, &outTime);
614  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::GetCurrentTime: got an error getting the current time");
615 }
616 
617 void CAHALAudioDevice::TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime)
618 {
619  OSStatus theError = AudioDeviceTranslateTime(mObjectID, &inTime, &outTime);
620  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::TranslateTime: got an error translating time");
621 }
622 
623 void CAHALAudioDevice::GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware)
624 {
625  UInt32 theFlags = 0;
626  if(inIsInput)
627  {
628  theFlags |= kAudioDeviceStartTimeIsInputFlag;
629  }
630  if(inIgnoreHardware)
631  {
632  theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag;
633  }
634 
635  OSStatus theError = AudioDeviceGetNearestStartTime(mObjectID, &ioTime, theFlags);
636  ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::GetNearestStartTime: got an error getting the start time");
637 }
638 
639 bool CAHALAudioDevice::HasVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
640 {
641  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
642  return HasProperty(theAddress);
643 }
644 
645 bool CAHALAudioDevice::VolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
646 {
647  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
648  return IsPropertySettable(theAddress);
649 }
650 
651 Float32 CAHALAudioDevice::GetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
652 {
653  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
654  Float32 theValue = 0.0f;
655  UInt32 theSize = sizeof(Float32);
656  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
657  return theValue;
658 }
659 
660 Float32 CAHALAudioDevice::GetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
661 {
662  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibels, inScope, inChannel);
663  Float32 theValue = 0.0f;
664  UInt32 theSize = sizeof(Float32);
665  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
666  return theValue;
667 }
668 
669 void CAHALAudioDevice::SetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
670 {
671  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
672  SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
673 }
674 
675 void CAHALAudioDevice::SetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
676 {
677  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibels, inScope, inChannel);
678  SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
679 }
680 
681 Float32 CAHALAudioDevice::GetVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
682 {
683  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibelsToScalar, inScope, inChannel);
684  Float32 theValue = inValue;
685  UInt32 theSize = sizeof(Float32);
686  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
687  return theValue;
688 }
689 
690 Float32 CAHALAudioDevice::GetVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
691 {
692  CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalarToDecibels, inScope, inChannel);
693  Float32 theValue = inValue;
694  UInt32 theSize = sizeof(Float32);
695  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
696  return theValue;
697 }
698 
699 bool CAHALAudioDevice::HasSubVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
700 {
701  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
702  return HasProperty(theAddress);
703 }
704 
705 bool CAHALAudioDevice::SubVolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
706 {
707  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
708  return IsPropertySettable(theAddress);
709 }
710 
711 Float32 CAHALAudioDevice::GetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
712 {
713  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
714  Float32 theValue = 0.0f;
715  UInt32 theSize = sizeof(Float32);
716  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
717  return theValue;
718 }
719 
720 Float32 CAHALAudioDevice::GetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
721 {
722  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibels, inScope, inChannel);
723  Float32 theValue = 0.0f;
724  UInt32 theSize = sizeof(Float32);
725  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
726  return theValue;
727 }
728 
729 void CAHALAudioDevice::SetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
730 {
731  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
732  SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
733 }
734 
735 void CAHALAudioDevice::SetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
736 {
737  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibels, inScope, inChannel);
738  SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
739 }
740 
741 Float32 CAHALAudioDevice::GetSubVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
742 {
743  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibelsToScalar, inScope, inChannel);
744  Float32 theValue = inValue;
745  UInt32 theSize = sizeof(Float32);
746  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
747  return theValue;
748 }
749 
750 Float32 CAHALAudioDevice::GetSubVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
751 {
752  CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalarToDecibels, inScope, inChannel);
753  Float32 theValue = inValue;
754  UInt32 theSize = sizeof(Float32);
755  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
756  return theValue;
757 }
758 
759 bool CAHALAudioDevice::HasMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
760 {
761  CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
762  return HasProperty(theAddress);
763 }
764 
765 bool CAHALAudioDevice::MuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
766 {
767  CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
768  return IsPropertySettable(theAddress);
769 }
770 
771 bool CAHALAudioDevice::GetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
772 {
773  CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
774  UInt32 theValue = 0;
775  UInt32 theSize = sizeof(UInt32);
776  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
777  return theValue != 0;
778 }
779 
780 void CAHALAudioDevice::SetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
781 {
782  CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
783  UInt32 theValue = (inValue ? 1 : 0);
784  UInt32 theSize = sizeof(UInt32);
785  SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
786 }
787 
788 bool CAHALAudioDevice::HasSoloControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
789 {
790  CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
791  return HasProperty(theAddress);
792 }
793 
794 bool CAHALAudioDevice::SoloControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
795 {
796  CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
797  return IsPropertySettable(theAddress);
798 }
799 
800 bool CAHALAudioDevice::GetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
801 {
802  CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
803  UInt32 theValue = 0;
804  UInt32 theSize = sizeof(UInt32);
805  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
806  return theValue != 0;
807 }
808 
809 void CAHALAudioDevice::SetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
810 {
811  CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
812  UInt32 theValue = (inValue ? 1 : 0);
813  UInt32 theSize = sizeof(UInt32);
814  SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
815 }
816 
817 bool CAHALAudioDevice::HasStereoPanControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
818 {
819  CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
820  return HasProperty(theAddress);
821 }
822 
823 bool CAHALAudioDevice::StereoPanControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
824 {
825  CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
826  return IsPropertySettable(theAddress);
827 }
828 
829 Float32 CAHALAudioDevice::GetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
830 {
831  CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
832  Float32 theValue = 0.0f;
833  UInt32 theSize = sizeof(Float32);
834  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
835  return theValue;
836 }
837 
838 void CAHALAudioDevice::SetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
839 {
840  CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
841  UInt32 theSize = sizeof(Float32);
842  SetPropertyData(theAddress, 0, NULL, theSize, &inValue);
843 }
844 
845 void CAHALAudioDevice::GetStereoPanControlChannels(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& outLeftChannel, UInt32& outRightChannel) const
846 {
847  CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
848  UInt32 theValue[2] = { 0, 0 };
849  UInt32 theSize = 2 * sizeof(UInt32);
850  GetPropertyData(theAddress, 0, NULL, theSize, theValue);
851  outLeftChannel = theValue[0];
852  outRightChannel = theValue[1];
853 }
854 
855 bool CAHALAudioDevice::HasJackControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
856 {
857  CAPropertyAddress theAddress(kAudioDevicePropertyJackIsConnected, inScope, inChannel);
858  return HasProperty(theAddress);
859 }
860 
861 bool CAHALAudioDevice::GetJackControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
862 {
863  CAPropertyAddress theAddress(kAudioDevicePropertyJackIsConnected, inScope, inChannel);
864  UInt32 theValue = 0;
865  UInt32 theSize = sizeof(UInt32);
866  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
867  return theValue != 0;
868 }
869 
870 bool CAHALAudioDevice::HasSubMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
871 {
872  CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
873  return HasProperty(theAddress);
874 }
875 
876 bool CAHALAudioDevice::SubMuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
877 {
878  CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
879  return IsPropertySettable(theAddress);
880 }
881 
882 bool CAHALAudioDevice::GetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
883 {
884  CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
885  UInt32 theValue = 0;
886  UInt32 theSize = sizeof(UInt32);
887  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
888  return theValue != 0;
889 }
890 
891 void CAHALAudioDevice::SetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
892 {
893  CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
894  UInt32 theValue = (inValue ? 1 : 0);
895  UInt32 theSize = sizeof(UInt32);
896  SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
897 }
898 
899 bool CAHALAudioDevice::HasiSubOwnerControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
900 {
901  CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
902  return HasProperty(theAddress);
903 }
904 
905 bool CAHALAudioDevice::iSubOwnerControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
906 {
907  CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
908  return IsPropertySettable(theAddress);
909 }
910 
911 bool CAHALAudioDevice::GetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
912 {
913  CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
914  UInt32 theValue = 0;
915  UInt32 theSize = sizeof(UInt32);
916  GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
917  return theValue != 0;
918 }
919 
920 void CAHALAudioDevice::SetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
921 {
922  CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
923  UInt32 theValue = (inValue ? 1 : 0);
924  UInt32 theSize = sizeof(UInt32);
925  SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
926 }
927 
928 bool CAHALAudioDevice::HasDataSourceControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
929 {
930  CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
931  return HasProperty(theAddress);
932 }
933 
934 bool CAHALAudioDevice::DataSourceControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
935 {
936  CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
937  return IsPropertySettable(theAddress);
938 }
939 
940 UInt32 CAHALAudioDevice::GetCurrentDataSourceID(AudioObjectPropertyScope inScope, UInt32 inChannel) const
941 {
942  CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
943  UInt32 theAnswer = 0;
944  UInt32 theSize = sizeof(UInt32);
945  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
946  return theAnswer;
947 }
948 
949 void CAHALAudioDevice::SetCurrentDataSourceByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID)
950 {
951  CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
952  UInt32 theSize = sizeof(UInt32);
953  SetPropertyData(theAddress, 0, NULL, theSize, &inID);
954 }
955 
956 UInt32 CAHALAudioDevice::GetNumberAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel) const
957 {
958  CAPropertyAddress theAddress(kAudioDevicePropertyDataSources, inScope, inChannel);
959  UInt32 theAnswer = 0;
960  if(HasProperty(theAddress))
961  {
962  UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
963  theAnswer = theSize / sizeof(UInt32);
964  }
965  return theAnswer;
966 }
967 
968 void CAHALAudioDevice::GetAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberSources, UInt32* outSources) const
969 {
970  CAPropertyAddress theAddress(kAudioDevicePropertyDataSources, inScope, inChannel);
971  UInt32 theNumberSources = std::min(GetNumberAvailableDataSources(inScope, inChannel), ioNumberSources);
972  UInt32 theSize = theNumberSources * sizeof(UInt32);
973  GetPropertyData(theAddress, 0, NULL, theSize, outSources);
974  ioNumberSources = theSize / sizeof(UInt32);
975 }
976 
977 UInt32 CAHALAudioDevice::GetAvailableDataSourceByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const
978 {
979  AudioStreamID theAnswer = 0;
980  UInt32 theNumberSources = GetNumberAvailableDataSources(inScope, inChannel);
981  if((theNumberSources > 0) && (inIndex < theNumberSources))
982  {
983  CAAutoArrayDelete<UInt32> theSourceList(theNumberSources);
984  GetAvailableDataSources(inScope, inChannel, theNumberSources, theSourceList);
985  theAnswer = theSourceList[inIndex];
986  }
987  return theAnswer;
988 }
989 
990 CFStringRef CAHALAudioDevice::CopyDataSourceNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const
991 {
992  CAPropertyAddress theAddress(kAudioDevicePropertyDataSourceNameForIDCFString, inScope, inChannel);
993  CFStringRef theAnswer = NULL;
994  AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
995  UInt32 theSize = sizeof(AudioValueTranslation);
996  GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
997  return theAnswer;
998 }
999 
1000 bool CAHALAudioDevice::HasDataDestinationControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
1001 {
1002  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
1003  return HasProperty(theAddress);
1004 }
1005 
1006 bool CAHALAudioDevice::DataDestinationControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
1007 {
1008  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
1009  return IsPropertySettable(theAddress);
1010 }
1011 
1012 UInt32 CAHALAudioDevice::GetCurrentDataDestinationID(AudioObjectPropertyScope inScope, UInt32 inChannel) const
1013 {
1014  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
1015  UInt32 theAnswer = 0;
1016  UInt32 theSize = sizeof(UInt32);
1017  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
1018  return theAnswer;
1019 }
1020 
1021 void CAHALAudioDevice::SetCurrentDataDestinationByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID)
1022 {
1023  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
1024  UInt32 theSize = sizeof(UInt32);
1025  SetPropertyData(theAddress, 0, NULL, theSize, &inID);
1026 }
1027 
1028 UInt32 CAHALAudioDevice::GetNumberAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel) const
1029 {
1030  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinations, inScope, inChannel);
1031  UInt32 theAnswer = 0;
1032  if(HasProperty(theAddress))
1033  {
1034  UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
1035  theAnswer = theSize / sizeof(UInt32);
1036  }
1037  return theAnswer;
1038 }
1039 
1040 void CAHALAudioDevice::GetAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberDestinations, UInt32* outDestinations) const
1041 {
1042  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinations, inScope, inChannel);
1043  UInt32 theNumberDestinations = std::min(GetNumberAvailableDataDestinations(inScope, inChannel), ioNumberDestinations);
1044  UInt32 theSize = theNumberDestinations * sizeof(UInt32);
1045  GetPropertyData(theAddress, 0, NULL, theSize, outDestinations);
1046  ioNumberDestinations = theSize / sizeof(UInt32);
1047 }
1048 
1049 UInt32 CAHALAudioDevice::GetAvailableDataDestinationByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const
1050 {
1051  AudioStreamID theAnswer = 0;
1052  UInt32 theNumberDestinations = GetNumberAvailableDataDestinations(inScope, inChannel);
1053  if((theNumberDestinations > 0) && (inIndex < theNumberDestinations))
1054  {
1055  CAAutoArrayDelete<UInt32> theDestinationList(theNumberDestinations);
1056  GetAvailableDataDestinations(inScope, inChannel, theNumberDestinations, theDestinationList);
1057  theAnswer = theDestinationList[inIndex];
1058  }
1059  return theAnswer;
1060 }
1061 
1062 CFStringRef CAHALAudioDevice::CopyDataDestinationNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const
1063 {
1064  CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinationNameForIDCFString, inScope, inChannel);
1065  CFStringRef theAnswer = NULL;
1066  AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
1067  UInt32 theSize = sizeof(AudioValueTranslation);
1068  GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
1069  return theAnswer;
1070 }
1071 
1072 bool CAHALAudioDevice::HasClockSourceControl() const
1073 {
1074  CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
1075  return HasProperty(theAddress);
1076 }
1077 
1078 bool CAHALAudioDevice::ClockSourceControlIsSettable() const
1079 {
1080  CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
1081  return IsPropertySettable(theAddress);
1082 }
1083 
1084 UInt32 CAHALAudioDevice::GetCurrentClockSourceID() const
1085 {
1086  CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
1087  UInt32 theAnswer = 0;
1088  UInt32 theSize = sizeof(UInt32);
1089  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
1090  return theAnswer;
1091 }
1092 
1093 void CAHALAudioDevice::SetCurrentClockSourceByID(UInt32 inID)
1094 {
1095  CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
1096  UInt32 theSize = sizeof(UInt32);
1097  SetPropertyData(theAddress, 0, NULL, theSize, &inID);
1098 }
1099 
1100 UInt32 CAHALAudioDevice::GetNumberAvailableClockSources() const
1101 {
1102  CAPropertyAddress theAddress(kAudioDevicePropertyClockSources);
1103  UInt32 theAnswer = 0;
1104  if(HasProperty(theAddress))
1105  {
1106  UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
1107  theAnswer = theSize / sizeof(UInt32);
1108  }
1109  return theAnswer;
1110 }
1111 
1112 void CAHALAudioDevice::GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const
1113 {
1114  CAPropertyAddress theAddress(kAudioDevicePropertyClockSources);
1115  UInt32 theNumberSources = std::min(GetNumberAvailableClockSources(), ioNumberSources);
1116  UInt32 theSize = theNumberSources * sizeof(UInt32);
1117  GetPropertyData(theAddress, 0, NULL, theSize, outSources);
1118  ioNumberSources = theSize / sizeof(UInt32);
1119 }
1120 
1121 UInt32 CAHALAudioDevice::GetAvailableClockSourceByIndex(UInt32 inIndex) const
1122 {
1123  AudioStreamID theAnswer = 0;
1124  UInt32 theNumberSources = GetNumberAvailableClockSources();
1125  if((theNumberSources > 0) && (inIndex < theNumberSources))
1126  {
1127  CAAutoArrayDelete<UInt32> theSourceList(theNumberSources);
1128  GetAvailableClockSources(theNumberSources, theSourceList);
1129  theAnswer = theSourceList[inIndex];
1130  }
1131  return theAnswer;
1132 }
1133 
1134 CFStringRef CAHALAudioDevice::CopyClockSourceNameForID(UInt32 inID) const
1135 {
1136  CAPropertyAddress theAddress(kAudioDevicePropertyClockSourceNameForIDCFString);
1137  CFStringRef theAnswer = NULL;
1138  AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
1139  UInt32 theSize = sizeof(AudioValueTranslation);
1140  GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
1141  return theAnswer;
1142 }
1143 
1144 UInt32 CAHALAudioDevice::GetClockSourceKindForID(UInt32 inID) const
1145 {
1146  CAPropertyAddress theAddress(kAudioDevicePropertyClockSourceKindForID);
1147  UInt32 theAnswer = inID;
1148  UInt32 theSize = sizeof(UInt32);
1149  GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
1150  return theAnswer;
1151 }