1 /*
2 File: CAHALAudioObject.cpp
3 Abstract: CAHALAudioObject.h
4 Version: 1.1
5
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
7 Inc. ("Apple") in consideration of your agreement to the following
8 terms, and your use, installation, modification or redistribution of
9 this Apple software constitutes acceptance of these terms. If you do
10 not agree with these terms, please do not use, install, modify or
11 redistribute this Apple software.
12
13 In consideration of your agreement to abide by the following terms, and
14 subject to these terms, Apple grants you a personal, non-exclusive
15 license, under Apple's copyrights in this original Apple software (the
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple
17 Software, with or without modifications, in source and/or binary forms;
18 provided that if you redistribute the Apple Software in its entirety and
19 without modifications, you must retain this notice and the following
20 text and disclaimers in all such redistributions of the Apple Software.
21 Neither the name, trademarks, service marks or logos of Apple Inc. may
22 be used to endorse or promote products derived from the Apple Software
23 without specific prior written permission from Apple. Except as
24 expressly stated in this notice, no other rights or licenses, express or
25 implied, are granted by Apple herein, including but not limited to any
26 patent rights that may be infringed by your derivative works or by other
27 works in which the Apple Software may be incorporated.
28
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42 POSSIBILITY OF SUCH DAMAGE.
43
44 Copyright (C) 2014 Apple Inc. All Rights Reserved.
45
46 */
47 //==================================================================================================
48 // Includes
49 //==================================================================================================
50
51 // Self Include
52 #include "CAHALAudioObject.h"
53
54 // PublicUtility Includes
55 #include "CAAutoDisposer.h"
56 #include "CADebugMacros.h"
57 #include "CAException.h"
58 #include "CAPropertyAddress.h"
59
60 //==================================================================================================
61 // CAHALAudioObject
62 //==================================================================================================
63
CAHALAudioObject(AudioObjectID inObjectID)64 CAHALAudioObject::CAHALAudioObject(AudioObjectID inObjectID)
65 :
66 mObjectID(inObjectID)
67 {
68 }
69
~CAHALAudioObject()70 CAHALAudioObject::~CAHALAudioObject()
71 {
72 }
73
GetObjectID() const74 AudioObjectID CAHALAudioObject::GetObjectID() const
75 {
76 return mObjectID;
77 }
78
SetObjectID(AudioObjectID inObjectID)79 void CAHALAudioObject::SetObjectID(AudioObjectID inObjectID)
80 {
81 mObjectID = inObjectID;
82 }
83
GetClassID() const84 AudioClassID CAHALAudioObject::GetClassID() const
85 {
86 // set up the return value
87 AudioClassID theAnswer = 0;
88
89 // set up the property address
90 CAPropertyAddress theAddress(kAudioObjectPropertyClass);
91
92 // make sure the property exists
93 if(HasProperty(theAddress))
94 {
95 UInt32 theSize = sizeof(AudioClassID);
96 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
97 }
98
99 return theAnswer;
100 }
101
GetOwnerObjectID() const102 AudioObjectID CAHALAudioObject::GetOwnerObjectID() const
103 {
104 // set up the return value
105 AudioObjectID theAnswer = 0;
106
107 // set up the property address
108 CAPropertyAddress theAddress(kAudioObjectPropertyOwner);
109
110 // make sure the property exists
111 if(HasProperty(theAddress))
112 {
113 // get the property data
114 UInt32 theSize = sizeof(AudioObjectID);
115 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
116 }
117
118 return theAnswer;
119 }
120
CopyOwningPlugInBundleID() const121 CFStringRef CAHALAudioObject::CopyOwningPlugInBundleID() const
122 {
123 // set up the return value
124 CFStringRef theAnswer = NULL;
125
126 // set up the property address
127 CAPropertyAddress theAddress(kAudioObjectPropertyCreator);
128
129 // make sure the property exists
130 if(HasProperty(theAddress))
131 {
132 // get the property data
133 UInt32 theSize = sizeof(CFStringRef);
134 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
135 }
136
137 return theAnswer;
138 }
139
CopyName() const140 CFStringRef CAHALAudioObject::CopyName() const
141 {
142 // set up the return value
143 CFStringRef theAnswer = NULL;
144
145 // set up the property address
146 CAPropertyAddress theAddress(kAudioObjectPropertyName);
147
148 // make sure the property exists
149 if(HasProperty(theAddress))
150 {
151 // get the property data
152 UInt32 theSize = sizeof(CFStringRef);
153 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
154 }
155
156 return theAnswer;
157 }
158
CopyManufacturer() const159 CFStringRef CAHALAudioObject::CopyManufacturer() const
160 {
161 // set up the return value
162 CFStringRef theAnswer = NULL;
163
164 // set up the property address
165 CAPropertyAddress theAddress(kAudioObjectPropertyManufacturer);
166
167 // make sure the property exists
168 if(HasProperty(theAddress))
169 {
170 // get the property data
171 UInt32 theSize = sizeof(CFStringRef);
172 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
173 }
174
175 return theAnswer;
176 }
177
CopyNameForElement(AudioObjectPropertyScope inScope,AudioObjectPropertyElement inElement) const178 CFStringRef CAHALAudioObject::CopyNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
179 {
180 // set up the return value
181 CFStringRef theAnswer = NULL;
182
183 // set up the property address
184 CAPropertyAddress theAddress(kAudioObjectPropertyElementName, inScope, inElement);
185
186 // make sure the property exists
187 if(HasProperty(theAddress))
188 {
189 // get the property data
190 UInt32 theSize = sizeof(CFStringRef);
191 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
192 }
193
194 return theAnswer;
195 }
196
CopyCategoryNameForElement(AudioObjectPropertyScope inScope,AudioObjectPropertyElement inElement) const197 CFStringRef CAHALAudioObject::CopyCategoryNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
198 {
199 // set up the return value
200 CFStringRef theAnswer = NULL;
201
202 // set up the property address
203 CAPropertyAddress theAddress(kAudioObjectPropertyElementCategoryName, inScope, inElement);
204
205 // make sure the property exists
206 if(HasProperty(theAddress))
207 {
208 // get the property data
209 UInt32 theSize = sizeof(CFStringRef);
210 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
211 }
212
213 return theAnswer;
214 }
215
CopyNumberNameForElement(AudioObjectPropertyScope inScope,AudioObjectPropertyElement inElement) const216 CFStringRef CAHALAudioObject::CopyNumberNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
217 {
218 // set up the return value
219 CFStringRef theAnswer = NULL;
220
221 // set up the property address
222 CAPropertyAddress theAddress(kAudioObjectPropertyElementNumberName, inScope, inElement);
223
224 // make sure the property exists
225 if(HasProperty(theAddress))
226 {
227 // get the property data
228 UInt32 theSize = sizeof(CFStringRef);
229 GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
230 }
231
232 return theAnswer;
233 }
234
ObjectExists(AudioObjectID inObjectID)235 bool CAHALAudioObject::ObjectExists(AudioObjectID inObjectID)
236 {
237 Boolean isSettable;
238 CAPropertyAddress theAddress(kAudioObjectPropertyClass);
239 return (inObjectID == 0) || (AudioObjectIsPropertySettable(inObjectID, &theAddress, &isSettable) != 0);
240 }
241
GetNumberOwnedObjects(AudioClassID inClass) const242 UInt32 CAHALAudioObject::GetNumberOwnedObjects(AudioClassID inClass) const
243 {
244 // set up the return value
245 UInt32 theAnswer = 0;
246
247 // set up the property address
248 CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
249
250 // figure out the qualifier
251 UInt32 theQualifierSize = 0;
252 void* theQualifierData = NULL;
253 if(inClass != 0)
254 {
255 theQualifierSize = sizeof(AudioObjectID);
256 theQualifierData = &inClass;
257 }
258
259 // get the property data size
260 theAnswer = GetPropertyDataSize(theAddress, theQualifierSize, theQualifierData);
261
262 // calculate the number of object IDs
263 theAnswer /= SizeOf32(AudioObjectID);
264
265 return theAnswer;
266 }
267
GetAllOwnedObjects(AudioClassID inClass,UInt32 & ioNumberObjects,AudioObjectID * ioObjectIDs) const268 void CAHALAudioObject::GetAllOwnedObjects(AudioClassID inClass, UInt32& ioNumberObjects, AudioObjectID* ioObjectIDs) const
269 {
270 // set up the property address
271 CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
272
273 // figure out the qualifier
274 UInt32 theQualifierSize = 0;
275 void* theQualifierData = NULL;
276 if(inClass != 0)
277 {
278 theQualifierSize = sizeof(AudioObjectID);
279 theQualifierData = &inClass;
280 }
281
282 // get the property data
283 UInt32 theDataSize = ioNumberObjects * SizeOf32(AudioClassID);
284 GetPropertyData(theAddress, theQualifierSize, theQualifierData, theDataSize, ioObjectIDs);
285
286 // set the number of object IDs being returned
287 ioNumberObjects = theDataSize / SizeOf32(AudioObjectID);
288 }
289
GetOwnedObjectByIndex(AudioClassID inClass,UInt32 inIndex)290 AudioObjectID CAHALAudioObject::GetOwnedObjectByIndex(AudioClassID inClass, UInt32 inIndex)
291 {
292 // set up the property address
293 CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
294
295 // figure out the qualifier
296 UInt32 theQualifierSize = 0;
297 void* theQualifierData = NULL;
298 if(inClass != 0)
299 {
300 theQualifierSize = sizeof(AudioObjectID);
301 theQualifierData = &inClass;
302 }
303
304 // figure out how much space to allocate
305 UInt32 theDataSize = GetPropertyDataSize(theAddress, theQualifierSize, theQualifierData);
306 UInt32 theNumberObjectIDs = theDataSize / SizeOf32(AudioObjectID);
307
308 // set up the return value
309 AudioObjectID theAnswer = 0;
310
311 // maker sure the index is in range
312 if(inIndex < theNumberObjectIDs)
313 {
314 // allocate it
315 CAAutoArrayDelete<AudioObjectID> theObjectList(theDataSize / sizeof(AudioObjectID));
316
317 // get the property data
318 GetPropertyData(theAddress, theQualifierSize, theQualifierData, theDataSize, theObjectList);
319
320 // get the return value
321 theAnswer = theObjectList[inIndex];
322 }
323
324 return theAnswer;
325 }
326
HasProperty(const AudioObjectPropertyAddress & inAddress) const327 bool CAHALAudioObject::HasProperty(const AudioObjectPropertyAddress& inAddress) const
328 {
329 return AudioObjectHasProperty(mObjectID, &inAddress);
330 }
331
IsPropertySettable(const AudioObjectPropertyAddress & inAddress) const332 bool CAHALAudioObject::IsPropertySettable(const AudioObjectPropertyAddress& inAddress) const
333 {
334 Boolean isSettable = false;
335 OSStatus theError = AudioObjectIsPropertySettable(mObjectID, &inAddress, &isSettable);
336 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::IsPropertySettable: got an error getting info about a property");
337 return isSettable != 0;
338 }
339
GetPropertyDataSize(const AudioObjectPropertyAddress & inAddress,UInt32 inQualifierDataSize,const void * inQualifierData) const340 UInt32 CAHALAudioObject::GetPropertyDataSize(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData) const
341 {
342 UInt32 theDataSize = 0;
343 OSStatus theError = AudioObjectGetPropertyDataSize(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, &theDataSize);
344 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::GetPropertyDataSize: got an error getting the property data size");
345 return theDataSize;
346 }
347
GetPropertyData(const AudioObjectPropertyAddress & inAddress,UInt32 inQualifierDataSize,const void * inQualifierData,UInt32 & ioDataSize,void * outData) const348 void CAHALAudioObject::GetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32& ioDataSize, void* outData) const
349 {
350 OSStatus theError = AudioObjectGetPropertyData(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, &ioDataSize, outData);
351 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::GetPropertyData: got an error getting the property data");
352 }
353
SetPropertyData(const AudioObjectPropertyAddress & inAddress,UInt32 inQualifierDataSize,const void * inQualifierData,UInt32 inDataSize,const void * inData)354 void CAHALAudioObject::SetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData)
355 {
356 OSStatus theError = AudioObjectSetPropertyData(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, inDataSize, inData);
357 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::SetPropertyData: got an error setting the property data");
358 }
359
AddPropertyListener(const AudioObjectPropertyAddress & inAddress,AudioObjectPropertyListenerProc inListenerProc,void * inClientData)360 void CAHALAudioObject::AddPropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData)
361 {
362 OSStatus theError = AudioObjectAddPropertyListener(mObjectID, &inAddress, inListenerProc, inClientData);
363 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::AddPropertyListener: got an error adding a property listener");
364 }
365
RemovePropertyListener(const AudioObjectPropertyAddress & inAddress,AudioObjectPropertyListenerProc inListenerProc,void * inClientData)366 void CAHALAudioObject::RemovePropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData)
367 {
368 OSStatus theError = AudioObjectRemovePropertyListener(mObjectID, &inAddress, inListenerProc, inClientData);
369 ThrowIfError(theError, CAException(theError), "CAHALAudioObject::RemovePropertyListener: got an error removing a property listener");
370 }
371