Make sure MSVC knows which version of 'floor()' we want
[ardour.git] / libs / appleutility / CoreAudio / PublicUtility / CAHALAudioObject.cpp
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
64 CAHALAudioObject::CAHALAudioObject(AudioObjectID inObjectID)
65 :
66         mObjectID(inObjectID)
67 {
68 }
69
70 CAHALAudioObject::~CAHALAudioObject()
71 {
72 }
73
74 AudioObjectID   CAHALAudioObject::GetObjectID() const
75 {
76         return mObjectID;
77 }
78
79 void    CAHALAudioObject::SetObjectID(AudioObjectID inObjectID)
80 {
81         mObjectID = inObjectID;
82 }
83
84 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
102 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
121 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
140 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
159 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
178 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
197 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
216 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
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
242 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
268 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
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
327 bool    CAHALAudioObject::HasProperty(const AudioObjectPropertyAddress& inAddress) const
328 {
329         return AudioObjectHasProperty(mObjectID, &inAddress);
330 }
331
332 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
340 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
348 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
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
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
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 }