summaryrefslogtreecommitdiff
path: root/libs/appleutility/CoreAudio/PublicUtility
diff options
context:
space:
mode:
Diffstat (limited to 'libs/appleutility/CoreAudio/PublicUtility')
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.cpp169
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.h118
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.cpp139
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.h112
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.cpp227
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.h541
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.cpp233
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.h102
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.cpp400
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.h191
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.cpp707
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.h293
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAtomic.h305
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAtomicStack.h239
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.cpp239
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.h108
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp153
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.h199
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayoutObject.cpp210
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.cpp424
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.h149
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.cpp135
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.h97
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.cpp1421
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.h439
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioUnitOutputCapturer.h143
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.cpp262
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.h121
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h508
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABitOperations.h206
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABool.h89
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABufferList.cpp259
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABufferList.h324
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.cpp84
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.h69
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAByteOrder.h161
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFArray.cpp821
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFArray.h195
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFData.h108
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.cpp581
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.h176
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.cpp107
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.h73
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.cpp168
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.h95
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.cpp163
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.h119
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFNumber.cpp83
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFNumber.h151
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFObject.h138
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFPlugIn.h101
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.cpp287
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.h92
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFString.cpp110
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CACFString.h196
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAComponent.cpp182
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAComponent.h121
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.cpp110
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.h145
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.cpp90
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.h581
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.cpp89
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.h115
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugger.cpp103
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CADebugger.h69
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAException.h83
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAExtAudioFile.h300
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.cpp188
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.h70
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAGuard.cpp343
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAGuard.h133
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.cpp1156
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.h238
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.cpp370
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.h155
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.cpp182
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.h94
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.cpp181
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.h90
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.cpp99
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.h234
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CALogMacros.h140
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAMath.h68
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAMixMap.h157
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAMutex.cpp345
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAMutex.h163
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAPThread.cpp450
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAPThread.h191
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAPersistence.cpp468
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAProcess.cpp92
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAProcess.h75
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAPropertyAddress.h312
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAReferenceCounted.h97
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.cpp319
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.h126
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.cpp737
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.h128
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.cpp118
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.h64
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.cpp376
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.h146
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp879
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.h424
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.cpp183
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.h140
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAThreadSafeList.h233
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CATink.h146
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CATokenMap.h212
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.cpp195
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.h101
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAVectorUnitTypes.h60
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.cpp482
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.h178
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAXException.cpp49
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/CAXException.h361
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.cpp149
-rw-r--r--libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.h71
117 files changed, 27296 insertions, 0 deletions
diff --git a/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.cpp b/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.cpp
new file mode 100644
index 0000000000..c2c8468bd9
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.cpp
@@ -0,0 +1,169 @@
+/*
+ File: AUOutputBL.cpp
+ Abstract: AUOutputBL.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "AUOutputBL.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioUnit/AUComponent.h>
+#else
+ #include <AUComponent.h>
+#endif
+/*
+struct AudioBufferList
+{
+ UInt32 mNumberBuffers;
+ AudioBuffer mBuffers[1];
+};
+struct AudioBuffer
+{
+ UInt32 mNumberChannels; // number of interleaved channels in the buffer
+ UInt32 mDataByteSize; // the size of the buffer pointed to by mData
+ void* mData; // the pointer to the buffer
+};
+*/
+
+AUOutputBL::AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames)
+ : mFormat (inDesc),
+ mBufferMemory(NULL),
+ mBufferList (NULL),
+ mNumberBuffers (0), // keep this here, so can ensure integrity of ABL
+ mBufferSize (0),
+ mFrames(inDefaultNumFrames)
+{
+ mNumberBuffers = mFormat.IsInterleaved() ? 1 : mFormat.NumberChannels();
+ mBufferList = reinterpret_cast<AudioBufferList*>(new Byte[offsetof(AudioBufferList, mBuffers) + (mNumberBuffers * sizeof(AudioBuffer))]);
+}
+
+AUOutputBL::~AUOutputBL()
+{
+ if (mBufferMemory)
+ delete[] mBufferMemory;
+
+ if (mBufferList)
+ delete [] (Byte *)mBufferList;
+}
+
+void AUOutputBL::Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated)
+{
+ UInt32 channelsPerBuffer = mFormat.IsInterleaved() ? mFormat.NumberChannels() : 1;
+
+ if (mBufferMemory == NULL || inWantNullBufferIfAllocated)
+ {
+ mBufferList->mNumberBuffers = mNumberBuffers;
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
+ buf->mNumberChannels = channelsPerBuffer;
+ buf->mDataByteSize = mFormat.FramesToBytes (inNumFrames);
+ buf->mData = NULL;
+ }
+ }
+ else
+ {
+ UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
+ if ((nBytes * mNumberBuffers) > AllocatedBytes())
+ throw OSStatus(kAudioUnitErr_TooManyFramesToProcess);
+
+ mBufferList->mNumberBuffers = mNumberBuffers;
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ Byte* p = mBufferMemory;
+ for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
+ buf->mNumberChannels = channelsPerBuffer;
+ buf->mDataByteSize = nBytes;
+ buf->mData = p;
+ p += mBufferSize;
+ }
+ }
+}
+
+
+void AUOutputBL::Allocate (UInt32 inNumFrames)
+{
+ if (inNumFrames)
+ {
+ UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
+
+ if (nBytes <= AllocatedBytes())
+ return;
+
+ // align successive buffers for Altivec and to take alternating
+ // cache line hits by spacing them by odd multiples of 16
+ if (mNumberBuffers > 1)
+ nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
+
+ mBufferSize = nBytes;
+
+ UInt32 memorySize = mBufferSize * mNumberBuffers;
+ Byte *newMemory = new Byte[memorySize];
+ memset(newMemory, 0, memorySize); // make buffer "hot"
+
+ Byte *oldMemory = mBufferMemory;
+ mBufferMemory = newMemory;
+ delete[] oldMemory;
+
+ mFrames = inNumFrames;
+ }
+ else
+ {
+ if (mBufferMemory) {
+ delete [] mBufferMemory;
+ mBufferMemory = NULL;
+ }
+ mBufferSize = 0;
+ mFrames = 0;
+ }
+}
+
+#if DEBUG
+void AUOutputBL::Print()
+{
+ printf ("AUOutputBL::Print\n");
+ mFormat.Print();
+ printf ("Num Buffers:%d, mFrames:%d, allocatedMemory:%c\n", (int)mBufferList->mNumberBuffers, (int)mFrames, (mBufferMemory != NULL ? 'T' : 'F'));
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ for (UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i, ++buf)
+ printf ("\tBuffer:%d, Size:%d, Chans:%d, Buffer:%p\n", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
+}
+#endif
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.h b/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.h
new file mode 100644
index 0000000000..0baad3a579
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/AUOutputBL.h
@@ -0,0 +1,118 @@
+/*
+ File: AUOutputBL.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __AUOutputBL_h__
+#define __AUOutputBL_h__
+
+#include "CAStreamBasicDescription.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+#else
+#endif
+
+// ____________________________________________________________________________
+//
+// AUOutputBL - Simple Buffer List wrapper targetted to use with retrieving AU output
+// Works in one of two ways (both adjustable)... Can use it with NULL pointers, or allocate
+// memory to receive the data in.
+
+// Before using this with any call to AudioUnitRender, it needs to be Prepared
+// as some calls to AudioUnitRender can reset the ABL
+
+class AUOutputBL {
+public:
+
+ // you CANNOT use one of these - it will crash!
+// AUOutputBL ();
+
+ // this is the constructor that you use
+ // it can't be reset once you've constructed it
+ AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames = 512);
+ ~AUOutputBL();
+
+ void Prepare ()
+ {
+ Prepare (mFrames);
+ }
+
+ // this version can throw if this is an allocted ABL and inNumFrames is > AllocatedFrames()
+ // you can set the bool to true if you want a NULL buffer list even if allocated
+ // inNumFrames must be a valid number (will throw if inNumFrames is 0)
+ void Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated = false);
+
+ AudioBufferList* ABL() { return mBufferList; }
+
+ // You only need to call this if you want to allocate a buffer list
+ // if you want an empty buffer list, just call Prepare()
+ // if you want to dispose previously allocted memory, pass in 0
+ // then you either have an empty buffer list, or you can re-allocate
+ // Memory is kept around if an Allocation request is less than what is currently allocated
+ void Allocate (UInt32 inNumberFrames);
+
+ UInt32 AllocatedFrames() const { return mFrames; }
+
+ const CAStreamBasicDescription& GetFormat() const { return mFormat; }
+
+#if DEBUG
+ void Print();
+#endif
+
+private:
+ UInt32 AllocatedBytes () const { return (mBufferSize * mNumberBuffers); }
+
+ CAStreamBasicDescription mFormat;
+ Byte* mBufferMemory;
+ AudioBufferList* mBufferList;
+ UInt32 mNumberBuffers;
+ UInt32 mBufferSize;
+ UInt32 mFrames;
+
+// don't want to copy these.. can if you want, but more code to write!
+ AUOutputBL () {}
+ AUOutputBL (const AUOutputBL &c);
+ AUOutputBL& operator= (const AUOutputBL& c);
+};
+
+#endif // __AUOutputBL_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.cpp b/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.cpp
new file mode 100644
index 0000000000..87d7848790
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.cpp
@@ -0,0 +1,139 @@
+/*
+ File: AUParamInfo.cpp
+ Abstract: AUParamInfo.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "AUParamInfo.h"
+#include "CAXException.h"
+
+AUParamInfo::AUParamInfo (AudioUnit inAU,
+ bool inIncludeExpert,
+ bool inIncludeReadOnly,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement)
+ : mAU (inAU),
+ mNumParams (0),
+ mParamListID(NULL),
+ mScope (inScope),
+ mElement (inElement)
+{
+ UInt32 size;
+ OSStatus result = AudioUnitGetPropertyInfo(mAU, kAudioUnitProperty_ParameterList, inScope, mElement, &size, NULL);
+ if (size == 0 || result) return;
+
+ int nparams = size / sizeof(AudioUnitPropertyID);
+ mParamListID = new AudioUnitParameterID[nparams];
+
+ memset (mParamListID, 0xFF, size);
+
+ AudioUnitParameterID *paramList = new AudioUnitParameterID[nparams];
+
+ result = AudioUnitGetProperty(mAU, kAudioUnitProperty_ParameterList, mScope, mElement, paramList, &size);
+ if (result) {
+ delete [] mParamListID;
+ delete [] paramList;
+ mParamListID = NULL;
+ return;
+ }
+
+ ParameterMap params;
+ for (int i = 0; i < nparams; ++i)
+ {
+ CAAUParameter auvp (mAU, paramList[i], mScope, mElement); // took out only using global scope in CAAUParameter creation
+ const AudioUnitParameterInfo &paramInfo = auvp.ParamInfo();
+
+ // don't include if parameter can't be read or written
+ if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable)
+ && !(paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
+ continue;
+
+ // only include if expert params wanted
+ if (!inIncludeExpert && auvp.IsExpert())
+ continue;
+
+ // only include if read only params are wanted
+ if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable)
+ && (paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
+ {
+ if (!inIncludeReadOnly)
+ continue;
+ }
+
+ mParamListID[mNumParams] = paramList[i];
+ mNumParams++;
+
+ // ok - if we're here, then we have a parameter we are going to display.
+ UInt32 clump = 0;
+ auvp.GetClumpID (clump);
+ mParams[clump].push_back (auvp);
+ }
+
+ delete [] paramList;
+}
+
+AUParamInfo::~AUParamInfo()
+{
+ delete [] mParamListID;
+}
+
+UInt32 AUParamInfo::NumParamsForClump (UInt32 inClump) const
+{
+ ParameterMap::const_iterator it = mParams.find(inClump);
+ if (it != mParams.end())
+ return static_cast<UInt32>((*it).second.size());
+ return 0;
+}
+
+const CAAUParameter* AUParamInfo::GetParamInfo (AudioUnitParameterID inParamID) const
+{
+ for (ParameterMap::const_iterator it = mParams.begin(); it != mParams.end(); ++it) {
+ const ParameterList &list = (*it).second;
+ for (ParameterList::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
+ if (inParamID == (*iter).mParameterID) {
+ return &(*iter);
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.h b/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.h
new file mode 100644
index 0000000000..d15fbfeb2d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/AUParamInfo.h
@@ -0,0 +1,112 @@
+/*
+ File: AUParamInfo.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include <map>
+#include <vector>
+#include <AudioUnit/AudioUnit.h>
+#include "CAAUParameter.h"
+
+/*
+ The ParameterMap returned by the Map() method is a map where
+ - the key is the clumpID
+ - the value is a ParameterList (vector<CAAUParameter>)
+
+ If you have parameters on multiple scopes (or elements within a scope), then you should create one of these
+ for each scope-element pair
+*/
+
+class AUParamInfo {
+
+public:
+ typedef std::vector <CAAUParameter> ParameterList;
+ typedef std::map <UInt32, ParameterList, std::less<UInt32> > ParameterMap;
+
+
+
+ AUParamInfo (AudioUnit inAU,
+ bool inIncludeExpert,
+ bool inIncludeReadOnly,
+ AudioUnitScope inScope = kAudioUnitScope_Global,
+ AudioUnitElement inElement = 0);
+
+ ~AUParamInfo();
+
+ const ParameterMap& Map () const { return mParams; }
+
+ // some convenience methods
+ UInt32 NumParams () const { return mNumParams; }
+
+ AudioUnitParameterID ParamID (UInt32 inIndex) const
+ {
+ if (inIndex < mNumParams) return mParamListID[inIndex];
+ return 0xFFFFFFFF;
+ }
+
+ UInt32 NumClumps () const { return static_cast<UInt32>(mParams.size()); }
+
+ UInt32 NumParamsForClump (UInt32 inClump) const;
+
+ // returns NULL if there's no info for the parameter
+ const CAAUParameter* GetParamInfo (AudioUnitParameterID inParamID) const;
+
+ AudioUnitScope GetScope () const { return mScope; }
+ AudioUnitElement GetElement () const { return mElement; }
+
+private:
+
+ AudioUnit mAU;
+ UInt32 mNumParams;
+ AudioUnitParameterID * mParamListID;
+
+ ParameterMap mParams;
+ AudioUnitScope mScope;
+ AudioUnitElement mElement;
+
+ // disallow
+ AUParamInfo () {}
+ AUParamInfo (const AUParamInfo &c) {}
+ AUParamInfo& operator= (const AUParamInfo& c) { return *this; }
+};
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.cpp
new file mode 100644
index 0000000000..4e72b22858
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.cpp
@@ -0,0 +1,227 @@
+/*
+ File: CAAUMIDIMap.cpp
+ Abstract: CAAUMIDIMap.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAUMIDIMap.h"
+#include <pthread.h>
+
+struct AllMidiTransformers
+{
+ MIDILinearTransformer linearTrans;
+ MIDILogTransformer logTrans;
+ MIDIExpTransformer expTrans;
+ MIDISqrtTransformer sqrtTrans;
+ MIDISquareTransformer squareTrans;
+ MIDICubeRtTransformer cubeRtTrans;
+ MIDICubeTransformer cubeTrans;
+};
+
+AllMidiTransformers* gAllMidiTransformers = NULL;
+
+#if TARGET_OS_MAC
+static pthread_once_t sOnce = PTHREAD_ONCE_INIT;
+
+static void InitAllMidiTransformers()
+{
+ gAllMidiTransformers = new AllMidiTransformers();
+}
+
+static void CheckInitAllMidiTransformers()
+{
+ pthread_once(&sOnce, InitAllMidiTransformers);
+}
+#endif
+
+MIDIValueTransformer * CAAUMIDIMap::GetTransformer (UInt32 inFlags)
+{
+#if TARGET_OS_MAC
+ if (gAllMidiTransformers == NULL)
+ CheckInitAllMidiTransformers();
+#else
+ if (gAllMidiTransformers == NULL)
+ gAllMidiTransformers = new AllMidiTransformers();
+#endif
+
+ if (AudioUnitDisplayTypeIsLogarithmic(inFlags))
+ return &gAllMidiTransformers->logTrans;
+ else if (AudioUnitDisplayTypeIsExponential(inFlags))
+ return &gAllMidiTransformers->expTrans;
+ else if (AudioUnitDisplayTypeIsSquareRoot(inFlags))
+ return &gAllMidiTransformers->sqrtTrans;
+ else if (AudioUnitDisplayTypeIsSquared(inFlags))
+ return &gAllMidiTransformers->squareTrans;
+ else if (AudioUnitDisplayTypeIsCubed(inFlags))
+ return &gAllMidiTransformers->cubeTrans;
+ else if (AudioUnitDisplayTypeIsCubeRoot(inFlags))
+ return &gAllMidiTransformers->cubeRtTrans;
+ else
+ return &gAllMidiTransformers->linearTrans;
+}
+
+// The CALLER of this method must ensure that the status byte's MIDI Command matches!!!
+bool CAAUMIDIMap::MIDI_Matches (UInt8 inChannel, UInt8 inData1, UInt8 inData2, Float32 &outLinear) const
+{
+ // see if the channels match first
+ SInt8 chan = Channel();
+ // channel matches (if chan is less than zero, "Any Channel" flag is set)
+ if (chan >= 0 && chan != inChannel)
+ return false;
+
+ // match the special cases first
+ if (IsKeyEvent()) {
+ // we're using this key event as an on/off type switch
+ if (IsBipolar()) {
+ if (IsKeyPressure()){
+ if (IsBipolar_OnValue()) {
+ if (inData2 > 63) {
+ outLinear = 1;
+ return true;
+ }
+ } else {
+ if (inData2 < 64) {
+ outLinear = 0;
+ return true;
+ }
+ }
+ return false;
+ }
+ else {
+ if (IsBipolar_OnValue()) {
+ if (inData1 > 63) {
+ outLinear = 1;
+ return true;
+ }
+ } else {
+ if (inData1 < 64) {
+ outLinear = 0;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ if (IsAnyNote()) {
+// not quite sure how to interpret this...
+ if (IsKeyPressure())
+ outLinear = inData2 / 127.0;
+ else
+ outLinear = inData1 / 127.0;
+ return true;
+ }
+ if (mData1 == inData1) {
+ if (IsKeyPressure())
+ outLinear = inData2 / 127.0;
+ else
+ outLinear = 1;
+ return true;
+ }
+ return false;
+ }
+ else if (IsControlChange()) {
+ // controller ID matches
+ if (mData1 == inData1) {
+ if (IsBipolar()) {
+ if (IsBipolar_OnValue()) {
+ if (inData2 > 63) {
+ outLinear = 1;
+ return true;
+ }
+ } else {
+ if (inData2 < 64) {
+ outLinear = 0;
+ return true;
+ }
+ }
+ return false;
+ }
+ //printf("this in midi matches %X with ", this);
+ outLinear = inData2 / 127.;
+ return true;
+ }
+ return false;
+ }
+
+ // this just matches on the patch change value itself...
+ if (IsPatchChange()) {
+ if (mData1 == inData1) {
+ outLinear = 1;
+ return true;
+ }
+ return false;
+ }
+
+ // finally, for the other two, just check the bi-polar matching conditions
+ // pitch bend and after touch
+ if (IsBipolar()) {
+ if (IsBipolar_OnValue()) {
+ if (inData1 > 63) {
+ outLinear = 1;
+ return true;
+ }
+ } else {
+ if (inData1 < 64) {
+ outLinear = 0;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ if (IsPitchBend()) {
+ UInt16 value = (inData2 << 7) | inData1;
+ outLinear = value / 16383.;
+ }
+ else if (IsChannelPressure()) {
+ outLinear = inData1 / 127.0;
+ }
+
+ return true;
+}
+
+
+void CAAUMIDIMap::Print () const
+{
+ printf ("CAAUMIDIMap:%p, (%u/%u), mParamID %d, IsValid:%c, Status:0x%X, mData1 %d, Flags:0x%X\n", this, (unsigned int)mScope, (unsigned int)mElement, (int)mParameterID, (IsValid() ? 'T' : 'F'), mStatus, mData1, (int)mFlags);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.h b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.h
new file mode 100644
index 0000000000..a53fdf70dc
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMap.h
@@ -0,0 +1,541 @@
+/*
+ File: CAAUMIDIMap.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAUMIDIMap_h_
+#define __CAAUMIDIMap_h_
+
+#include <AudioUnit/AudioUnitProperties.h>
+#include <algorithm>
+
+/*
+enum {
+ kAUParameterMIDIMapping_AnyChannelFlag = (1L << 0),
+ // If this flag is set and mStatus is a MIDI channel message, then the MIDI channel number
+ // in the status byte is ignored; the mapping is from the specified MIDI message on ANY channel.
+
+ kAUParameterMIDIMapping_AnyNoteFlag = (1L << 1),
+ // If this flag is set and mStatus is a Note On, Note Off, or Polyphonic Pressure message,
+ // the message's note number is ignored; the mapping is from ANY note number.
+
+ kAUParameterMIDIMapping_SubRange = (1L << 2),
+ // set this flag if the midi control should map only to a sub-range of the parameter's value
+ // then specify that range in the mSubRangeMin and mSubRangeMax members
+
+ kAUParameterMIDIMapping_Toggle = (1L << 3),
+ // this is only useful for boolean typed parameters. When set, it means that the parameter's
+ // value should be toggled (if true, become false and vice versa) when the represented MIDI message
+ // is received
+
+ kAUParameterMIDIMapping_Bipolar = (1L << 4),
+ // this can be set to when mapping a MIDI Controller to indicate that the parameter (typically a boolean
+ // style parameter) will only have its value changed to either the on or off state of a MIDI controller message
+ // (0 < 64 is off, 64 < 127 is on) such as the sustain pedal. The seeting of the next flag
+ // (kAUParameterMIDIMapping_Bipolar_On) determine whether the parameter is mapped to the on or off
+ // state of the controller
+ kAUParameterMIDIMapping_Bipolar_On = (1L << 5)
+ // only a valid flag if kAUParameterMIDIMapping_Bipolar is set
+};
+
+// The reserved fields here are being used to reserve space (as well as align to 64 bit size) for future use
+// When/If these fields are used, the names of the fields will be changed to reflect their functionality
+// so, apps should NOT refer to these reserved fields directly by name
+typedef struct AUParameterMIDIMapping
+{
+ AudioUnitScope mScope;
+ AudioUnitElement mElement;
+ AudioUnitParameterID mParameterID;
+ UInt32 mFlags;
+ Float32 mSubRangeMin;
+ Float32 mSubRangeMax;
+ UInt8 mStatus;
+ UInt8 mData1;
+ UInt8 reserved1; // MUST be set to zero
+ UInt8 reserved2; // MUST be set to zero
+ UInt32 reserved3; // MUST be set to zero
+} AUParameterMIDIMapping;
+*/
+
+/*
+Parameter To MIDI Mapping Properties
+These properties are used to:
+Describe a current set of mappings between MIDI messages and Parameter value setting
+Create a mapping between a parameter and a MIDI message through either:
+- explicitly adding (or removing) the mapping
+- telling the AU to hot-map the next MIDI message to a specified Parameter
+ The same MIDI Message can map to one or more parameters
+ One Parameter can be mapped from multiple MIDI messages
+
+ In general usage, these properties only apply to AU's that implement the MIDI API
+ AU Instruments (type=='aumu') and Music Effects (type == 'aumf')
+
+ These properties are used in the Global scope. The scope and element members of the structure describe
+ the scope and element of the parameter. In all usages, mScope, mElement and mParameterID must be
+ correctly specified.
+
+
+ * The AUParameterMIDIMapping Structure
+
+ Command mStatus mData1
+ Note Off 0x8n Note Num
+ Note On 0x9n Note Num
+ Key Pressure 0xAn Note Num
+ Control Change 0xBn ControllerID
+ Patch Change 0xCn Patch Num
+ Channel Pressure DxDn 0 (Unused)
+ Pitch Bend 0xEn 0 (Unused)
+
+ (where n is 0-0xF to correspond to MIDI channels 1-16)
+
+ Details:
+
+ In general MIDI Commands can be mapped to either a specific channel as specified in the mStatus bit.
+ If the kAUParameterMIDIMapping_AnyChannelFlag bit is set mStatus is a MIDI channel message, then the
+ MIDI channel number in the status byte is ignored; the mapping is from the specified MIDI message on ANY channel.
+
+ For note commands (note on, note off, key pressure), the MIDI message can trigger either with just a specific
+ note number, or any note number if the kAUParameterMIDIMapping_AnyNoteFlag bit is set. In these instances, the
+ note number is used as the trigger value (for instance, a note message could be used to set the
+ cut off frequency of a filter).
+
+ The Properties:
+
+ kAudioUnitProperty_AllParameterMIDIMappings array of AUParameterMIDIMapping (read/write)
+ This property is used to both retreive and set the current mapping state between (some/many/all of) its parameters
+ and MIDI messages. When set, it should replace any previous mapped settings the AU had.
+
+ If this property is implemented by a non-MIDI capable AU (such as an 'aufx' type), then the property is
+ read only, and recommends a suggested set of mappings for the host to perform. In this case, it is the
+ host's responsibility to map MIDI message to the AU parameters. As described previously, there are a set
+ of default mappings (see AudioToolbox/AUMIDIController.h) that the host can recommend to the user
+ in this circumstance.
+
+ This property's size will be very dynamic, depending on the number of mappings currently in affect, so the
+ caller should always get the size of the property first before retrieving it. The AU should return an error
+ if the caller doesn't provide enough space to return all of the current mappings.
+
+ kAudioUnitProperty_AddParameterMIDIMapping array of AUParameterMIDIMapping (write only)
+ This property is used to Add mappings to the existing set of mappings the AU possesses. It does NOT replace
+ any existing mappings.
+
+ kAudioUnitProperty_RemoveParameterMIDIMapping array of AUParameterMIDIMapping (write only)
+ This property is used to remove the specified mappings from the AU. If a mapping is specified that does not
+ currently exist in the AU, then it should just be ignored.
+
+ kAudioUnitProperty_HotMapParameterMIDIMapping AUParameterMIDIMapping (read/write)
+ This property is used in two ways, determined by the value supplied by the caller.
+ (1) If a mapping struct is provided, then that struct provides *all* of the information that the AU should
+ use to map the parameter, *except* for the MIDI message. The AU should then listen for the next MIDI message
+ and associate that MIDI message with the supplied AUParameter mapping. When this MIDI message is received and
+ the mapping made, the AU should also issue a notification on this property
+ (kAudioUnitProperty_HotMapParameterMIDIMapping) to indicate to the host that the mapping has been made. The host
+ can then retrieve the mapping that was made by getting the value of this property.
+
+ To avoid possible confusion, it is recommended that once the host has retrieved this mapping (if it is
+ presenting a UI to describe the mappings for example), that it then clears the mapping state as described next.
+
+ Thus, the only time this property will return a valid value is when the AU has made a mapping. If the AU's mapping
+ state has been cleared (or it has not been asked to make a mapping), then the AU should return
+ kAudioUnitErr_InvalidPropertyValue if the host tries to read this value.
+
+ (2) If the value passed in is NULL, then if the AU had a parameter that it was in the process of mapping, it
+ should disregard that (stop listening to the MIDI messages to create a mapping) and discard the partially
+ mapped struct. If the value is NULL and the AU is not in the process of mapping, the AU can ignore the request.
+
+ At all times, the _AllMappings property will completely describe the current known state of the AU's mappings
+ of MIDI messages to parameters.
+*/
+
+
+/*
+ When mapping, it is recommended that LSB controllers are in general not mapped (ie. the controller range of 32 < 64)
+ as many host parsers will map 14 bit control values. If you know (or can present an option) that the host deals with
+ 7 bit controllers only, then these controller ID's can be mapped of course.
+*/
+
+
+struct MIDIValueTransformer {
+ virtual double tolinear(double) = 0;
+ virtual double fromlinear(double) = 0;
+#if DEBUG
+ // suppress warning
+ virtual ~MIDIValueTransformer() { }
+#endif
+};
+
+struct MIDILinearTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return x; }
+ virtual double fromlinear(double x) { return x; }
+};
+
+struct MIDILogTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return log(std::max(x, .00001)); }
+ virtual double fromlinear(double x) { return exp(x); }
+};
+
+struct MIDIExpTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return exp(x); }
+ virtual double fromlinear(double x) { return log(std::max(x, .00001)); }
+};
+
+struct MIDISqrtTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return x < 0. ? -(sqrt(-x)) : sqrt(x); }
+ virtual double fromlinear(double x) { return x < 0. ? -(x * x) : x * x; }
+};
+
+struct MIDISquareTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return x < 0. ? -(x * x) : x * x; }
+ virtual double fromlinear(double x) { return x < 0. ? -(sqrt(-x)) : sqrt(x); }
+};
+
+struct MIDICubeRtTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return x < 0. ? -(pow(-x, 1./3.)) : pow(x, 1./3.); }
+ virtual double fromlinear(double x) { return x * x * x; }
+};
+
+struct MIDICubeTransformer : public MIDIValueTransformer {
+ virtual double tolinear(double x) { return x * x * x; }
+ virtual double fromlinear(double x) { return x < 0. ? -(pow(-x, 1./3.)) : pow(x, 1./3.); }
+};
+
+
+class CAAUMIDIMap : public AUParameterMIDIMapping {
+
+public:
+// variables for more efficient parsing of MIDI to Param value
+ Float32 mMinValue;
+ Float32 mMaxValue;
+ MIDIValueTransformer *mTransType;
+
+// methods
+ static MIDIValueTransformer *GetTransformer (UInt32 inFlags);
+
+ CAAUMIDIMap() { memset(this, 0, sizeof(CAAUMIDIMap)); }
+ CAAUMIDIMap (const AUParameterMIDIMapping& inMap)
+ {
+ memset(this, 0, sizeof(CAAUMIDIMap));
+ memcpy (this, &inMap, sizeof(inMap));
+ }
+ CAAUMIDIMap (AudioUnitScope inScope, AudioUnitElement inElement, AudioUnitParameterID inParam)
+ {
+ memset(this, 0, sizeof(CAAUMIDIMap));
+ mScope = inScope;
+ mElement = inElement;
+ mParameterID = inParam;
+ }
+
+
+ bool IsValid () const { return mStatus != 0; }
+
+ // returns -1 if any channel bit is set
+ SInt32 Channel () const { return IsAnyChannel() ? -1 : (mStatus & 0xF); }
+ bool IsAnyChannel () const {
+ return mFlags & kAUParameterMIDIMapping_AnyChannelFlag;
+ }
+ // preserves the existing channel info in the status byte
+ // preserves any previously set mFlags value
+ void SetAnyChannel (bool inFlag)
+ {
+ if (inFlag)
+ mFlags |= kAUParameterMIDIMapping_AnyChannelFlag;
+ else
+ mFlags &= ~kAUParameterMIDIMapping_AnyChannelFlag;
+ }
+
+ bool IsAnyNote () const {
+ return (mFlags & kAUParameterMIDIMapping_AnyNoteFlag) != 0;
+ }
+ // preserves the existing key num in the mData1 byte
+ // preserves any previously set mFlags value
+ void SetAnyNote (bool inFlag)
+ {
+ if (inFlag)
+ mFlags |= kAUParameterMIDIMapping_AnyNoteFlag;
+ else
+ mFlags &= ~kAUParameterMIDIMapping_AnyNoteFlag;
+ }
+
+ bool IsToggle() const { return (mFlags & kAUParameterMIDIMapping_Toggle) != 0; }
+ void SetToggle (bool inFlag)
+ {
+ if (inFlag)
+ mFlags |= kAUParameterMIDIMapping_Toggle;
+ else
+ mFlags &= ~kAUParameterMIDIMapping_Toggle;
+ }
+
+ bool IsBipolar() const { return (mFlags & kAUParameterMIDIMapping_Bipolar) != 0; }
+ // inUseOnValue is valid ONLY if inFlag is true
+ void SetBipolar (bool inFlag, bool inUseOnValue = false)
+ {
+ if (inFlag) {
+ mFlags |= kAUParameterMIDIMapping_Bipolar;
+ if (inUseOnValue)
+ mFlags |= kAUParameterMIDIMapping_Bipolar_On;
+ else
+ mFlags &= ~kAUParameterMIDIMapping_Bipolar_On;
+ } else {
+ mFlags &= ~kAUParameterMIDIMapping_Bipolar;
+ mFlags &= ~kAUParameterMIDIMapping_Bipolar_On;
+ }
+ }
+ bool IsBipolar_OnValue () const { return (mFlags & kAUParameterMIDIMapping_Bipolar_On) != 0; }
+
+ bool IsSubRange () const { return (mFlags & kAUParameterMIDIMapping_SubRange) != 0; }
+ void SetSubRange (Float32 inStartValue, Float32 inStopValue)
+ {
+ mFlags |= kAUParameterMIDIMapping_SubRange;
+
+ mSubRangeMin = inStartValue;
+ mSubRangeMax = inStopValue;
+ }
+
+ void SetParamRange(Float32 minValue, Float32 maxValue)
+ {
+ mMinValue = minValue;
+ mMaxValue = maxValue;
+ }
+
+ // this will retain the subrange values previously set.
+ void SetSubRange (bool inFlag)
+ {
+ if (inFlag)
+ mFlags |= kAUParameterMIDIMapping_SubRange;
+ else
+ mFlags &= ~kAUParameterMIDIMapping_SubRange;
+ }
+
+ bool IsAnyValue() const{return !IsBipolar();}
+ bool IsOnValue() const{return IsBipolar_OnValue();}
+ bool IsOffValue() const{return IsBipolar();}
+
+ bool IsNoteOff () const { return ((mStatus & 0xF0) == 0x80); }
+ bool IsNoteOn () const { return ((mStatus & 0xF0) == 0x90); }
+
+ bool IsKeyPressure () const { return ((mStatus & 0xF0) == 0xA0); }
+
+ bool IsKeyEvent () const { return (mStatus > 0x7F) && (mStatus < 0xB0); }
+
+ bool IsPatchChange () const { return ((mStatus & 0xF0) == 0xC0); }
+ bool IsChannelPressure () const { return ((mStatus & 0xF0) == 0xD0); }
+ bool IsPitchBend () const { return ((mStatus & 0xF0) == 0xE0); }
+ bool IsControlChange () const { return ((mStatus & 0xF0) == 0xB0); }
+
+
+ void SetControllerOnValue(){SetBipolar(true,true);}
+ void SetControllerOffValue(){SetBipolar(true,false);}
+ void SetControllerAnyValue(){SetBipolar(false,false);}
+
+ // All of these Set calls will reset the mFlags field based on the
+ // anyChannel param value
+ void SetNoteOff (UInt8 key, SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0x80 | (channel & 0xF);
+ mData1 = key;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+
+ }
+
+ void SetNoteOn (UInt8 key, SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0x90 | (channel & 0xF);
+ mData1 = key;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+ void SetPolyKey (UInt8 key, SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0xA0 | (channel & 0xF);
+ mData1 = key;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+ void SetControlChange (UInt8 controllerID, SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0xB0 | (channel & 0xF);
+ mData1 = controllerID;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+ void SetPatchChange (UInt8 patchChange, SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0xC0 | (channel & 0xF);
+ mData1 = patchChange;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+ void SetChannelPressure (SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0xD0 | (channel & 0xF);
+ mData1 = 0;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+ void SetPitchBend (SInt8 channel, bool anyChannel = false)
+ {
+ mStatus = 0xE0 | (channel & 0xF);
+ mData1 = 0;
+ mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
+ }
+
+
+ Float32 ParamValueFromMIDILinear (Float32 inLinearValue) const
+ {
+ Float32 low, high;
+ if (IsSubRange()){
+ low = mSubRangeMin;
+ high = mSubRangeMax;
+ }
+ else {
+ low = mMinValue;
+ high = mMaxValue;
+ }
+
+
+ // WE ARE ASSUMING YOU HAVE SET THIS UP PROPERLY!!!!! (or this will crash cause it will be NULL)
+ return (Float32)mTransType->fromlinear((inLinearValue * (high - low)) + low);
+ }
+
+
+ // The CALLER of this method must ensure that the status byte's MIDI Command (ignoring the channel) matches!!!
+ bool MIDI_Matches (UInt8 inChannel, UInt8 inData1, UInt8 inData2, Float32 &outLinear) const;
+
+ void Print () const;
+
+ void Save (CFPropertyListRef &outData) const;
+ void Restore (CFDictionaryRef inData);
+
+ static void SaveAsMapPList (AudioUnit inUnit,
+ const AUParameterMIDIMapping * inMappings,
+ UInt32 inNumMappings,
+ CFPropertyListRef &outData,
+ CFStringRef inName = NULL);
+
+ // inNumMappings describes how much memory is allocated in outMappings
+ static void RestoreFromMapPList (const CFDictionaryRef inData,
+ AUParameterMIDIMapping * outMappings,
+ UInt32 inNumMappings);
+
+ static UInt32 NumberOfMaps (const CFDictionaryRef inData);
+};
+
+
+ // these sorting operations sort for run-time efficiency based on the MIDI messages
+inline bool operator== (const CAAUMIDIMap &a, const CAAUMIDIMap &b)
+{
+ // ignore channel first
+ return (((a.mStatus & 0xF0) == (b.mStatus & 0xF0))
+ && (a.mData1 == b.mData1)
+ && ((a.mStatus & 0xF) == (b.mStatus & 0xf)) // now compare the channel
+ && (a.mParameterID == b.mParameterID)
+ && (a.mElement == b.mElement)
+ && (a.mScope == b.mScope));
+
+ // reserved field comparisons - ignored until/if they are used
+}
+
+inline bool operator< (const CAAUMIDIMap &a, const CAAUMIDIMap &b)
+{
+ if ((a.mStatus & 0xF0) != (b.mStatus & 0xF0))
+ return ((a.mStatus & 0xF0) < (b.mStatus & 0xF0));
+
+ if (a.mData1 != b.mData1)
+ return (a.mData1 < b.mData1);
+
+ if ((a.mStatus & 0xF) != (b.mStatus & 0xf)) // now compare the channel
+ return ((a.mStatus & 0xF) < (b.mStatus & 0xf));
+
+// reserved field comparisons - ignored until/if they are used
+
+// we're sorting this by MIDI, so we don't really care how the rest is sorted
+ return ((a.mParameterID < b.mParameterID)
+ && (a.mElement < b.mElement)
+ && (a.mScope < b.mScope));
+}
+
+
+
+class CompareMIDIMap {
+ int compare (const CAAUMIDIMap &a, const CAAUMIDIMap &b)
+ {
+ if ((a.mStatus & 0xF0) < (b.mStatus & 0xF0))
+ return -1;
+ if ((a.mStatus & 0xF0) > (b.mStatus & 0xF0))
+ return 1;
+
+ // note event
+ if (a.mStatus < 0xB0 || a.mStatus >= 0xD0)
+ return 0;
+ if (a.mData1 > b.mData1) return 1;
+ if (a.mData1 < b.mData1) return -1;
+ return 0;
+ }
+
+public:
+ bool operator() (const CAAUMIDIMap &a, const CAAUMIDIMap &b) {
+ return compare (a, b) < 0;
+ }
+ bool Finish (const CAAUMIDIMap &a, const CAAUMIDIMap &b) {
+ return compare (a, b) != 0;
+ }
+};
+
+
+/*
+ usage: To find potential mapped events for a given status byte, where mMMapEvents is a sorted vec
+ CompareMIDIMap comparObj;
+ sortVecIter lower_iter = std::lower_bound(mMMapEvents.begin(), mMMapEvents.end(), inStatusByte, compareObj);
+ for (;lower_iter < mMMapEvents.end(); ++lower_iter) {
+ // then, see if we go out of the status byte range, using the Finish method
+ if (compareObj.Finish(map, tempMap)) // tempMap is a CAAUMIDIMap object with the status/dataByte 1 set
+ break;
+ // ...
+ }
+
+ in the for loop you call the MIDI_Matches call, to see if the MIDI event matches a given AUMIDIParam mapping
+ special note: you HAVE to transform note on (with vel zero) events to the note off status byte
+*/
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.cpp
new file mode 100644
index 0000000000..b24ff9945c
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.cpp
@@ -0,0 +1,233 @@
+/*
+ File: CAAUMIDIMapManager.cpp
+ Abstract: CAAUMIDIMapManager.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAUMIDIMapManager.h"
+#include <AudioToolbox/AudioUnitUtilities.h>
+
+CAAUMIDIMapManager::CAAUMIDIMapManager()
+{
+ hotMapping = false;
+}
+
+static void FillInMap (CAAUMIDIMap &map, AUBase &That)
+{
+ AudioUnitParameterInfo info;
+ That.GetParameterInfo (map.mScope, map.mParameterID, info);
+
+ if (map.IsSubRange()) {
+ map.mMinValue = map.mSubRangeMin;
+ map.mMaxValue = map.mSubRangeMax;
+ } else {
+ map.mMinValue = info.minValue;
+ map.mMaxValue = info.maxValue;
+ }
+
+ map.mTransType = CAAUMIDIMap::GetTransformer(info.flags);
+}
+
+OSStatus CAAUMIDIMapManager::SortedInsertToParamaterMaps (AUParameterMIDIMapping *maps, UInt32 inNumMaps, AUBase &That)
+{
+ for (unsigned int i = 0; i < inNumMaps; ++i)
+ {
+ CAAUMIDIMap map(maps[i]);
+
+ FillInMap (map, That);
+
+ int idx = FindParameterIndex (maps[i]);
+ if (idx > -1)
+ mParameterMaps.erase(mParameterMaps.begin() + idx);
+
+ // least disruptive place to put this is at the end
+ mParameterMaps.push_back(map);
+ }
+
+ std::sort(mParameterMaps.begin(), mParameterMaps.end(), CompareMIDIMap());
+
+ return noErr;
+}
+
+void CAAUMIDIMapManager::GetHotParameterMap(AUParameterMIDIMapping &outMap )
+{
+ outMap = mHotMap;
+}
+
+void CAAUMIDIMapManager::SortedRemoveFromParameterMaps(AUParameterMIDIMapping *maps, UInt32 inNumMaps, bool &outMapDidChange)
+{
+ if (hotMapping) {
+ hotMapping = false;
+ }
+
+ outMapDidChange = false;
+ for (unsigned int i = 0; i < inNumMaps; ++i) {
+ int idx = FindParameterIndex (maps[i]);
+ if (idx > -1) {
+ //mParameterMaps[idx].Print();
+ mParameterMaps.erase(mParameterMaps.begin() + idx);
+ outMapDidChange = true;
+ }
+ }
+}
+
+void CAAUMIDIMapManager::ReplaceAllMaps (AUParameterMIDIMapping* inMappings, UInt32 inNumMaps, AUBase &That)
+{
+ mParameterMaps.clear();
+
+ for (unsigned int i = 0; i < inNumMaps; ++i) {
+ CAAUMIDIMap mapping(inMappings[i]);
+
+ FillInMap (mapping, That);
+ mParameterMaps.push_back (mapping);
+ }
+
+ std::sort(mParameterMaps.begin(),mParameterMaps.end(), CompareMIDIMap());
+}
+
+bool CAAUMIDIMapManager::HandleHotMapping(UInt8 inStatus,
+ UInt8 inChannel,
+ UInt8 inData1,
+ AUBase &That)
+{ //used to set the hot map info
+
+ if (inStatus == 0xf0) return false;
+
+ if (!hotMapping) return false;
+ hotMapping = false;
+
+ mHotMap.mStatus = inStatus | inChannel;
+ mHotMap.mData1 = inData1;
+
+ SortedInsertToParamaterMaps (&mHotMap, 1, That);
+ return true;
+}
+
+#if DEBUG
+
+void CAAUMIDIMapManager::Print()
+{
+ for ( ParameterMaps::iterator i = mParameterMaps.begin(); i < mParameterMaps.end(); ++i) {
+ CAAUMIDIMap* listmap = &(*i);
+ listmap->Print();
+ }
+}
+
+#endif // DEBUG
+
+void CAAUMIDIMapManager::GetMaps(AUParameterMIDIMapping* maps)
+{
+ int i = 0;
+ for ( ParameterMaps::iterator iter = mParameterMaps.begin(); iter < mParameterMaps.end(); ++iter, ++i) {
+ AUParameterMIDIMapping &listmap = (*iter);
+ maps[i] = listmap;
+ }
+}
+
+int CAAUMIDIMapManager::FindParameterIndex (AUParameterMIDIMapping &inMap)
+{
+ //used to get back hot mapping and one at a time maps, for ui
+
+ int idx = 0;
+ for ( ParameterMaps::iterator i = mParameterMaps.begin(); i < mParameterMaps.end(); ++i) {
+ CAAUMIDIMap & listmap = (*i);
+ if ( (listmap.mParameterID == inMap.mParameterID) &&
+ (listmap.mScope == inMap.mScope) &&
+ (listmap.mElement == inMap.mElement) )
+ {
+ return idx;
+ }
+ idx++;
+ }
+ return -1;
+}
+
+bool CAAUMIDIMapManager::FindParameterMapEventMatch( UInt8 inStatus,
+ UInt8 inChannel,
+ UInt8 inData1,
+ UInt8 inData2,
+ UInt32 inBufferOffset,
+ AUBase& inAUBase)
+{
+ bool ret_value = false;
+
+ if (inStatus == 0x90 && !inData2)
+ inStatus = 0x80 | inChannel;
+
+ //used to test for midi matches once map is made
+ CAAUMIDIMap tempMap;
+ tempMap.mStatus = inStatus | inChannel;
+ tempMap.mData1 = inData1;
+
+ CompareMIDIMap compareObj;
+
+ AudioUnitEvent event;
+ event.mEventType = kAudioUnitEvent_ParameterValueChange;
+ event.mArgument.mParameter.mAudioUnit = inAUBase.GetComponentInstance();
+
+ ParameterMaps::iterator lower_iter =
+ std::lower_bound(mParameterMaps.begin(), mParameterMaps.end(), tempMap, compareObj);
+
+ while (lower_iter < mParameterMaps.end())
+ {
+ CAAUMIDIMap & map = (*lower_iter);
+ if (compareObj.Finish(map, tempMap))
+ break;
+
+ Float32 value;
+ if (map.MIDI_Matches(inChannel, inData1, inData2, value))
+ {
+ inAUBase.SetParameter ( map.mParameterID, map.mScope, map.mElement,
+ map.ParamValueFromMIDILinear(value), inBufferOffset);
+
+ event.mArgument.mParameter.mParameterID = map.mParameterID;
+ event.mArgument.mParameter.mScope = map.mScope;
+ event.mArgument.mParameter.mElement = map.mElement;
+
+ AUEventListenerNotify(NULL, NULL, &event);
+ ret_value = true;
+ }
+ ++lower_iter;
+ }
+ return ret_value;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.h b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.h
new file mode 100644
index 0000000000..8926d8f6e1
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUMIDIMapManager.h
@@ -0,0 +1,102 @@
+/*
+ File: CAAUMIDIMapManager.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAUMIDIMapManager_h_
+#define __CAAUMIDIMapManager_h_
+
+#include "AUBase.h"
+#include "CAAUMIDIMap.h"
+#include <vector>
+#include <AudioToolbox/AudioUnitUtilities.h>
+
+class CAAUMIDIMapManager {
+
+protected:
+
+ typedef std::vector<CAAUMIDIMap> ParameterMaps;
+ ParameterMaps mParameterMaps;
+
+ bool hotMapping;
+ AUParameterMIDIMapping mHotMap;
+
+public:
+
+ CAAUMIDIMapManager();
+
+ UInt32 NumMaps(){return static_cast<UInt32>(mParameterMaps.size());}
+ void GetMaps(AUParameterMIDIMapping* maps);
+
+ int FindParameterIndex(AUParameterMIDIMapping &map);
+
+ void GetHotParameterMap(AUParameterMIDIMapping &outMap);
+
+ void SortedRemoveFromParameterMaps (AUParameterMIDIMapping *maps, UInt32 inNumMaps, bool &outMapDidChange);
+ OSStatus SortedInsertToParamaterMaps (AUParameterMIDIMapping *maps, UInt32 inNumMaps, AUBase &That);
+
+ void ReplaceAllMaps (AUParameterMIDIMapping* inMappings, UInt32 inNumMaps, AUBase &That);
+
+ bool IsHotMapping(){return hotMapping;}
+ void SetHotMapping (AUParameterMIDIMapping &inMap){hotMapping = true; mHotMap = inMap; }
+
+ bool HandleHotMapping( UInt8 inStatus,
+ UInt8 inChannel,
+ UInt8 inData1,
+ AUBase &That);
+
+
+ bool FindParameterMapEventMatch(UInt8 inStatus,
+ UInt8 inChannel,
+ UInt8 inData1,
+ UInt8 inData2,
+ UInt32 inBufferOffset,
+ AUBase& inAUBase);
+#if DEBUG
+ void Print();
+#endif
+};
+
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.cpp
new file mode 100644
index 0000000000..2d8fe18341
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.cpp
@@ -0,0 +1,400 @@
+/*
+ File: CAAUParameter.cpp
+ Abstract: CAAUParameter.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAUParameter.h"
+
+CAAUParameter::CAAUParameter()
+{
+ memset(this, 0, sizeof(CAAUParameter));
+}
+
+CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
+{
+ memset(this, 0, sizeof(CAAUParameter));
+ Init (au, param, scope, element);
+}
+
+CAAUParameter::CAAUParameter (AudioUnitParameter &inParam)
+{
+ memset(this, 0, sizeof(CAAUParameter));
+ Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement);
+}
+
+CAAUParameter::CAAUParameter(const CAAUParameter &a)
+{
+ memset(this, 0, sizeof(CAAUParameter));
+ *this = a;
+}
+
+CAAUParameter & CAAUParameter::operator = (const CAAUParameter &a)
+{
+ if (mParamName) CFRelease(mParamName);
+ if (mParamTag) CFRelease(mParamTag);
+ if (mNamedParams) CFRelease(mNamedParams);
+
+ memcpy(this, &a, sizeof(CAAUParameter));
+
+ if (mParamName) CFRetain(mParamName);
+ if (mParamTag) CFRetain(mParamTag);
+ if (mNamedParams) CFRetain(mNamedParams);
+
+ return *this;
+}
+
+CAAUParameter::~CAAUParameter()
+{
+ if (mParamName) CFRelease(mParamName);
+ if (mParamTag) CFRelease(mParamTag);
+ if (mNamedParams) CFRelease (mNamedParams);
+}
+
+void CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
+{
+ mAudioUnit = au;
+ mParameterID = param;
+ mScope = scope;
+ mElement = element;
+
+ UInt32 propertySize = sizeof(mParamInfo);
+ OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo,
+ scope, param, &mParamInfo, &propertySize);
+ if (err)
+ memset(&mParamInfo, 0, sizeof(mParamInfo));
+ if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) {
+ mParamName = mParamInfo.cfNameString;
+ if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease))
+ CFRetain (mParamName);
+ } else
+ mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8);
+
+ const char* str = 0;
+ switch (mParamInfo.unit)
+ {
+ case kAudioUnitParameterUnit_Boolean:
+ str = "T/F";
+ break;
+ case kAudioUnitParameterUnit_Percent:
+ case kAudioUnitParameterUnit_EqualPowerCrossfade:
+ str = "%";
+ break;
+ case kAudioUnitParameterUnit_Seconds:
+ str = "Secs";
+ break;
+ case kAudioUnitParameterUnit_SampleFrames:
+ str = "Samps";
+ break;
+ case kAudioUnitParameterUnit_Phase:
+ case kAudioUnitParameterUnit_Degrees:
+ str = "Degr.";
+ break;
+ case kAudioUnitParameterUnit_Hertz:
+ str = "Hz";
+ break;
+ case kAudioUnitParameterUnit_Cents:
+ case kAudioUnitParameterUnit_AbsoluteCents:
+ str = "Cents";
+ break;
+ case kAudioUnitParameterUnit_RelativeSemiTones:
+ str = "S-T";
+ break;
+ case kAudioUnitParameterUnit_MIDINoteNumber:
+ case kAudioUnitParameterUnit_MIDIController:
+ str = "MIDI";
+ //these are inclusive, so add one value here
+ mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
+ break;
+ case kAudioUnitParameterUnit_Decibels:
+ str = "dB";
+ break;
+ case kAudioUnitParameterUnit_MixerFaderCurve1:
+ case kAudioUnitParameterUnit_LinearGain:
+ str = "Gain";
+ break;
+ case kAudioUnitParameterUnit_Pan:
+ str = "L/R";
+ break;
+ case kAudioUnitParameterUnit_Meters:
+ str = "Mtrs";
+ break;
+ case kAudioUnitParameterUnit_Octaves:
+ str = "8ve";
+ break;
+ case kAudioUnitParameterUnit_BPM:
+ str = "BPM";
+ break;
+ case kAudioUnitParameterUnit_Beats:
+ str = "Beats";
+ break;
+ case kAudioUnitParameterUnit_Milliseconds:
+ str = "msecs";
+ break;
+ case kAudioUnitParameterUnit_Ratio:
+ str = "Ratio";
+ break;
+ case kAudioUnitParameterUnit_Indexed:
+ {
+ propertySize = sizeof(mNamedParams);
+ err = AudioUnitGetProperty (au,
+ kAudioUnitProperty_ParameterValueStrings,
+ scope,
+ param,
+ &mNamedParams,
+ &propertySize);
+ if (!err && mNamedParams) {
+ mNumIndexedParams = CFArrayGetCount(mNamedParams);
+ } else {
+ //these are inclusive, so add one value here
+ mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
+ }
+ str = NULL;
+ }
+ break;
+ case kAudioUnitParameterUnit_CustomUnit:
+ {
+ CFStringRef unitName = mParamInfo.unitName;
+ static char paramStr[256];
+ CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8);
+ if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)
+ CFRelease (unitName);
+ str = paramStr;
+ break;
+ }
+ case kAudioUnitParameterUnit_Generic:
+ case kAudioUnitParameterUnit_Rate:
+ default:
+ str = NULL;
+ break;
+ }
+
+ if (str)
+ mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
+ else
+ mParamTag = NULL;
+}
+
+
+Float32 CAAUParameter::GetValue() const
+{
+ Float32 value = 0.;
+ //OSStatus err =
+ AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value);
+ return value;
+}
+
+CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
+ const CAAUParameter * inParameter,
+ UInt32 inDigits,
+ UInt32 minDigits) {
+ if (!inParameter) return nil;
+
+ AudioUnitParameterInfo info = inParameter->ParamInfo();
+ int pow10;
+
+ switch (info.unit) {
+ case kAudioUnitParameterUnit_Hertz:
+ // number of significant digits based on value
+ pow10 = int(log10(fmax(inParameterValue, .000001)));
+ break;
+ default:
+ // number of significant digits based on parameter range
+ pow10 = int(log10(fmax(double(info.maxValue - info.minValue), .000001)));
+ break;
+ }
+
+ // pow10 range nDigitsAfterDecimal
+ // -2 .0100-.0999 4
+ // -1 .100-.999 3
+ // 0 1.00-9.99 2
+ // 1 10.0-99.9 1
+ // 2 100-999 0
+ // 3 1000-9990 -1
+ // 4 10000-99900 -2
+
+ int nDigitsAfterDecimal = inDigits - (pow10 + 1);
+ if (nDigitsAfterDecimal < 0)
+ nDigitsAfterDecimal = 0; // the least number of digits possible is zero
+
+ if (info.flags & kAudioUnitParameterFlag_IsHighResolution)
+ nDigitsAfterDecimal = 4;
+
+ CFLocaleRef currentLocale = CFLocaleCopyCurrent();
+ CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
+
+ CFNumberRef maxFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
+
+ if (nDigitsAfterDecimal > 0)
+ nDigitsAfterDecimal = minDigits;
+
+ CFNumberRef minFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
+
+ CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMinFractionDigits, minFractionDigits);
+ CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMaxFractionDigits, maxFractionDigits);
+ CFStringRef formattedNumberString = CFNumberFormatterCreateStringWithValue (NULL, numberFormatter, kCFNumberDoubleType, &inParameterValue);
+
+ CFRelease(currentLocale);
+ CFRelease(numberFormatter);
+ CFRelease(maxFractionDigits);
+ CFRelease(minFractionDigits);
+
+ return formattedNumberString;
+}
+
+CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
+ const CAAUParameter * inParameter,
+ UInt32 inDigits) {
+ return CreateLocalizedStringForParameterValue (inParameterValue, inParameter, inDigits, 1);
+}
+
+double ValueForLocalizedParameterString (CFStringRef string, const CAAUParameter * inParameter) {
+ CFLocaleRef currentLocale = CFLocaleCopyCurrent();
+ CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
+
+ double value = 0;
+ Boolean worked = CFNumberFormatterGetValueFromString (numberFormatter, string, NULL, kCFNumberDoubleType, &value);
+
+ CFRelease(currentLocale);
+ CFRelease(numberFormatter);
+
+ if (worked)
+ return value;
+ else {
+ AudioUnitParameterInfo info = inParameter->ParamInfo();
+ return info.defaultValue;
+ }
+}
+
+CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const
+{
+ if (HasNamedParams())
+ {
+ Float32 val = (value == NULL ? GetValue() : *value);
+ int index = int(mParamInfo.minValue) + int(val);
+ CFStringRef str = GetParamName (index);
+ if (str) {
+ CFRetain (str);
+ return str;
+ }
+ }
+ else if (ValuesHaveStrings())
+ {
+ AudioUnitParameterStringFromValue stringValue;
+ stringValue.inParamID = mParameterID;
+ stringValue.inValue = value;
+ stringValue.outString = NULL;
+ UInt32 propertySize = sizeof(stringValue);
+
+ OSStatus err = AudioUnitGetProperty (mAudioUnit,
+ kAudioUnitProperty_ParameterStringFromValue,
+ mScope,
+ 0,
+ &stringValue,
+ &propertySize);
+
+ if (!err && stringValue.outString != NULL)
+ return stringValue.outString;
+ }
+
+ Float32 val = (value == NULL ? GetValue() : *value);
+ AudioUnitParameterUnit unit = this->ParamInfo().unit;
+ if (unit == kAudioUnitParameterUnit_Cents || unit == kAudioUnitParameterUnit_AbsoluteCents)
+ return CreateLocalizedStringForParameterValue(val, this, 4, 0);
+ else
+ return CreateLocalizedStringForParameterValue(val, this, 4);
+}
+
+Float32 CAAUParameter::GetValueFromString(CFStringRef str) const
+{
+ if (ValuesHaveStrings())
+ {
+ AudioUnitParameterValueFromString valueString;
+ valueString.inParamID = mParameterID;
+ valueString.inString = str;
+ UInt32 propertySize = sizeof(valueString);
+
+ OSStatus err = AudioUnitGetProperty (mAudioUnit,
+ kAudioUnitProperty_ParameterValueFromString,
+ mScope,
+ 0,
+ &valueString,
+ &propertySize);
+
+ if (!err) {
+ return valueString.outValue;
+ }
+ }
+
+ return (Float32) ValueForLocalizedParameterString(str, this);
+}
+
+void CAAUParameter::SetValue( AUParameterListenerRef inListener,
+ void * inObject,
+ Float32 inValue) const
+{
+ // clip inValue as: maxValue >= inValue >= minValue before setting
+ Float32 valueToSet = inValue;
+ if (valueToSet > mParamInfo.maxValue)
+ valueToSet = mParamInfo.maxValue;
+ if (valueToSet < mParamInfo.minValue)
+ valueToSet = mParamInfo.minValue;
+
+ AUParameterSet(inListener, inObject, this, valueToSet, 0);
+}
+
+#if DEBUG
+void CAAUParameter::Print() const
+{
+ UInt32 clump = 0;
+ GetClumpID (clump);
+
+ UInt32 len = static_cast<UInt32>(CFStringGetLength(mParamName));
+ char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
+ if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8))
+ chars[0] = 0;
+
+ printf ("ID: %ld, Clump: %u, Name: %s\n", (long unsigned int) mParameterID, (unsigned int) clump, chars);
+ free (chars);
+}
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.h b/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.h
new file mode 100644
index 0000000000..f8b5733d8c
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUParameter.h
@@ -0,0 +1,191 @@
+/*
+ File: CAAUParameter.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAUParameter_h__
+#define __CAAUParameter_h__
+
+#include <AudioToolbox/AudioUnitUtilities.h>
+
+// ____________________________________________________________________________
+// CAAUParameter
+// complete parameter specification
+ /*! @class CAAUParameter */
+class CAAUParameter : public AudioUnitParameter {
+public:
+ /*! @ctor CAAUParameter.0 */
+ CAAUParameter();
+ /*! @ctor CAAUParameter.1 */
+ CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
+ /*! @ctor CAAUParameter.2 */
+ CAAUParameter(AudioUnitParameter &inParam);
+ /*! @ctor CAAUParameter.3 */
+ CAAUParameter(const CAAUParameter &a);
+ /*! @dtor ~CAAUParameter */
+ ~CAAUParameter();
+
+ /*! @method operator <@ */
+ bool operator < (const CAAUParameter &a) const
+ {
+ return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0;
+ }
+
+ /*! @method operator ==@ */
+ bool operator == (const CAAUParameter &a) const
+ {
+ return !memcmp(this, &a, sizeof(AudioUnitParameter));
+ }
+
+ /*! @method operator =@ */
+ CAAUParameter & operator = (const CAAUParameter &a);
+
+ /*! @method GetValue */
+ Float32 GetValue() const;
+ /*! @method SetValue */
+ void SetValue( AUParameterListenerRef inListener,
+ void * inObject,
+ Float32 inValue) const;
+
+ /*! @method GetName */
+ CFStringRef GetName() const { return mParamName; }
+ // borrowed reference!
+
+ /*! @method GetStringFromValueCopy */
+ CFStringRef GetStringFromValueCopy(const Float32 *value = NULL) const;
+ // returns a copy of the name of the current parameter value
+ // or null if there is no name associated
+ // caller must release
+ /*! @method ValuesHaveStrings */
+ bool ValuesHaveStrings () const
+ {
+ return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0;
+ }
+
+ /*! @method GetValueFromString */
+ Float32 GetValueFromString (CFStringRef str) const;
+ // caller must release
+
+ /*! @method ParamInfo */
+ const AudioUnitParameterInfo &
+ ParamInfo() const { return mParamInfo; }
+
+ /*! @method GetParamTag */
+ CFStringRef GetParamTag() const { return mParamTag; }
+ // this may return null! -
+ // in which case there is no descriptive tag for the parameter
+
+ /*! @method GetParamName */
+ CFStringRef GetParamName (int inIndex) const
+ // this can return null if there is no name for the parameter
+ {
+ return (mNamedParams && inIndex < mNumIndexedParams)
+ ? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex)
+ : 0;
+ }
+
+ /*! @method GetNumIndexedParams */
+ int GetNumIndexedParams () const { return mNumIndexedParams; }
+
+ /*! @method IsIndexedParam */
+ bool IsIndexedParam () const { return mNumIndexedParams != 0; }
+
+ /*! @method HasNamedParams */
+ bool HasNamedParams () const { return IsIndexedParam() && mNamedParams; }
+
+ /*! @method GetClumpID */
+ bool GetClumpID (UInt32 &outClumpID) const
+ {
+ if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) {
+ outClumpID = mParamInfo.clumpID;
+ return true;
+ }
+ return false;
+ }
+
+ /*! @method HasDisplayTransformation */
+ bool HasDisplayTransformation () const
+ {
+ return GetAudioUnitParameterDisplayType (mParamInfo.flags);
+ }
+
+ /*! @method IsExpert */
+ bool IsExpert () const
+ {
+ return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode;
+ }
+#if DEBUG
+ void Print () const;
+#endif
+
+ // these methods are defined in CAPersistence.cpp
+ // they will persist and restore only the scope, element and param ID's of the AudioUnitParameter
+ // however, this is sufficient to be able to save/restore a CAAUParameter object
+ void Save (CFPropertyListRef &outData) const;
+
+ static void Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData);
+
+ static OSStatus Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam);
+
+protected:
+ // cached parameter info
+ /*! @var mParamInfo */
+ AudioUnitParameterInfo mParamInfo;
+ /*! @var mParamName */
+ CFStringRef mParamName;
+ /*! @var mParamTag */
+ CFStringRef mParamTag;
+ /*! @var mNumIndexedParams */
+ short mNumIndexedParams;
+ /*! @var mNamedParams */
+ CFArrayRef mNamedParams;
+
+private:
+ void Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
+
+};
+
+
+
+#endif // __CAAUParameter_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.cpp
new file mode 100644
index 0000000000..1cda39c99d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.cpp
@@ -0,0 +1,707 @@
+/*
+ File: CAAUProcessor.cpp
+ Abstract: CAAUProcessor.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAUProcessor.h"
+#include "CAXException.h"
+
+static OSStatus SilenceInputCallback (void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData)
+{
+ AudioBuffer *buf = ioData->mBuffers;
+ for (UInt32 i = ioData->mNumberBuffers; i--; ++buf)
+ memset((Byte *)buf->mData, 0, buf->mDataByteSize);
+
+ //provide a hint that our input data is silent.
+ *ioActionFlags &= kAudioUnitRenderAction_OutputIsSilence;
+ return noErr;
+}
+
+static AURenderCallbackStruct sSilentCallback = { SilenceInputCallback, NULL };
+
+
+CAAUProcessor::CAAUProcessor (const CAComponent& inComp)
+ : mPreflightABL(NULL)
+{
+ OSStatus result = CAAudioUnit::Open (inComp, mUnit);
+ if (result)
+ throw result;
+ memset (&mUserCallback, 0, sizeof (AURenderCallbackStruct));
+ mMaxTailTime = 10.;
+}
+
+CAAUProcessor::~CAAUProcessor ()
+{
+ if (mPreflightABL)
+ delete mPreflightABL;
+}
+
+inline OSStatus SetInputCallback (CAAudioUnit &inUnit, AURenderCallbackStruct &inInputCallback)
+{
+ return inUnit.SetProperty (kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Input,
+ 0,
+ &inInputCallback,
+ sizeof(inInputCallback));
+}
+
+static AURenderCallbackStruct sRenderCallback;
+static OSStatus PrerollRenderProc ( void * /*inRefCon*/,
+ AudioUnitRenderActionFlags * /*inActionFlags*/,
+ const AudioTimeStamp * /*inTimeStamp*/,
+ UInt32 /*inBusNumber*/,
+ UInt32 /*inNumFrames*/,
+ AudioBufferList *ioData)
+{
+ AudioBuffer *buf = ioData->mBuffers;
+ for (UInt32 i = ioData->mNumberBuffers; i--; ++buf)
+ memset((Byte *)buf->mData, 0, buf->mDataByteSize);
+
+ return noErr;
+}
+
+OSStatus Preroll (CAAudioUnit & inAU, UInt32 inFrameSize)
+{
+ CAStreamBasicDescription desc;
+ OSStatus result = inAU.GetFormat (kAudioUnitScope_Input, 0, desc);
+ bool hasInput = false;
+ //we have input
+ if (result == noErr)
+ {
+ sRenderCallback.inputProc = PrerollRenderProc;
+ sRenderCallback.inputProcRefCon = 0;
+
+ result = inAU.SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+ 0, &sRenderCallback, sizeof(sRenderCallback));
+ if (result) return result;
+ hasInput = true;
+ }
+
+ AudioUnitRenderActionFlags flags = 0;
+ AudioTimeStamp time;
+ memset (&time, 0, sizeof(time));
+ time.mFlags = kAudioTimeStampSampleTimeValid;
+
+ CAStreamBasicDescription outputFormat;
+ ca_require_noerr (result = inAU.GetFormat (kAudioUnitScope_Output, 0, outputFormat), home);
+ {
+ AUOutputBL list (outputFormat, inFrameSize);
+ list.Prepare ();
+
+ result = inAU.Render (&flags, &time, 0, inFrameSize, list.ABL());
+ if (result) { printf("A result %d\n", (int)result); goto home; }
+ }
+
+home:
+ if (hasInput) {
+ // remove our installed callback
+ sRenderCallback.inputProc = 0;
+ sRenderCallback.inputProcRefCon = 0;
+
+ inAU.SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+ 0, &sRenderCallback, sizeof(sRenderCallback));
+ }
+ return result;
+}
+
+
+OSStatus CAAUProcessor::EstablishInputCallback (AURenderCallbackStruct &inInputCallback)
+{
+ OSStatus result = SetInputCallback (mUnit, inInputCallback);
+ if (!result)
+ memcpy (&mUserCallback, &inInputCallback, sizeof(AURenderCallbackStruct));
+ else
+ memset (&mUserCallback, 0, sizeof (AURenderCallbackStruct));
+ return result;
+}
+
+OSStatus CAAUProcessor::SetAUPreset (CFPropertyListRef inPreset)
+{
+ return mUnit.SetProperty (kAudioUnitProperty_ClassInfo,
+ kAudioUnitScope_Global,
+ 0,
+ &inPreset,
+ sizeof(inPreset));
+}
+
+OSStatus CAAUProcessor::SetAUPresetIndex (SInt32 inPresetIndex)
+{
+ AUPreset aup;
+ aup.presetName = NULL;
+ aup.presetNumber = inPresetIndex;
+ return mUnit.SetPresentPreset(aup);
+}
+
+
+OSStatus CAAUProcessor::SetParameter (AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames)
+{
+ return mUnit.SetParameter(inID, scope, element, value, bufferOffsetFrames);
+}
+
+
+UInt32 CAAUProcessor::MaxFramesPerRender () const
+{
+ UInt32 maxFrames;
+ UInt32 propSize = sizeof (maxFrames);
+ if (mUnit.GetProperty (kAudioUnitProperty_MaximumFramesPerSlice,
+ kAudioUnitScope_Global, 0, &maxFrames, &propSize))
+ {
+ return 0;
+ }
+ return maxFrames;
+}
+
+OSStatus CAAUProcessor::SetMaxFramesPerRender (UInt32 inMaxFrames)
+{
+ return mUnit.SetProperty (kAudioUnitProperty_MaximumFramesPerSlice,
+ kAudioUnitScope_Global, 0, &inMaxFrames, sizeof(inMaxFrames));
+}
+
+OSStatus CAAUProcessor::Initialize (const CAStreamBasicDescription &inInputDesc,
+ const CAStreamBasicDescription &inOutputDesc,
+ UInt64 inNumInputSamples)
+{
+ return DoInitialisation (inInputDesc, inOutputDesc, inNumInputSamples, MaxFramesPerRender());
+}
+
+OSStatus CAAUProcessor::Reinitialize (UInt32 inNewMaxFrames)
+{
+ OSStatus result;
+ CAStreamBasicDescription inputDesc, outputDesc;
+
+ ca_require_noerr (result = mUnit.GetFormat (kAudioUnitScope_Input, 0, inputDesc), home);
+ ca_require_noerr (result = mUnit.GetFormat (kAudioUnitScope_Output, 0, outputDesc), home);
+
+ ca_require_noerr (result = DoInitialisation (inputDesc, outputDesc, mNumInputSamples, inNewMaxFrames), home);
+
+home:
+ return result;
+}
+
+
+OSStatus CAAUProcessor::DoInitialisation (const CAStreamBasicDescription &inInputFormat,
+ const CAStreamBasicDescription &inOutputFormat,
+ UInt64 inNumInputSamples,
+ UInt32 inMaxFrames)
+{
+ OSStatus result;
+
+ if (inNumInputSamples == 0 && IsOfflineAU())
+ return kAudioUnitErr_InvalidOfflineRender;
+
+ mNumInputSamples = inNumInputSamples;
+
+ // first check that we can do this number of channels
+ if (mUnit.CanDo (inInputFormat.NumberChannels(), inOutputFormat.NumberChannels()) == false)
+ ca_require_noerr (result = kAudioUnitErr_FailedInitialization, home);
+
+ // just uninitialise the AU as a matter of course
+ ca_require_noerr (result = mUnit.Uninitialize(), home);
+
+ ca_require_noerr (result = mUnit.SetFormat (kAudioUnitScope_Input, 0, inInputFormat), home);
+ ca_require_noerr (result = mUnit.SetFormat (kAudioUnitScope_Output, 0, inOutputFormat), home);
+ ca_require_noerr (result = SetMaxFramesPerRender (inMaxFrames), home);
+
+#if !TARGET_OS_IPHONE
+ // if we're any AU but an offline AU, we should tell it that we've processing offline
+ if (!IsOfflineAU()) {
+ UInt32 isOffline = (IsOfflineContext() ? 1 : 0);
+ // don't care whether this succeeds of fails as many AU's don't care about this
+ // but the ones that do its important that they are told their render context
+ mUnit.SetProperty (kAudioUnitProperty_OfflineRender, kAudioUnitScope_Global, 0, &isOffline, sizeof(isOffline));
+ } else {
+ // tell the offline unit how many input samples we wish to process...
+ mUnit.SetProperty (kAudioUnitOfflineProperty_InputSize,
+ kAudioUnitScope_Global, 0,
+ &mNumInputSamples, sizeof(mNumInputSamples));
+ }
+#endif
+
+ ca_require_noerr (result = mUnit.Initialize(), home);
+
+ ca_require_noerr (result = SetInputCallback (mUnit, mUserCallback), home);
+
+ // finally reset our time stamp
+ // the time stamp we use with the AU Render - only sample count is valid
+ memset (&mRenderTimeStamp, 0, sizeof(mRenderTimeStamp));
+ mRenderTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
+
+ // now, if we're NOT an offline AU, preflighting is not required
+ // if we are an offline AU, we should preflight.. an offline AU will tell us when its preflighting is done
+ mPreflightDone = false;
+
+ if (mPreflightABL) {
+ delete mPreflightABL;
+ mPreflightABL = NULL;
+ }
+
+ mPreflightABL = new AUOutputBL (inOutputFormat);
+
+ mLastPercentReported = 0;
+
+home:
+ return result;
+}
+
+void CAAUProcessor::CalculateRemainderSamples (Float64 inSampleRate)
+{
+ mLatencySamples = 0;
+ mTailSamplesToProcess = 0;
+ mTailSamples = 0;
+ mTailSamplesRemaining = 0;
+ return;
+
+ // nothing to do because we're not processing offline
+ if (IsOfflineContext() == false) return;
+
+ // because an offline unit has some indeterminancy about what it does with the input samples
+ // it is *required* to deal internally with both latency and tail
+ if (!IsOfflineAU())
+ {
+ // when offline we need to deal with both latency and tail
+
+ // if the AU has latency - how many samples at the start will be zero?
+ // we'll end up chucking these away.
+ Float64 renderTimeProps;
+ UInt32 propSize = sizeof (renderTimeProps);
+ OSStatus result = mUnit.GetProperty (kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0,
+ &renderTimeProps, &propSize);
+
+ Float64 latencySamples = 0;
+ if (result == noErr) // we have latency to deal with - its reported in seconds
+ latencySamples = renderTimeProps * inSampleRate;
+
+ // AU tail
+ // if the AU has a tail - we'll pull that many zeroes through at the end to flush
+ // out this tail - think of a decaying digital delay or reverb...
+ result = mUnit.GetProperty (kAudioUnitProperty_TailTime, kAudioUnitScope_Global, 0,
+ &renderTimeProps, &propSize);
+ if (renderTimeProps > mMaxTailTime)
+ renderTimeProps = mMaxTailTime;
+ Float64 tailSamples = 0;
+ if (result == noErr)
+ tailSamples = renderTimeProps * inSampleRate;
+
+ // this dictates how many samples at the end we need to pull through...
+ // we add latency to tail because we throw the latency samples away from the start of the rendering
+ // and we have to pull that many samples after the end of course to get the last of the original data
+ // then to that is added the tail of the effect...
+ mTailSamplesToProcess = UInt32(tailSamples + latencySamples);
+ mTailSamples = UInt32(tailSamples);
+ mLatencySamples = UInt32(latencySamples);
+ }
+}
+
+#if !TARGET_OS_IPHONE
+CFStringRef CAAUProcessor::GetOLPreflightName () const
+{
+ if (OfflineAUNeedsPreflight())
+ {
+ CFStringRef str;
+ UInt32 size = sizeof(str);
+ OSStatus result = mUnit.GetProperty (kAudioUnitOfflineProperty_PreflightName,
+ kAudioUnitScope_Global, 0,
+ &str, &size);
+ return result ? NULL : str;
+ }
+ return NULL; // says NO to preflighting
+}
+
+bool CAAUProcessor::OfflineAUNeedsPreflight () const
+{
+ if (IsOfflineAU()) {
+ UInt32 preflightRequirements;
+ UInt32 size = sizeof(preflightRequirements);
+ OSStatus result = mUnit.GetProperty (kAudioUnitOfflineProperty_PreflightRequirements,
+ kAudioUnitScope_Global, 0,
+ &preflightRequirements, &size);
+ if (result)
+ return false;
+ return preflightRequirements;
+ }
+ return false;
+}
+#endif
+
+OSStatus CAAUProcessor::Preflight (bool inProcessPreceedingTail)
+{
+ printf(">>>>CAAUProcessor::Preflight\n");
+ //we're preflighting again, so reset ourselves
+ if (mPreflightDone) {
+ mPreflightDone = false;
+ // the time stamp we use with the AU Render - only sample count is valid
+ memset (&mRenderTimeStamp, 0, sizeof(mRenderTimeStamp));
+ mRenderTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
+ mUnit.GlobalReset();
+ }
+
+ Float64 sampleRate;
+ OSStatus result = mUnit.GetSampleRate (kAudioUnitScope_Output, 0, sampleRate);
+ CalculateRemainderSamples (sampleRate);
+
+ UInt32 numFrames = MaxFramesPerRender();
+ if (numFrames == 0)
+ return kAudioUnitErr_InvalidProperty;
+
+ if (!IsOfflineAU())
+ {
+ if ((IsOfflineContext() == false && inProcessPreceedingTail) || IsOfflineContext())
+ {
+ // re-establish the user's input callback
+ ca_require_noerr (result = SetInputCallback (mUnit, mUserCallback), home);
+
+ // Consume the number of input samples indicated by the AU's latency or tail
+ // based on whether the AU is being used in an offline context or not.
+
+ UInt32 latSamps = IsOfflineContext() ? mLatencySamples : mTailSamples;
+ printf("latSamps %d\n", (int)latSamps);
+ latSamps = 0;
+ while (latSamps > 0)
+ {
+ if (latSamps < numFrames)
+ numFrames = latSamps;
+
+ // process the samples (the unit's input callback will read the samples
+ // from the file and convert them to float for processing
+ AudioUnitRenderActionFlags renderFlags = 0;
+ mPreflightABL->Prepare();
+ result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, numFrames, mPreflightABL->ABL());
+ if (result) { printf("B result %d\n", (int)result); goto home; }
+
+ mRenderTimeStamp.mSampleTime += numFrames;
+ latSamps -= numFrames;
+ }
+ if (IsOfflineContext())
+ mRenderTimeStamp.mSampleTime = mLatencySamples;
+ }
+ else
+ {
+ // processing real-time but not processing preceeding tail, so we should preroll the AU
+ ca_require_noerr (result = Preroll(mUnit, numFrames), home);
+
+ // re-establish the user's input callback
+ ca_require_noerr (result = SetInputCallback (mUnit, mUserCallback), home);
+
+ mRenderTimeStamp.mSampleTime = 0;
+ }
+ }
+#if !TARGET_OS_IPHONE
+ else
+ {
+ // re-establish the user's input callback
+ ca_require_noerr (result = SetInputCallback (mUnit, mUserCallback), home);
+
+ UInt32 preflightRequirements;
+ UInt32 size; size = sizeof(preflightRequirements);
+ ca_require_noerr (result = mUnit.GetProperty (kAudioUnitOfflineProperty_PreflightRequirements,
+ kAudioUnitScope_Global, 0,
+ &preflightRequirements, &size), home);
+
+ // 0 indicates none, otherwise optional or required -> we do it for either
+ if (preflightRequirements)
+ {
+ for (;;) {
+ // here we need to do the preflight loop - we don't expect any data back, but have to
+ // give the offline unit all of its input data to allow it to prepare its processing
+ AudioUnitRenderActionFlags renderFlags = kAudioOfflineUnitRenderAction_Preflight;
+ mPreflightABL->Prepare();
+ result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, numFrames, mPreflightABL->ABL());
+ if (result) { printf("C result %d\n", (int)result); goto home; }
+ mRenderTimeStamp.mSampleTime += numFrames;
+
+ if (renderFlags & kAudioOfflineUnitRenderAction_Complete)
+ break;
+ }
+ }
+ // the time stamp we use with the AU Render - only sample count is valid
+ mRenderTimeStamp.mSampleTime = 0;
+ }
+#endif
+
+ if (result == noErr) {
+ mPreflightDone = true;
+ }
+
+home:
+ printf("<<<<CAAUProcessor::Preflight\n");
+ return result;
+}
+
+#if !TARGET_OS_IPHONE
+OSStatus CAAUProcessor::OfflineAUPreflight (UInt32 inNumFrames, bool &outIsDone)
+{
+ if (!IsOfflineAU())
+ return -50/*paramErr*/;
+ if (mNumInputSamples == 0)
+ return -50/*paramErr*/;
+
+ UInt32 preflightRequirements;
+ UInt32 size = sizeof(preflightRequirements);
+ OSStatus result;
+ ca_require_noerr (result = mUnit.GetProperty (kAudioUnitOfflineProperty_PreflightRequirements,
+ kAudioUnitScope_Global, 0,
+ &preflightRequirements, &size), home);
+
+ // 0 indicates none, otherwise optional or required -> we do it for either
+ if (preflightRequirements)
+ {
+ AudioUnitRenderActionFlags renderFlags = kAudioOfflineUnitRenderAction_Preflight;
+ mPreflightABL->Prepare();
+ result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, inNumFrames, mPreflightABL->ABL());
+ if (result) { printf("D result %d\n", (int)result); goto home; }
+ mRenderTimeStamp.mSampleTime += inNumFrames;
+
+ if (renderFlags & kAudioOfflineUnitRenderAction_Complete) {
+ outIsDone = true;
+ mRenderTimeStamp.mSampleTime = 0;
+ mPreflightDone = true;
+ mLastPercentReported = 0;
+ }
+ }
+ else
+ {
+ outIsDone = true;
+ mRenderTimeStamp.mSampleTime = 0;
+ mPreflightDone = true;
+ mLastPercentReported = 0;
+ }
+
+home:
+ return result;
+}
+#endif
+
+void SetBufferListToNumFrames (AudioBufferList &list, UInt32 inNumFrames)
+{
+ for (unsigned int i = 0; i < list.mNumberBuffers; ++i) {
+ AudioBuffer &buf = list.mBuffers[i];
+ if (buf.mDataByteSize > 0)
+ buf.mDataByteSize = inNumFrames * sizeof (Float32);
+ }
+}
+
+OSStatus CAAUProcessor::Render (AudioBufferList *ioData,
+ UInt32 &ioNumFrames,
+ bool &outIsSilence,
+ bool *outOLCompleted,
+ bool *outOLRequiresPostProcess)
+{
+ if (IsOfflineContext())
+ {
+ if (!mPreflightDone)
+ return kAudioUnitErr_InvalidOfflineRender;
+
+ // YES - this is correct!!! you have to provide both if rendering in an offline Context
+ *outOLCompleted = false;
+ *outOLRequiresPostProcess = false;
+
+ if (!IsOfflineAU() && !mUnit.Comp().Desc().IsFConv())
+ {
+ // have we processed the input we expect too?
+ // in an offline case, we want to create output that matches the input
+ // for an OfflineAU type, it manages this internally, so we don't have to do anything
+ // for a FormatConverter AU, we don't know and can't tell, so we can't do anything here
+ // for any other AU type (effect, instrument) the Prime assumption is that it will
+ // ask for the same number of frames of input as it is asked to output
+ // so we can ask what it is doing, and get a sample accurate output (which is input + tail time)
+ if (mRenderTimeStamp.mSampleTime + ioNumFrames >= InputSampleCount())
+ {
+ // if we fall into here, we have just a partial number of input samples left
+ // (less input less than what we've been asked to produce output for.
+ *outOLCompleted = true;
+ // we require post processing if we've got some tail (or latency) samples to flush through
+ *outOLRequiresPostProcess = mTailSamplesToProcess > 0;
+ if (InputSampleCount() > mRenderTimeStamp.mSampleTime) {
+ ioNumFrames = (UInt32)(InputSampleCount() - mRenderTimeStamp.mSampleTime);
+ } else {
+ ioNumFrames = 0;
+ }
+ mTailSamplesRemaining = mTailSamplesToProcess;
+ // we've got no input samples to process this time.
+ SetBufferListToNumFrames (*ioData, ioNumFrames);
+ if (ioNumFrames == 0) {
+ if (*outOLRequiresPostProcess)
+ SetInputCallback (mUnit, sSilentCallback);
+ else
+ mUnit.GlobalReset (); //flush this out, as we're done with this phase
+ return noErr;
+ }
+ }
+ }
+ AudioUnitRenderActionFlags renderFlags = IsOfflineAU() ? kAudioOfflineUnitRenderAction_Render : 0;
+ OSStatus result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, ioNumFrames, ioData);
+ if (result) { printf("E result %d\n", (int)result); }
+ if (result) {
+ if (mUnit.Comp().Desc().IsFConv()) {
+ // this is the only way we can tell we're done with a FormatConverter AU
+ // - ie. client returns an error from input
+ result = noErr;
+ *outOLCompleted = true;
+ *outOLRequiresPostProcess = mTailSamplesToProcess > 0;
+ ioNumFrames = 0;
+ SetBufferListToNumFrames (*ioData, ioNumFrames);
+ } else
+ return result;
+ }
+// for (UInt32 i = 0; i < ioNumFrames; ++i) {
+// union {
+// float f;
+// unsigned char c[4];
+// } u;
+// u.f = ((float*)(ioData->mBuffers[0].mData))[i];
+// printf("aup out %4d %14.10f %02X %02X %02X %02X\n", (int)i, u.f, u.c[0], u.c[1], u.c[2], u.c[3]);
+// }
+ mRenderTimeStamp.mSampleTime += ioNumFrames;
+ outIsSilence = (renderFlags & kAudioUnitRenderAction_OutputIsSilence);
+
+ // if we're an Offline AU type, it will set this flag on completion of its processing
+ if (renderFlags & kAudioOfflineUnitRenderAction_Complete) {
+ // we now need to calculate how many frames we rendered.
+ // as we're dealing with PCM non-interleaved buffers, we can calculate the numFrames simply
+ ioNumFrames = ioData->mBuffers[0].mDataByteSize / sizeof(Float32);
+ *outOLCompleted = true;
+ *outOLRequiresPostProcess = false;
+ mUnit.GlobalReset (); //flush this out, as we're done with this phase
+ } else {
+ if (*outOLCompleted) {
+ if (*outOLRequiresPostProcess)
+ result = SetInputCallback (mUnit, sSilentCallback);
+ else
+ mUnit.GlobalReset (); //flush this out, as we're done with this phase
+ }
+ }
+
+ return result;
+ }
+
+// rendering in a RT context:
+ AudioUnitRenderActionFlags renderFlags = 0;
+ OSStatus result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, ioNumFrames, ioData);
+ if (result) { printf("F result %d\n", (int)result); }
+ if (!result) {
+ mRenderTimeStamp.mSampleTime += ioNumFrames;
+ outIsSilence = (renderFlags & kAudioUnitRenderAction_OutputIsSilence);
+ }
+// for (UInt32 i = 0; i < ioNumFrames; ++i) {
+// union {
+// float f;
+// unsigned char c[4];
+// } u;
+// u.f = ((float*)(ioData->mBuffers[0].mData))[i];
+// printf("aup out %4d %14.10f %02X %02X %02X %02X\n", (int)i, u.f, u.c[0], u.c[1], u.c[2], u.c[3]);
+// }
+
+ return result;
+}
+
+OSStatus CAAUProcessor::PostProcess (AudioBufferList *ioData,
+ UInt32 &ioNumFrames,
+ bool &outIsSilence,
+ bool &outDone)
+{
+ if (IsOfflineAU() || !IsOfflineContext())
+ return kAudioUnitErr_CannotDoInCurrentContext;
+
+ outDone = false;
+
+ // we've got less samples to process than we've been asked to process
+ if (mTailSamplesRemaining <= SInt32(ioNumFrames)) {
+ outDone = true;
+ ioNumFrames = mTailSamplesRemaining > 0 ? mTailSamplesRemaining : 0;
+ SetBufferListToNumFrames (*ioData, ioNumFrames);
+ if (ioNumFrames == 0)
+ return noErr;
+ }
+
+ AudioUnitRenderActionFlags renderFlags = 0;
+ OSStatus result;
+ result = mUnit.Render (&renderFlags, &mRenderTimeStamp, 0, ioNumFrames, ioData);
+ if (result) { printf("G result %d\n", (int)result); goto home; }
+ mRenderTimeStamp.mSampleTime += ioNumFrames;
+ mTailSamplesRemaining -= ioNumFrames;
+ outIsSilence = (renderFlags & kAudioUnitRenderAction_OutputIsSilence);
+
+ if (outDone) {
+ ca_require_noerr (result = SetInputCallback (mUnit, mUserCallback), home);
+ mUnit.GlobalReset (); //flush this out, as we're done with this phase
+ }
+home:
+ return result;
+}
+
+#if !TARGET_OS_IPHONE
+Float32 CAAUProcessor::GetOLPercentComplete ()
+{
+ if (!IsOfflineContext())
+ return 0;
+
+ Float32 percentDone = mLastPercentReported;
+
+ if (IsOfflineAU())
+ {
+ // we get the output size every time, as this can change as parameters are changed
+ UInt64 numOutputSamples = mNumInputSamples;
+ UInt32 propSize = sizeof(numOutputSamples);
+ mUnit.GetProperty (kAudioUnitOfflineProperty_OutputSize,
+ kAudioUnitScope_Global, 0, &numOutputSamples, &propSize);
+
+ percentDone = (mRenderTimeStamp.mSampleTime / Float64(numOutputSamples)) * 100.;
+ }
+ else
+ {
+ percentDone = (mRenderTimeStamp.mSampleTime / Float64(mNumInputSamples + mTailSamples)) * 100.;
+ }
+
+ if (percentDone > mLastPercentReported)
+ mLastPercentReported = percentDone;
+
+ return mLastPercentReported;
+}
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.h b/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.h
new file mode 100644
index 0000000000..f0fb34574d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAUProcessor.h
@@ -0,0 +1,293 @@
+/*
+ File: CAAUProcessor.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAUProcessor_h__
+#define __CAAUProcessor_h__
+
+#include <AudioToolbox/AudioToolbox.h>
+#include "CAStreamBasicDescription.h"
+#include "CAAudioUnit.h"
+#include "AUOutputBL.h"
+
+#if TARGET_OS_IPHONE
+ #include <AssertMacros.h>
+#endif
+/*
+ This class wraps an AU (using the CAAudioUnit helper class) to use that AU for processing data
+ It can be used in a RealTime context (rendering data with RT constraints) or in an OffLine context
+ such as using an AU to process data that is stored in a file, and on which there are no
+ RT constraints to be imposed.
+
+ Order of operations:
+ Create an instance
+ Establish an Input Callback
+ Initialize the AU to the audio formats and whether it is going to process in an offline or RT context
+ Preflight
+
+ while (...)
+ Render // based on your calling context
+
+ PostProcess if needed (only in OL case)
+
+ After any initialization, preflighting is required.
+
+ Parameter Values on the AU should be set just before each call to Render. The sampleFrameOffsets
+ supplied when setting those values are an offset into that next render buffer's numFrames.
+
+ RT vs OT is determined by whether the inputSampleCount is set during Initialization, thus
+ this class can move the AU between RT and OL contexts. If you are using an AU of type 'auol'
+ (Offline), then it cannot be used in a RT context.
+
+ The CAAUProcessor will only call your Input Callback for input when it needs valid input.
+ This input callback will contain a sample time that indicates where within your input
+ you should read data from, where after preflighting, the first output data produces is for
+ the output sample count of zero.
+
+ MaxFrames should be set before initialisation (or is also passed in to the Reinitialize API)
+
+ If RT, then PostProcessing will *never* be required, nor will Render ever return an isDone value
+ If OL, then Render will at some point return isDone==true, and then also indicate if PostProcessing is required
+
+ If using a Format Converter AU in offline context, then the only way for it to determine that you've finished
+ is for the Input callback to return an error. This means ultimately, that you'll have potentially longer output
+ than you should have. The only way to manage this is for the caller to know the relationship between
+ input to output samples that will be required, and to call Render for just that amount of output samples
+ then return an error, so the tail and latency can be processed.
+
+ Tail and Latency are *only* calculated at initialisation.. Some AU's may change these properties based on
+ either different presets or parameter settings... Ideally, this class should listen to those properties
+ and recalculate its values based on those changes.
+*/
+
+class CAAUProcessor {
+public:
+ // by default this is set to process offline
+ CAAUProcessor (const CAComponent& inComp);
+ ~CAAUProcessor ();
+
+ CAAudioUnit& AU() { return mUnit; }
+ const CAAudioUnit& AU() const { return mUnit; }
+
+#pragma mark __Setup APIs
+ bool IsOfflineContext () const { return mNumInputSamples != 0; }
+
+ // this contains the callback and client data that the AU
+ // uses to call when it needs input
+ OSStatus EstablishInputCallback (AURenderCallbackStruct &inInputCallback);
+
+ OSStatus SetAUPreset (CFPropertyListRef inPreset);
+ OSStatus SetAUPresetIndex (SInt32 inPresetIndex);
+
+ OSStatus SetParameter (AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames = 0);
+
+ // a result of zero here signifies an error
+ UInt32 MaxFramesPerRender () const;
+
+ // this call can return an error if the AU is initialized - see Reinitialize
+ OSStatus SetMaxFramesPerRender (UInt32 inMaxFrames);
+
+ // Prepares the AU for processing at the specified format
+ // only doing n-n channel processing here.. could extend this for n-m channel processing easily enough
+ // if you are processing using an Offline AU, you HAVE to specify the numInputSamples to process
+ // if you are processing real-time, then inNumInputSamples should be zero
+ OSStatus Initialize (const CAStreamBasicDescription &inIODesc, UInt64 inNumInputSamples = 0)
+ {
+ return Initialize (inIODesc, inIODesc, inNumInputSamples);
+ }
+ OSStatus Initialize (const CAStreamBasicDescription &inInputDesc,
+ const CAStreamBasicDescription &inOutputDesc,
+ UInt64 inNumInputSamples = 0);
+
+ // takes the existing format state of the AU, but resets the AUProcessor so that:
+ // applies an optional new number of max frames
+ // the AUProcessor will have to be Preflighted again after this call
+ // Use this when you want to keep the same formats, same input sample count,
+ // but want to re-initialize the AU to use a new num max frames and prepare it
+ // appropriately...
+ OSStatus Reinitialize (UInt32 inNewMaxFrames);
+
+
+
+#pragma mark __Render APIs
+ // Preflighting - you HAVE to preflight
+ // returns noErr when preflighting is done
+
+ // Offline Context:
+ // Offline AU's require preflighting, even if they will end up doing no work.
+ // In the case where the AU is offline the latency samples are trimmed and not returned
+ // from the consequent Render calls
+
+ // If you are NOT an offline AU then the first time Render is called,
+ // there will need to be some consumption of the input before you will get any valid output data.
+ // This is determined by the value of the AU's reported latency. So, in this case preflight
+ // will consume those initial samples and then return.
+ // Your InputCallback MUST provide the initial data that is to be processed.
+
+ // RealTime Context:
+ // (1 No priming. In this case inProcessPreceedingTail is false (the default) and no
+ // processing is done on the AU. However, because preflight is the first time that Rendering
+ // is called on an AU we can presume that this is outside the context of the processing that
+ // is occuring in the host application. To avoid taking page faults, priming cold memory, etc.
+ // when the AU *is* consequently used to render real data, the AU is prerolled and reset if this is the case.
+
+ // (2) Prime the AU's buffers with input data that preceeds the portion of audio you
+ // want to process. This amount of input data is equivalent to the tail time of the AU
+ // which expresses how long it takes for an sample on input to disappear from the output
+ // (Think of a delay or a reverb)
+ // So, by setting inProcessPreceedingTail to true, the preflight call will consume
+ // the tail time samples of input (which should be valid input BEFORE the data to be processed)
+ // So, your input proc here will HAVE to read samples from the preceeding input. The time
+ // stamps to your input proc in this case can be interpreted as 0 is the start of the preceeding data
+ // and you'll need to read up to the numSamples of tail time of the preceeding data.
+ // It discards the output results of the preflighting. If you don't have any previous data
+ // with which to prepare the AU, then you do NOT need to take this path and can do the step below.
+
+ // In both of these cases the inital latency frames are *not* trimmed from
+ // the output that will be generated by a consequent call to render.
+ OSStatus Preflight (bool inProcessPreceedingTail = false);
+
+ // this can be used with an OfflineAU to do a gradual preflight (so you could for instance,
+ // present a progress indicator. The Preflight call will do it all at once.
+ // If you break out of the preflight before you are done, then you HAVE to reinitialise the AU
+ // before you can either do another preflight or do a render, otherwise the Render call will produce
+ // invalid results.
+ OSStatus OfflineAUPreflight (UInt32 inNumFrames, bool &outIsDone);
+
+ // Here's the major stage that produces output.
+ // You pass in two bool flags and an ioNumFrames....
+
+ // So ioNumFrames will be *untouched* if outOLCompleted == false
+ // if outOLCompleted is true, ioNumFrames contains the number of valid frames within the ioData data that are valid data
+ // (ioData's pointers and sizes will also have been resized to match these number of frames)
+ // outOLRequiresPostProcess should also be checked when outOLCompleted is true,
+ // to see if any post-processing is required
+ // if rendering in a RT context, then neither outOLCompleted or outOLRequiresPostProcess is required
+ // if rendering in an OL context, both must be specified.
+ // Caller MUST provide an ABL that is set up in the previously specified output format
+
+ // If you receive kAudioUnitErr_InvalidOfflineRender when dealing with an OfflineAU Type, then you have either not
+ // preflighted it (and the AU requires it) or you have changed some state (its num input samples, its start offest)
+ // and it needs to be re-preflighted. In that case, preflight the AU again first.
+ OSStatus Render (AudioBufferList *ioData,
+ UInt32 &ioNumFrames,
+ bool &outIsSilence,
+ bool *outOLCompleted = NULL,
+ bool *outOLRequiresPostProcess = NULL);
+
+ // call this method if outOLRequiresPostProcess returned true upon rendering completion
+ OSStatus PostProcess (AudioBufferList *ioData, UInt32 &ioNumFrames, bool &outIsSilence, bool &outDone);
+
+ // This method returns how many input samples will need to be provided before
+ // valid output data is produced.
+ UInt32 LatencySampleCount () const { return mLatencySamples; }
+
+ UInt32 TailSampleCount () const { return mTailSamples; }
+
+ UInt64 InputSampleCount () const { return mNumInputSamples; }
+
+ // the class maintains the TimeStamp from render call to render call
+ // this value is the sample count that will be used in the *next* render call
+ Float64 SampleTime () const { return mRenderTimeStamp.mSampleTime; }
+
+ // in some settings (for instance a delay with 100% feedback) tail time is essentially infinite
+ // so you should safeguard the final OL render stage (post process) which is aimed at pulling the tail through
+ // default is 10 seconds
+ Float64 GetMaxTailTime () const { return mMaxTailTime; }
+
+ // this ONLY takes affect when you initialise the processor, it doesn't change that AU's tail time,
+ // but just the max amount of time that this object will allow the AU to post-process data
+ // set this to 0, to use the AU's tail time with no adjustment
+ void SetMaxTailTime (Float64 inTailTimeSecs) { mMaxTailTime = inTailTimeSecs; }
+
+#if !TARGET_OS_IPHONE
+ // if this is NULL, then there is no explicit (optional or required) preflight requirement of the AU
+ // if this is valid, then the AU either requires or optionally requires preflighting. The default
+ // behaviour in this case is that the processor will preflight. This name can be used to preset
+ // to the user. If the AU doesn't present a name, but preflighting is optional/required, then the
+ // processor return "Preflight" as its string.
+ // the String should be released by the caller.
+ CFStringRef GetOLPreflightName () const;
+
+ // Returns true if this is processor is an offline AU, and that AU (whether optional or required)
+ // needs preflighting
+ bool OfflineAUNeedsPreflight () const;
+
+ // this provides a rough approximation of the progress of an Offline Processing operation (both for the
+ // preflight and the render phases)
+ Float32 GetOLPercentComplete ();
+#endif
+
+private:
+ CAAudioUnit mUnit;
+ UInt32 mLatencySamples;
+ UInt32 mTailSamples;
+ UInt32 mTailSamplesToProcess;
+ UInt64 mNumInputSamples;
+ AudioTimeStamp mRenderTimeStamp;
+ bool mPreflightDone;
+ AUOutputBL * mPreflightABL;
+ SInt32 mTailSamplesRemaining;
+ AURenderCallbackStruct mUserCallback;
+ Float64 mMaxTailTime;
+ Float32 mLastPercentReported;
+
+ bool IsOfflineAU () const { return mUnit.Comp().Desc().IsOffline(); }
+
+ void CalculateRemainderSamples (Float64 inSampleRate);
+
+ OSStatus DoInitialisation (const CAStreamBasicDescription &inInputFormat,
+ const CAStreamBasicDescription &inOutputFormat,
+ UInt64 inNumInputSamples,
+ UInt32 inMaxFrames);
+
+ // stop automatic copying of this object
+ CAAUProcessor () {}
+ CAAUProcessor (const CAAUProcessor &c) {}
+ CAAUProcessor& operator= (const CAAUProcessor& c) { return *this; }
+};
+
+#endif //__CAAUProcessor_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAtomic.h b/libs/appleutility/CoreAudio/PublicUtility/CAAtomic.h
new file mode 100644
index 0000000000..c9a611bf7a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAtomic.h
@@ -0,0 +1,305 @@
+/*
+ File: CAAtomic.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+/*
+ This file implements all Atomic operations using Interlocked functions specified in
+ Winbase.h
+NOTE: According to Microsoft documentation, all Interlocked functions generates a
+full barrier.
+ On Windows:
+ As the Interlocked functions returns the Old value, Extra checks and operations
+ are made after the atomic operation to return value consistent with OSX counterparts.
+*/
+#ifndef __CAAtomic_h__
+#define __CAAtomic_h__
+
+#if TARGET_OS_WIN32
+ #include <windows.h>
+ #include <intrin.h>
+ #pragma intrinsic(_InterlockedOr)
+ #pragma intrinsic(_InterlockedAnd)
+#else
+ #include <CoreFoundation/CFBase.h>
+ #include <libkern/OSAtomic.h>
+#endif
+
+inline void CAMemoryBarrier()
+{
+#if TARGET_OS_WIN32
+ MemoryBarrier();
+#else
+ OSMemoryBarrier();
+#endif
+}
+
+inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt);
+ // InterlockedExchangeAdd returns the original value which differs from OSX version.
+ // At this point the addition would have occured and hence returning the new value
+ // to keep it sync with OSX.
+ return lRetVal + theAmt;
+#else
+ return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ // InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
+ // function instead.
+ long j = _InterlockedOr((volatile long*)theValue, theMask);
+ // _InterlockedOr returns the original value which differs from OSX version.
+ // Returning the new value similar to OSX
+ return (SInt32)(j | theMask);
+#else
+ return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue)
+{
+#if TARGET_OS_WIN32
+// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
+// function instead.
+ long j = _InterlockedAnd((volatile long*)theValue, theMask);
+ // _InterlockedAnd returns the original value which differs from OSX version.
+ // Returning the new value similar to OSX
+ return (SInt32)(j & theMask);
+#else
+ return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue);
+#endif
+}
+
+inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue)
+{
+#if TARGET_OS_WIN32
+ // InterlockedCompareExchange returns the old value. But we need to return bool value.
+ long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue);
+// Hence we check if the new value is set and if it is we return true else false.
+// If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen.
+ return (oldValue == lRetVal);
+#else
+ return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue);
+#endif
+}
+
+
+inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ return (SInt32)InterlockedIncrement((volatile long*)theValue);
+#else
+ return OSAtomicIncrement32((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ return (SInt32)InterlockedDecrement((volatile long*)theValue);
+#else
+ return OSAtomicDecrement32((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ return CAAtomicIncrement32(theValue);
+#else
+ return OSAtomicIncrement32Barrier((volatile int32_t *)theValue);
+#endif
+}
+
+inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue)
+{
+#if TARGET_OS_WIN32
+ return CAAtomicDecrement32(theValue);
+#else
+ return OSAtomicDecrement32Barrier((volatile int32_t *)theValue);
+#endif
+}
+
+inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress)
+{
+#if TARGET_OS_WIN32
+ BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear);
+ return (bOldVal ? true : false);
+#else
+ return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress);
+#endif
+}
+
+inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress)
+{
+#if TARGET_OS_WIN32
+ BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress);
+ return (bOldVal ? true : false);
+#else
+ return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress);
+#endif
+}
+
+inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
+{
+#if TARGET_OS_WIN32
+ BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet);
+ return (bOldVal ? true : false);
+#else
+ return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
+#endif
+}
+
+// int32_t flavors -- for C++ only since we can't overload in C
+// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
+// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
+// SInt32 is defined as signed long so this would work there.
+// So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included.
+#if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__
+inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue)
+{
+ return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue)
+{
+ return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue);
+}
+
+inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue)
+{
+ return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue);
+}
+
+inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue)
+{
+ return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicIncrement32(volatile int32_t* theValue)
+{
+ return CAAtomicIncrement32((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicDecrement32(volatile int32_t* theValue)
+{
+ return CAAtomicDecrement32((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue)
+{
+ return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue);
+}
+
+inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
+{
+ return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue);
+}
+#endif // __cplusplus && !__LP64__
+
+#if __LP64__
+inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
+{
+ return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue);
+}
+#endif
+
+inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue)
+{
+#if __LP64__
+ return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue);
+#else
+ return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
+#endif
+}
+
+/* Spinlocks. These use memory barriers as required to synchronize access to shared
+ * memory protected by the lock. The lock operation spins, but employs various strategies
+ * to back off if the lock is held, making it immune to most priority-inversion livelocks.
+ * The try operation immediately returns false if the lock was held, true if it took the
+ * lock. The convention is that unlocked is zero, locked is nonzero.
+ */
+#define CA_SPINLOCK_INIT 0
+
+typedef int32_t CASpinLock;
+
+bool CASpinLockTry( volatile CASpinLock *__lock );
+void CASpinLockLock( volatile CASpinLock *__lock );
+void CASpinLockUnlock( volatile CASpinLock *__lock );
+
+inline void CASpinLockLock( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+ OSSpinLockLock(__lock);
+#else
+ while (CAAtomicTestAndSetBarrier(0, (void*)__lock))
+ usleep(1000); // ???
+#endif
+}
+
+inline void CASpinLockUnlock( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+ OSSpinLockUnlock(__lock);
+#else
+ CAAtomicTestAndClearBarrier(0, (void*)__lock);
+#endif
+}
+
+inline bool CASpinLockTry( volatile CASpinLock *__lock )
+{
+#if TARGET_OS_MAC
+ return OSSpinLockTry(__lock);
+#else
+ return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0);
+#endif
+}
+
+
+#endif // __CAAtomic_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAtomicStack.h b/libs/appleutility/CoreAudio/PublicUtility/CAAtomicStack.h
new file mode 100644
index 0000000000..8d40fc5d27
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAtomicStack.h
@@ -0,0 +1,239 @@
+/*
+ File: CAAtomicStack.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAtomicStack_h__
+#define __CAAtomicStack_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <libkern/OSAtomic.h>
+#else
+ #include <CAAtomic.h>
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+ #include <CoreServices/CoreServices.h>
+#endif
+
+// linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically
+// class T must implement T *& next().
+template <class T>
+class TAtomicStack {
+public:
+ TAtomicStack() : mHead(NULL) { }
+
+ // non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
+ void push_NA(T *item)
+ {
+ item->next() = mHead;
+ mHead = item;
+ }
+
+ T * pop_NA()
+ {
+ T *result = mHead;
+ if (result)
+ mHead = result->next();
+ return result;
+ }
+
+ bool empty() const { return mHead == NULL; }
+
+ T * head() { return mHead; }
+
+ // atomic routines
+ void push_atomic(T *item)
+ {
+ T *head_;
+ do {
+ head_ = mHead;
+ item->next() = head_;
+ } while (!compare_and_swap(head_, item, &mHead));
+ }
+
+ void push_multiple_atomic(T *item)
+ // pushes entire linked list headed by item
+ {
+ T *head_, *p = item, *tail;
+ // find the last one -- when done, it will be linked to head
+ do {
+ tail = p;
+ p = p->next();
+ } while (p);
+ do {
+ head_ = mHead;
+ tail->next() = head_;
+ } while (!compare_and_swap(head_, item, &mHead));
+ }
+
+ T * pop_atomic_single_reader()
+ // this may only be used when only one thread may potentially pop from the stack.
+ // if multiple threads may pop, this suffers from the ABA problem.
+ // <rdar://problem/4606346> TAtomicStack suffers from the ABA problem
+ {
+ T *result;
+ do {
+ if ((result = mHead) == NULL)
+ break;
+ } while (!compare_and_swap(result, result->next(), &mHead));
+ return result;
+ }
+
+ T * pop_atomic()
+ // This is inefficient for large linked lists.
+ // prefer pop_all() to a series of calls to pop_atomic.
+ // push_multiple_atomic has to traverse the entire list.
+ {
+ T *result = pop_all();
+ if (result) {
+ T *next = result->next();
+ if (next)
+ // push all the remaining items back onto the stack
+ push_multiple_atomic(next);
+ }
+ return result;
+ }
+
+ T * pop_all()
+ {
+ T *result;
+ do {
+ if ((result = mHead) == NULL)
+ break;
+ } while (!compare_and_swap(result, NULL, &mHead));
+ return result;
+ }
+
+ T* pop_all_reversed()
+ {
+ TAtomicStack<T> reversed;
+ T *p = pop_all(), *next;
+ while (p != NULL) {
+ next = p->next();
+ reversed.push_NA(p);
+ p = next;
+ }
+ return reversed.mHead;
+ }
+
+ static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
+ {
+#if TARGET_OS_MAC
+ #if __LP64__
+ return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
+ #elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue);
+ #else
+ return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
+ #endif
+#else
+ //return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
+ return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
+#endif
+ }
+
+protected:
+ T * mHead;
+};
+
+#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32)
+#include <libkern/OSAtomic.h>
+
+class CAAtomicStack {
+public:
+ CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) {
+ /*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
+ mHead.opaque1 = 0; mHead.opaque2 = 0;
+ }
+ // a subset of the above
+ void push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); }
+ void push_NA(void *p) { push_atomic(p); }
+
+ void * pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); }
+ void * pop_atomic_single_reader() { return pop_atomic(); }
+ void * pop_NA() { return pop_atomic(); }
+
+private:
+ OSQueueHead mHead;
+ size_t mNextPtrOffset;
+};
+
+// a more efficient subset of TAtomicStack using OSQueue.
+template <class T>
+class TAtomicStack2 {
+public:
+ TAtomicStack2() {
+ /*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
+ mHead.opaque1 = 0; mHead.opaque2 = 0;
+ mNextPtrOffset = -1;
+ }
+ void push_atomic(T *item) {
+ if (mNextPtrOffset < 0) {
+ T **pnext = &item->next(); // hack around offsetof not working with C++
+ mNextPtrOffset = (Byte *)pnext - (Byte *)item;
+ }
+ OSAtomicEnqueue(&mHead, item, mNextPtrOffset);
+ }
+ void push_NA(T *item) { push_atomic(item); }
+
+ T * pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); }
+ T * pop_atomic_single_reader() { return pop_atomic(); }
+ T * pop_NA() { return pop_atomic(); }
+
+ // caution: do not try to implement pop_all_reversed here. the writer could add new elements
+ // while the reader is trying to pop old ones!
+
+private:
+ OSQueueHead mHead;
+ ssize_t mNextPtrOffset;
+};
+
+#else
+
+#define TAtomicStack2 TAtomicStack
+
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32
+
+#endif // __CAAtomicStack_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.cpp
new file mode 100644
index 0000000000..d3644ed2e4
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.cpp
@@ -0,0 +1,239 @@
+/*
+ File: CAAudioBufferList.cpp
+ Abstract: CAAudioBufferList.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CAAudioBufferList.h"
+#include "CADebugMacros.h"
+#include "CALogMacros.h"
+#include <stdlib.h>
+#include <string.h>
+
+//=============================================================================
+// CAAudioBufferList
+//=============================================================================
+
+AudioBufferList* CAAudioBufferList::Create(UInt32 inNumberBuffers)
+{
+ UInt32 theSize = CalculateByteSize(inNumberBuffers);
+ AudioBufferList* theAnswer = static_cast<AudioBufferList*>(calloc(1, theSize));
+ if(theAnswer != NULL)
+ {
+ theAnswer->mNumberBuffers = inNumberBuffers;
+ }
+ return theAnswer;
+}
+
+void CAAudioBufferList::Destroy(AudioBufferList* inBufferList)
+{
+ free(inBufferList);
+}
+
+UInt32 CAAudioBufferList::CalculateByteSize(UInt32 inNumberBuffers)
+{
+ UInt32 theSize = SizeOf32(AudioBufferList) - SizeOf32(AudioBuffer);
+ theSize += inNumberBuffers * SizeOf32(AudioBuffer);
+ return theSize;
+}
+
+UInt32 CAAudioBufferList::GetTotalNumberChannels(const AudioBufferList& inBufferList)
+{
+ UInt32 theAnswer = 0;
+
+ for(UInt32 theIndex = 0; theIndex < inBufferList.mNumberBuffers; ++theIndex)
+ {
+ theAnswer += inBufferList.mBuffers[theIndex].mNumberChannels;
+ }
+
+ return theAnswer;
+}
+
+bool CAAudioBufferList::GetBufferForChannel(const AudioBufferList& inBufferList, UInt32 inChannel, UInt32& outBufferNumber, UInt32& outBufferChannel)
+{
+ bool theAnswer = false;
+ UInt32 theIndex = 0;
+
+ while((theIndex < inBufferList.mNumberBuffers) && (inChannel >= inBufferList.mBuffers[theIndex].mNumberChannels))
+ {
+ inChannel -= inBufferList.mBuffers[theIndex].mNumberChannels;
+ ++theIndex;
+ }
+
+ if(theIndex < inBufferList.mNumberBuffers)
+ {
+ outBufferNumber = theIndex;
+ outBufferChannel = inChannel;
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
+
+void CAAudioBufferList::Clear(AudioBufferList& outBufferList)
+{
+ // assumes that "0" is actually the 0 value for this stream format
+ for(UInt32 theBufferIndex = 0; theBufferIndex < outBufferList.mNumberBuffers; ++theBufferIndex)
+ {
+ if(outBufferList.mBuffers[theBufferIndex].mData != NULL)
+ {
+ memset(outBufferList.mBuffers[theBufferIndex].mData, 0, outBufferList.mBuffers[theBufferIndex].mDataByteSize);
+ }
+ }
+}
+
+void CAAudioBufferList::Copy(const AudioBufferList& inSource, UInt32 inStartingSourceChannel, AudioBufferList& outDestination, UInt32 inStartingDestinationChannel)
+{
+ // This is a brute force copy method that can handle ABL's that have different buffer layouts
+ // This means that this method is probably not the fastest way to do this for all cases.
+ // This method also assumes that both the source and destination sample formats are Float32
+
+ UInt32 theInputChannel = inStartingSourceChannel;
+ UInt32 theNumberInputChannels = GetTotalNumberChannels(inSource);
+ UInt32 theOutputChannel = inStartingDestinationChannel;
+ UInt32 theNumberOutputChannels = GetTotalNumberChannels(outDestination);
+
+ UInt32 theInputBufferIndex = 0;
+ UInt32 theInputBufferChannel = 0;
+ UInt32 theOutputBufferIndex = 0;
+ UInt32 theOutputBufferChannel = 0;
+ while((theInputChannel < theNumberInputChannels) && (theOutputChannel < theNumberOutputChannels))
+ {
+ GetBufferForChannel(inSource, theInputChannel, theInputBufferIndex, theInputBufferChannel);
+
+ GetBufferForChannel(inSource, theOutputChannel, theOutputBufferIndex, theOutputBufferChannel);
+
+ CopyChannel(inSource.mBuffers[theInputBufferIndex], theInputBufferChannel, outDestination.mBuffers[theOutputBufferIndex], theOutputBufferChannel);
+
+ ++theInputChannel;
+ ++theOutputChannel;
+ }
+}
+
+void CAAudioBufferList::CopyChannel(const AudioBuffer& inSource, UInt32 inSourceChannel, AudioBuffer& outDestination, UInt32 inDestinationChannel)
+{
+ // set up the stuff for the loop
+ UInt32 theNumberFramesToCopy = outDestination.mDataByteSize / (outDestination.mNumberChannels * SizeOf32(Float32));
+ const Float32* theSource = static_cast<const Float32*>(inSource.mData);
+ Float32* theDestination = static_cast<Float32*>(outDestination.mData);
+
+ // loop through the data and copy the samples
+ while(theNumberFramesToCopy > 0)
+ {
+ // copy the data
+ theDestination[inDestinationChannel] = theSource[inSourceChannel];
+
+ // adjust the pointers
+ --theNumberFramesToCopy;
+ theSource += inSource.mNumberChannels;
+ theDestination += outDestination.mNumberChannels;
+ }
+}
+
+void CAAudioBufferList::Sum(const AudioBufferList& inSourceBufferList, AudioBufferList& ioSummedBufferList)
+{
+ // assumes that the buffers are Float32 samples and the listst have the same layout
+ // this is a lame algorithm, by the way. it could at least be unrolled a couple of times
+ for(UInt32 theBufferIndex = 0; theBufferIndex < ioSummedBufferList.mNumberBuffers; ++theBufferIndex)
+ {
+ Float32* theSourceBuffer = static_cast<Float32*>(inSourceBufferList.mBuffers[theBufferIndex].mData);
+ Float32* theSummedBuffer = static_cast<Float32*>(ioSummedBufferList.mBuffers[theBufferIndex].mData);
+ UInt32 theNumberSamplesToMix = ioSummedBufferList.mBuffers[theBufferIndex].mDataByteSize / SizeOf32(Float32);
+ if((theSourceBuffer != NULL) && (theSummedBuffer != NULL) && (theNumberSamplesToMix > 0))
+ {
+ while(theNumberSamplesToMix > 0)
+ {
+ *theSummedBuffer += *theSourceBuffer;
+ ++theSummedBuffer;
+ ++theSourceBuffer;
+ --theNumberSamplesToMix;
+ }
+ }
+ }
+}
+
+bool CAAudioBufferList::HasData(AudioBufferList& inBufferList)
+{
+ bool hasData = false;
+ for(UInt32 theBufferIndex = 0; !hasData && (theBufferIndex < inBufferList.mNumberBuffers); ++theBufferIndex)
+ {
+ if(inBufferList.mBuffers[theBufferIndex].mData != NULL)
+ {
+ UInt32* theBuffer = (UInt32*)inBufferList.mBuffers[theBufferIndex].mData;
+ UInt32 theNumberSamples = inBufferList.mBuffers[theBufferIndex].mDataByteSize / SizeOf32(UInt32);
+ for(UInt32 theSampleIndex = 0; !hasData && (theSampleIndex < theNumberSamples); ++theSampleIndex)
+ {
+ hasData = theBuffer[theSampleIndex] != 0;
+ }
+ }
+ }
+ return hasData;
+}
+
+#if CoreAudio_Debug
+void CAAudioBufferList::PrintToLog(const AudioBufferList& inBufferList)
+{
+ PrintInt(" Number streams: ", inBufferList.mNumberBuffers);
+
+ for(UInt32 theIndex = 0; theIndex < inBufferList.mNumberBuffers; ++theIndex)
+ {
+ PrintIndexedInt(" Channels in stream", theIndex + 1, inBufferList.mBuffers[theIndex].mNumberChannels);
+ PrintIndexedInt(" Buffer size of stream", theIndex + 1, inBufferList.mBuffers[theIndex].mDataByteSize);
+ }
+}
+#endif
+
+const AudioBufferList* CAAudioBufferList::GetEmptyBufferList()
+{
+ static bool sInitializer = false;
+ static AudioBufferList sEmptyABL;
+ if(!sInitializer)
+ {
+ memset(&sEmptyABL, 0, sizeof(AudioBufferList));
+ }
+ return &sEmptyABL;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.h
new file mode 100644
index 0000000000..70614f3eb6
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioBufferList.h
@@ -0,0 +1,108 @@
+/*
+ File: CAAudioBufferList.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAAudioBufferList_h__)
+#define __CAAudioBufferList_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+#include "CAException.h"
+#include "CADebugMacros.h"
+
+//=============================================================================
+// Types
+//=============================================================================
+
+typedef AudioBufferList* AudioBufferListPtr;
+
+//=============================================================================
+// CAAudioBufferList
+//=============================================================================
+
+struct CAAudioBufferList
+{
+
+// Construction/Destruction
+public:
+ static AudioBufferList* Create(UInt32 inNumberBuffers);
+ static void Destroy(AudioBufferList* inBufferList);
+ static UInt32 CalculateByteSize(UInt32 inNumberBuffers);
+
+// Operations
+public:
+ static UInt32 GetTotalNumberChannels(const AudioBufferList& inBufferList);
+ static bool GetBufferForChannel(const AudioBufferList& inBufferList, UInt32 inChannel, UInt32& outBufferNumber, UInt32& outBufferChannel);
+ static void Clear(AudioBufferList& outBufferList);
+ static void Copy(const AudioBufferList& inSource, UInt32 inStartingSourceChannel, AudioBufferList& outDestination, UInt32 inStartingDestinationChannel);
+ static void CopyChannel(const AudioBuffer& inSource, UInt32 inSourceChannel, AudioBuffer& outDestination, UInt32 inDestinationChannel);
+ static void Sum(const AudioBufferList& inSourceBufferList, AudioBufferList& ioSummedBufferList);
+ static bool HasData(AudioBufferList& inBufferList);
+#if CoreAudio_Debug
+ static void PrintToLog(const AudioBufferList& inBufferList);
+#endif
+
+ static const AudioBufferList* GetEmptyBufferList();
+
+};
+
+// Declare a variably-sized AudioBufferList on the stack
+#define STACK_ABL(name, nbufs) \
+ ThrowIf(nbufs < 1 || nbufs > 64, CAException(kAudio_ParamError), "STACK_ABL: invalid number of buffers") \
+ const size_t name##_ByteSize = sizeof(AudioBufferList) + (nbufs - 1) * sizeof(AudioBuffer); \
+ AudioBufferList &name = *(AudioBufferList *)alloca(name##_ByteSize); \
+ name.mNumberBuffers = nbufs;
+
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp
new file mode 100644
index 0000000000..74753598db
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp
@@ -0,0 +1,153 @@
+/*
+ File: CAAudioChannelLayout.cpp
+ Abstract: CAAudioChannelLayout.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CAAudioChannelLayout.h"
+#include "CAAutoDisposer.h"
+#include <stdlib.h>
+#include <string.h>
+
+//=============================================================================
+// CAAudioChannelLayout
+//=============================================================================
+
+AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
+{
+ UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
+ AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(CA_calloc(1, theSize));
+ if(theAnswer != NULL)
+ {
+ SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
+ }
+ return theAnswer;
+}
+
+void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
+{
+ free(inChannelLayout);
+}
+
+void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
+{
+ outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+ outChannelLayout.mChannelBitmap = 0;
+ outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
+ for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
+ {
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
+ }
+}
+
+bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
+{
+ // compare based on the number of channel descriptions present
+ // (this may be too strict a comparison if all you care about are matching layout tags)
+ UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
+ UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
+
+ if (theSize1 != theSize2)
+ return false;
+
+ return !memcmp (&x, &y, theSize1);
+}
+
+bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y)
+{
+ return !(x == y);
+}
+
+// counting the one bits in a word
+inline UInt32 CountOnes(UInt32 x)
+{
+ // secret magic algorithm for counting bits in a word.
+ UInt32 t;
+ x = x - ((x >> 1) & 0x55555555);
+ t = ((x >> 2) & 0x33333333);
+ x = (x & 0x33333333) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x = x + (x << 8);
+ x = x + (x << 16);
+ return x >> 24;
+}
+
+UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
+{
+ if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+ return inLayout.mNumberChannelDescriptions;
+
+ if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+ return CountOnes (inLayout.mChannelBitmap);
+
+ return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
+}
+
+void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
+{
+ if (layout == NULL)
+ {
+ fprintf (file, "\tNULL layout\n");
+ return;
+ }
+ fprintf (file, "\tTag=0x%X, ", (int)layout->mChannelLayoutTag);
+ if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+ fprintf (file, "Using Bitmap:0x%X\n", (int)layout->mChannelBitmap);
+ else {
+ fprintf (file, "Num Chan Descs=%d\n", (int)layout->mNumberChannelDescriptions);
+ const AudioChannelDescription *desc = layout->mChannelDescriptions;
+ for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
+ fprintf (file, "\t\tLabel=%d, Flags=0x%X, ", (int)desc->mChannelLabel, (int)desc->mChannelFlags);
+ fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
+ }
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.h
new file mode 100644
index 0000000000..4307054aee
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayout.h
@@ -0,0 +1,199 @@
+/*
+ File: CAAudioChannelLayout.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAAudioChannelLayout_h__)
+#define __CAAudioChannelLayout_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CoreFoundation.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CADebugMacros.h"
+#include "CAAutoDisposer.h"
+
+#if !HAL_Build
+ #include "CAReferenceCounted.h"
+#endif
+
+//=============================================================================
+// CAAudioChannelLayout
+//=============================================================================
+
+bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
+bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y);
+
+extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
+
+class CAAudioChannelLayout
+{
+// static Construction/Destruction
+public:
+ static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
+ static void Destroy(AudioChannelLayout* inChannelLayout);
+ static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
+ return SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription) + (inNumberChannelDescriptions * SizeOf32(AudioChannelDescription));
+ }
+ static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
+ static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
+
+#if !HAL_Build
+// object methods
+public:
+ CAAudioChannelLayout ();
+
+ CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+ // if inChooseSurround is false, then symmetrical speaker arrangements
+ // are chosen in place of surround layouts if there is a choice
+ // This call chooses layouts based on the expected defaults in
+ // AudioUnit usage
+ CAAudioChannelLayout (AudioChannelLayoutTag inTag);
+ CAAudioChannelLayout (const CAAudioChannelLayout &c);
+ CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
+ ~CAAudioChannelLayout();
+
+ CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
+ CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
+ bool operator== (const CAAudioChannelLayout &c) const;
+ bool operator!= (const CAAudioChannelLayout &c) const;
+
+ void SetWithTag(AudioChannelLayoutTag inTag);
+
+ bool IsValid() const { return NumberChannels() > 0; }
+ UInt32 Size() const { return mLayout ? mLayout->Size() : 0; }
+
+ UInt32 NumberChannels() const { return mLayout ? mLayout->NumberChannels() : 0; }
+
+ AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
+ const AudioChannelLayout& Layout() const { return mLayout->Layout(); }
+ operator const AudioChannelLayout *() const { return &Layout(); }
+
+ void Print () const { Print (stdout); }
+ void Print (FILE* file) const;
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ class RefCountedLayout : public CAReferenceCounted {
+ void * operator new(size_t /* size */, size_t aclSize)
+ {
+ return CA_malloc(sizeof(RefCountedLayout) - sizeof(AudioChannelLayout) + aclSize);
+ }
+
+ void operator delete(void *mem)
+ {
+ free(mem);
+ }
+
+
+ RefCountedLayout(UInt32 inDataSize) :
+ mByteSize(inDataSize)
+ {
+ memset(&mACL, 0, inDataSize);
+ }
+
+ public:
+ static RefCountedLayout *CreateWithNumberChannelDescriptions(unsigned nChannels) {
+ size_t size = CAAudioChannelLayout::CalculateByteSize(nChannels);
+ return new(size) RefCountedLayout((UInt32)size);
+ }
+
+ static RefCountedLayout *CreateWithLayout(const AudioChannelLayout *layout) {
+ size_t size = CAAudioChannelLayout::CalculateByteSize(layout->mNumberChannelDescriptions);
+ RefCountedLayout *acl = new(size) RefCountedLayout((UInt32)size);
+ memcpy(&acl->mACL, layout, size);
+ return acl;
+ }
+ static RefCountedLayout *CreateWithLayoutTag(AudioChannelLayoutTag layoutTag) {
+ RefCountedLayout *acl = CreateWithNumberChannelDescriptions(0);
+ acl->mACL.mChannelLayoutTag = layoutTag;
+ return acl;
+ }
+
+ const AudioChannelLayout & Layout() const { return mACL; }
+
+ UInt32 Size () const { return mByteSize; }
+
+ UInt32 NumberChannels() { return CAAudioChannelLayout::NumberChannels(Layout()); }
+
+ private:
+ const UInt32 mByteSize;
+ AudioChannelLayout mACL;
+ // * * * mACL is variable length and thus must be last * * *
+
+ // only the constructors can change the actual state of the layout
+ friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+ friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
+ friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
+ friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
+
+ AudioChannelLayout * GetLayout() { return &mACL; }
+
+ private:
+ // prohibited methods: private and unimplemented.
+ RefCountedLayout();
+ RefCountedLayout(const RefCountedLayout& c);
+ RefCountedLayout& operator=(const RefCountedLayout& c);
+ };
+
+ RefCountedLayout *mLayout;
+#endif // HAL_Build
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayoutObject.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayoutObject.cpp
new file mode 100644
index 0000000000..009d4b3b5e
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioChannelLayoutObject.cpp
@@ -0,0 +1,210 @@
+/*
+ File: CAAudioChannelLayoutObject.cpp
+ Abstract: CAAudioChannelLayoutObject.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAudioChannelLayout.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioToolbox/AudioFormat.h>
+#else
+ #include <AudioFormat.h>
+#endif
+
+CAAudioChannelLayout::CAAudioChannelLayout ()
+{
+ mLayout = RefCountedLayout::CreateWithNumberChannelDescriptions(0);
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround)
+{
+ // this chooses default layouts based on the number of channels...
+ AudioChannelLayoutTag tag;
+
+ switch (inNumberChannels)
+ {
+ default:
+ // here we have a "broken" layout, in the sense that we haven't any idea how to lay this out
+ mLayout = RefCountedLayout::CreateWithNumberChannelDescriptions(inNumberChannels);
+ SetAllToUnknown(*mLayout->GetLayout(), inNumberChannels);
+ return; // don't fall into the tag case
+ case 1:
+ tag = kAudioChannelLayoutTag_Mono;
+ break;
+ case 2:
+ tag = inChooseSurround ? kAudioChannelLayoutTag_Binaural : kAudioChannelLayoutTag_Stereo;
+ break;
+ case 4:
+ tag = inChooseSurround ? kAudioChannelLayoutTag_Ambisonic_B_Format : kAudioChannelLayoutTag_AudioUnit_4;
+ break;
+ case 5:
+ tag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_5_0 : kAudioChannelLayoutTag_AudioUnit_5;
+ break;
+ case 6:
+ tag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_6_0 : kAudioChannelLayoutTag_AudioUnit_6;
+ break;
+ case 7:
+ tag = kAudioChannelLayoutTag_AudioUnit_7_0;
+ break;
+ case 8:
+ tag = kAudioChannelLayoutTag_AudioUnit_8;
+ break;
+ }
+
+ mLayout = RefCountedLayout::CreateWithLayoutTag(tag);
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (AudioChannelLayoutTag inLayoutTag)
+ : mLayout(NULL)
+{
+ SetWithTag(inLayoutTag);
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (const CAAudioChannelLayout &c)
+ : mLayout(NULL)
+{
+ *this = c;
+}
+
+
+//=============================================================================
+// CAAudioChannelLayout::AudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout)
+ : mLayout(NULL)
+{
+ *this = inChannelLayout;
+}
+
+//=============================================================================
+// CAAudioChannelLayout::~CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::~CAAudioChannelLayout ()
+{
+ if (mLayout) {
+ mLayout->release();
+ mLayout = NULL;
+ }
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout& CAAudioChannelLayout::operator= (const CAAudioChannelLayout &c)
+{
+ if (mLayout != c.mLayout) {
+ if (mLayout)
+ mLayout->release();
+
+ if ((mLayout = c.mLayout) != NULL)
+ mLayout->retain();
+ }
+
+ return *this;
+}
+
+CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout)
+{
+ if (mLayout && &mLayout->Layout() == inChannelLayout)
+ return *this;
+
+ if (mLayout)
+ mLayout->release();
+
+ if (inChannelLayout == NULL)
+ {
+ mLayout = RefCountedLayout::CreateWithNumberChannelDescriptions(0);
+ }
+ else
+ {
+ mLayout = RefCountedLayout::CreateWithLayout(inChannelLayout);
+ }
+ return *this;
+}
+
+void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag)
+{
+ if (mLayout)
+ mLayout->release();
+
+ mLayout = RefCountedLayout::CreateWithLayoutTag(inTag);
+}
+
+//=============================================================================
+// CAAudioChannelLayout::operator==
+//=============================================================================
+bool CAAudioChannelLayout::operator== (const CAAudioChannelLayout &c) const
+{
+ if (mLayout == c.mLayout)
+ return true;
+ return Layout() == c.Layout();
+}
+
+//=============================================================================
+// CAAudioChannelLayout::operator!=
+//=============================================================================
+bool CAAudioChannelLayout::operator!= (const CAAudioChannelLayout &c) const
+{
+ if (mLayout == c.mLayout)
+ return false;
+
+ return !(Layout() == c.Layout());
+}
+
+//=============================================================================
+// CAAudioChannelLayout::Print
+//=============================================================================
+void CAAudioChannelLayout::Print (FILE* file) const
+{
+ CAShowAudioChannelLayout (file, &Layout());
+}
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.cpp
new file mode 100644
index 0000000000..ce2efeae60
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.cpp
@@ -0,0 +1,424 @@
+/*
+ File: CAAudioFileFormats.cpp
+ Abstract: CAAudioFileFormats.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAudioFileFormats.h"
+#include <algorithm>
+#include <ctype.h>
+
+CAAudioFileFormats *CAAudioFileFormats::sInstance = NULL;
+
+CAAudioFileFormats *CAAudioFileFormats::Instance(bool loadDataFormats)
+{
+ if (sInstance == NULL)
+ sInstance = new CAAudioFileFormats(loadDataFormats);
+ return sInstance;
+}
+
+/*
+class CompareFileFormatNames {
+public:
+ bool operator() (const CAAudioFileFormats::FileFormatInfo &a, const CAAudioFileFormats::FileFormatInfo &b)
+ {
+ return CFStringCompare(a.mFileTypeName, b.mFileTypeName,
+ kCFCompareCaseInsensitive | kCFCompareLocalized) == kCFCompareLessThan;
+ }
+};*/
+
+static int CompareFileFormatNames(const void *va, const void *vb)
+{
+ CAAudioFileFormats::FileFormatInfo *a = (CAAudioFileFormats::FileFormatInfo *)va,
+ *b = (CAAudioFileFormats::FileFormatInfo *)vb;
+ return CFStringCompare(a->mFileTypeName, b->mFileTypeName,
+ kCFCompareCaseInsensitive | kCFCompareLocalized);
+}
+
+CAAudioFileFormats::CAAudioFileFormats(bool loadDataFormats) :
+ mNumFileFormats(0), mFileFormats(NULL)
+{
+ OSStatus err;
+ UInt32 size;
+ UInt32 *fileTypes = NULL;
+
+ // get all file types
+ err = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_WritableTypes, 0, NULL, &size);
+ if (err != noErr) goto bail;
+ mNumFileFormats = size / sizeof(UInt32);
+ mFileFormats = new FileFormatInfo[mNumFileFormats];
+ fileTypes = new UInt32[mNumFileFormats];
+ err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_WritableTypes, 0, NULL, &size, fileTypes);
+ if (err != noErr) goto bail;
+
+ // get info for each file type
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ OSType filetype = fileTypes[i];
+
+ ffi->mFileTypeID = filetype;
+
+ // file type name
+ ffi->mFileTypeName = NULL;
+ size = sizeof(CFStringRef);
+ err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_FileTypeName, sizeof(UInt32), &filetype, &size, &ffi->mFileTypeName);
+ if (err == noErr && ffi->mFileTypeName)
+ CFRetain(ffi->mFileTypeName);
+
+ // file extensions
+ size = sizeof(CFArrayRef);
+ err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_ExtensionsForType,
+ sizeof(OSType), &filetype, &size, &ffi->mExtensions);
+ if (err)
+ ffi->mExtensions = NULL;
+
+ // file data formats
+ ffi->mNumDataFormats = 0;
+ ffi->mDataFormats = NULL;
+
+ if (loadDataFormats)
+ ffi->LoadDataFormats();
+ }
+
+ // sort file formats by name
+ qsort(mFileFormats, mNumFileFormats, sizeof(FileFormatInfo), CompareFileFormatNames);
+bail:
+ delete[] fileTypes;
+}
+
+void CAAudioFileFormats::FileFormatInfo::LoadDataFormats()
+{
+ if (mDataFormats != NULL) return;
+
+ UInt32 *writableFormats = NULL, *readableFormats = NULL;
+ int nWritableFormats, nReadableFormats;
+ // get all writable formats
+ UInt32 size;
+ OSStatus err = AudioFormatGetPropertyInfo(kAudioFormatProperty_EncodeFormatIDs, 0, NULL, &size);
+ if (err != noErr) goto bail;
+ nWritableFormats = size / sizeof(UInt32);
+ writableFormats = new UInt32[nWritableFormats];
+ err = AudioFormatGetProperty(kAudioFormatProperty_EncodeFormatIDs, 0, NULL, &size, writableFormats);
+ if (err != noErr) goto bail;
+
+ // get all readable formats
+ err = AudioFormatGetPropertyInfo(kAudioFormatProperty_DecodeFormatIDs, 0, NULL, &size);
+ if (err != noErr) goto bail;
+ nReadableFormats = size / sizeof(UInt32);
+ readableFormats = new UInt32[nReadableFormats];
+ err = AudioFormatGetProperty(kAudioFormatProperty_DecodeFormatIDs, 0, NULL, &size, readableFormats);
+ if (err != noErr) goto bail;
+
+ err = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_AvailableFormatIDs, sizeof(UInt32), &mFileTypeID, &size);
+ if (err == noErr) {
+ mNumDataFormats = size / sizeof(OSType);
+ OSType *formatIDs = new OSType[mNumDataFormats];
+ err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableFormatIDs,
+ sizeof(UInt32), &mFileTypeID, &size, formatIDs);
+ if (err == noErr) {
+ mDataFormats = new DataFormatInfo[mNumDataFormats];
+ for (int j = 0; j < mNumDataFormats; ++j) {
+ int k;
+ bool anyBigEndian = false, anyLittleEndian = false;
+ DataFormatInfo *dfi = &mDataFormats[j];
+ dfi->mFormatID = formatIDs[j];
+ dfi->mReadable = (dfi->mFormatID == kAudioFormatLinearPCM);
+ dfi->mWritable = (dfi->mFormatID == kAudioFormatLinearPCM);
+ for (k = 0; k < nReadableFormats; ++k)
+ if (readableFormats[k] == dfi->mFormatID) {
+ dfi->mReadable = true;
+ break;
+ }
+ for (k = 0; k < nWritableFormats; ++k)
+ if (writableFormats[k] == dfi->mFormatID) {
+ dfi->mWritable = true;
+ break;
+ }
+
+ dfi->mNumVariants = 0;
+ AudioFileTypeAndFormatID tf = { mFileTypeID, dfi->mFormatID };
+ err = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,
+ sizeof(AudioFileTypeAndFormatID), &tf, &size);
+ if (err == noErr) {
+ dfi->mNumVariants = size / sizeof(AudioStreamBasicDescription);
+ dfi->mVariants = new AudioStreamBasicDescription[dfi->mNumVariants];
+ err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,
+ sizeof(AudioFileTypeAndFormatID), &tf, &size, dfi->mVariants);
+ if (err) {
+ dfi->mNumVariants = 0;
+ delete[] dfi->mVariants;
+ dfi->mVariants = NULL;
+ } else {
+ for (k = 0; k < dfi->mNumVariants; ++k) {
+ AudioStreamBasicDescription *desc = &dfi->mVariants[k];
+ if (desc->mBitsPerChannel > 8) {
+ if (desc->mFormatFlags & kAudioFormatFlagIsBigEndian)
+ anyBigEndian = true;
+ else
+ anyLittleEndian = true;
+ }
+ }
+ }
+ }
+
+ dfi->mEitherEndianPCM = (anyBigEndian && anyLittleEndian);
+ }
+ }
+ delete[] formatIDs;
+ }
+bail:
+ delete[] readableFormats;
+ delete[] writableFormats;
+}
+
+// note that the outgoing format will have zero for the sample rate, channels per frame, bytesPerPacket, bytesPerFrame
+bool CAAudioFileFormats::InferDataFormatFromFileFormat(AudioFileTypeID filetype, CAStreamBasicDescription &fmt)
+{
+ // if the file format only supports one data format
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ ffi->LoadDataFormats();
+ if (ffi->mFileTypeID == filetype && ffi->mNumDataFormats > 0) {
+ DataFormatInfo *dfi = &ffi->mDataFormats[0];
+ if (ffi->mNumDataFormats > 1) {
+ // file can contain multiple data formats. Take PCM if it's there.
+ for (int j = 0; j < ffi->mNumDataFormats; ++j) {
+ if (ffi->mDataFormats[j].mFormatID == kAudioFormatLinearPCM) {
+ dfi = &ffi->mDataFormats[j];
+ break;
+ }
+ }
+ }
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.mFormatID = dfi->mFormatID;
+ if (dfi->mNumVariants > 0) {
+ // take the first variant as a default
+ fmt = dfi->mVariants[0];
+ if (dfi->mNumVariants > 1 && dfi->mFormatID == kAudioFormatLinearPCM) {
+ // look for a 16-bit variant as a better default
+ for (int j = 0; j < dfi->mNumVariants; ++j) {
+ AudioStreamBasicDescription *desc = &dfi->mVariants[j];
+ if (desc->mBitsPerChannel == 16) {
+ fmt = *desc;
+ break;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CAAudioFileFormats::InferFileFormatFromFilename(CFStringRef filename, AudioFileTypeID &filetype)
+{
+ bool result = false;
+ CFRange range = CFStringFind(filename, CFSTR("."), kCFCompareBackwards);
+ if (range.location == kCFNotFound) return false;
+ range.location += 1;
+ range.length = CFStringGetLength(filename) - range.location;
+ CFStringRef ext = CFStringCreateWithSubstring(NULL, filename, range);
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ if (ffi->MatchExtension(ext)) {
+ filetype = ffi->mFileTypeID;
+ result = true;
+ break;
+ }
+ }
+ CFRelease(ext);
+ return result;
+}
+
+bool CAAudioFileFormats::InferFileFormatFromFilename(const char *filename, AudioFileTypeID &filetype)
+{
+ if (filename == NULL) return false;
+ CFStringRef cfname = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8);
+ bool result = InferFileFormatFromFilename(cfname, filetype);
+ CFRelease(cfname);
+ return result;
+}
+
+bool CAAudioFileFormats::InferFileFormatFromDataFormat(const CAStreamBasicDescription &fmt,
+ AudioFileTypeID &filetype)
+{
+ // if there's exactly one file format that supports this data format
+ FileFormatInfo *theFileFormat = NULL;
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ ffi->LoadDataFormats();
+ DataFormatInfo *dfi = ffi->mDataFormats, *dfiend = dfi + ffi->mNumDataFormats;
+ for ( ; dfi < dfiend; ++dfi)
+ if (dfi->mFormatID == fmt.mFormatID) {
+ if (theFileFormat != NULL)
+ return false; // ambiguous
+ theFileFormat = ffi; // got a candidate
+ }
+ }
+ if (theFileFormat == NULL)
+ return false;
+ filetype = theFileFormat->mFileTypeID;
+ return true;
+}
+
+bool CAAudioFileFormats::IsKnownDataFormat(OSType dataFormat)
+{
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ ffi->LoadDataFormats();
+ DataFormatInfo *dfi = ffi->mDataFormats, *dfiend = dfi + ffi->mNumDataFormats;
+ for ( ; dfi < dfiend; ++dfi)
+ if (dfi->mFormatID == dataFormat)
+ return true;
+ }
+ return false;
+}
+
+CAAudioFileFormats::FileFormatInfo * CAAudioFileFormats::FindFileFormat(UInt32 formatID)
+{
+ for (int i = 0; i < mNumFileFormats; ++i) {
+ FileFormatInfo *ffi = &mFileFormats[i];
+ if (ffi->mFileTypeID == formatID)
+ return ffi;
+ }
+ return NULL;
+}
+
+bool CAAudioFileFormats::FileFormatInfo::AnyWritableFormats()
+{
+ LoadDataFormats();
+ DataFormatInfo *dfi = mDataFormats, *dfiend = dfi + mNumDataFormats;
+ for ( ; dfi < dfiend; ++dfi)
+ if (dfi->mWritable)
+ return true;
+ return false;
+}
+
+char *OSTypeToStr(char *buf, size_t bufsize, OSType t)
+{
+ if (bufsize > 0) {
+ char *p = buf, *pend = buf + bufsize;
+ char str[4] = {0}, *q = str;
+ *(UInt32 *)str = CFSwapInt32HostToBig(t);
+ for (int i = 0; i < 4 && p < pend; ++i) {
+ if (isprint(*q) && *q != '\\')
+ *p++ = *q++;
+ else {
+ snprintf(p, pend - p, "\\x%02x", *q++);
+ p += 4;
+ }
+ }
+ if (p >= pend) p = pend - 1;
+ *p = '\0';
+ }
+ return buf;
+}
+
+int StrToOSType(const char *str, OSType &t)
+{
+ char buf[4];
+ const char *p = str;
+ int x;
+ for (int i = 0; i < 4; ++i) {
+ if (*p != '\\') {
+ if ((buf[i] = *p++) == '\0') {
+ // special-case for 'aac ': if we only got three characters, assume the last was a space
+ if (i == 3) {
+ --p;
+ buf[i] = ' ';
+ break;
+ }
+ goto fail;
+ }
+ } else {
+ if (*++p != 'x') goto fail;
+ if (sscanf(++p, "%02X", &x) != 1) goto fail;
+ buf[i] = x;
+ p += 2;
+ }
+ }
+ t = CFSwapInt32BigToHost(*(UInt32 *)buf);
+ return static_cast<int>(p - str);
+fail:
+ return 0;
+}
+
+#if DEBUG
+
+void CAAudioFileFormats::DebugPrint()
+{
+ for (int i = 0; i < mNumFileFormats; ++i)
+ mFileFormats[i].DebugPrint();
+}
+
+void CAAudioFileFormats::FileFormatInfo::DebugPrint()
+{
+ char ftype[20];
+ char ftypename[64];
+ CFStringGetCString(mFileTypeName, ftypename, sizeof(ftypename), kCFStringEncodingUTF8);
+ printf("File type: '%s' = %s\n Extensions:", OSTypeToStr(ftype, sizeof(ftype), mFileTypeID), ftypename);
+ int i, n = NumberOfExtensions();
+ for (i = 0; i < n; ++i) {
+ GetExtension(i, ftype, sizeof(ftype));
+ printf(" .%s", ftype);
+ }
+ LoadDataFormats();
+ printf("\n Formats:\n");
+ for (i = 0; i < mNumDataFormats; ++i)
+ mDataFormats[i].DebugPrint();
+}
+
+void CAAudioFileFormats::DataFormatInfo::DebugPrint()
+{
+ char buf[20];
+ static const char *ny[] = { "not ", "" };
+ printf(" '%s': %sreadable %swritable\n", OSTypeToStr(buf, sizeof(buf), mFormatID), ny[mReadable], ny[mWritable]);
+ for (int i = 0; i < mNumVariants; ++i) {
+ CAStreamBasicDescription desc(mVariants[i]);
+ desc.PrintFormat(stdout, " ", "");
+ //printf(" %d bytes/frame\n", desc.mBytesPerFrame);
+ }
+}
+#endif
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.h
new file mode 100644
index 0000000000..3d2f90f6de
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioFileFormats.h
@@ -0,0 +1,149 @@
+/*
+ File: CAAudioFileFormats.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAudioFileFormats_h__
+#define __CAAudioFileFormats_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioToolbox/AudioToolbox.h>
+#else
+ #include <AudioToolbox.h>
+#endif
+#include "CAStreamBasicDescription.h"
+
+class CAAudioFileFormats {
+public:
+ enum { noErr = 0 };
+
+ struct DataFormatInfo {
+ DataFormatInfo() : mVariants(NULL) { }
+ ~DataFormatInfo() { delete[] mVariants; }
+
+ UInt32 mFormatID;
+ int mNumVariants;
+ AudioStreamBasicDescription * mVariants;
+ bool mReadable;
+ bool mWritable;
+ bool mEitherEndianPCM;
+
+#if DEBUG
+ void DebugPrint();
+#endif
+ };
+
+ struct FileFormatInfo {
+ FileFormatInfo() : mFileTypeName(NULL), mExtensions(NULL), mDataFormats(NULL) { }
+ ~FileFormatInfo() {
+ delete[] mDataFormats;
+ if (mFileTypeName)
+ CFRelease(mFileTypeName);
+ if (mExtensions)
+ CFRelease(mExtensions);
+ }
+
+ AudioFileTypeID mFileTypeID;
+ CFStringRef mFileTypeName;
+ CFArrayRef mExtensions;
+ int mNumDataFormats;
+ DataFormatInfo * mDataFormats; // NULL until loaded!
+
+ int NumberOfExtensions() { return static_cast<int>(mExtensions ? CFArrayGetCount(mExtensions) : 0); }
+ char * GetExtension(int index, char *buf, int buflen) {
+ CFStringRef cfext = (CFStringRef)CFArrayGetValueAtIndex(mExtensions, index);
+ CFStringGetCString(cfext, buf, buflen, kCFStringEncodingUTF8);
+ return buf;
+ }
+ bool MatchExtension(CFStringRef testExt) { // testExt should not include "."
+ CFIndex n = NumberOfExtensions();
+ for (CFIndex i = 0; i < n; ++i) {
+ CFStringRef ext = (CFStringRef)CFArrayGetValueAtIndex(mExtensions, i);
+ if (CFStringCompare(ext, testExt, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ return true;
+ }
+ return false;
+ }
+ bool AnyWritableFormats();
+ void LoadDataFormats();
+
+#if DEBUG
+ void DebugPrint();
+#endif
+ };
+
+private: // use Instance()
+ CAAudioFileFormats(bool loadDataFormats);
+ ~CAAudioFileFormats();
+public:
+
+ bool InferDataFormatFromFileFormat(AudioFileTypeID filetype, CAStreamBasicDescription &fmt);
+
+ bool InferFileFormatFromFilename(const char *filename, AudioFileTypeID &filetype);
+
+ bool InferFileFormatFromFilename(CFStringRef filename, AudioFileTypeID &filetype);
+
+ bool InferFileFormatFromDataFormat(const CAStreamBasicDescription &fmt, AudioFileTypeID &filetype);
+
+ bool IsKnownDataFormat(UInt32 dataFormat);
+
+#if DEBUG
+ void DebugPrint();
+#endif
+
+ int mNumFileFormats;
+ FileFormatInfo * mFileFormats;
+
+ FileFormatInfo * FindFileFormat(UInt32 formatID);
+
+ static CAAudioFileFormats * Instance(bool loadDataFormats=true);
+
+private:
+ static CAAudioFileFormats * sInstance;
+};
+
+char * OSTypeToStr(char *buf, size_t bufsize, UInt32 t);
+int StrToOSType(const char *str, UInt32 &t);
+
+#endif // __CAAudioFileFormats_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.cpp
new file mode 100644
index 0000000000..0200ec9b79
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.cpp
@@ -0,0 +1,135 @@
+/*
+ File: CAAudioTimeStamp.cpp
+ Abstract: CAAudioTimeStamp.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CAAudioTimeStamp.h"
+
+//=============================================================================
+// CAAudioTimeStamp
+//=============================================================================
+
+const AudioTimeStamp CAAudioTimeStamp::kZero = { 0.0, 0, 0.0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 0 };
+
+bool operator<(const AudioTimeStamp& x, const AudioTimeStamp& y)
+{
+ bool isLessThan = false;
+ bool isDone = false;
+
+ // check the sample time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampSampleTimeValid) && (y.mFlags & kAudioTimeStampSampleTimeValid))
+ {
+ isLessThan = x.mSampleTime < y.mSampleTime;
+ isDone = true;
+ }
+ }
+
+ // check the host time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampHostTimeValid) && (y.mFlags & kAudioTimeStampHostTimeValid))
+ {
+ isLessThan = x.mHostTime < y.mHostTime;
+ isDone = true;
+ }
+ }
+
+ // check the word clock time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampWordClockTimeValid) && (y.mFlags & kAudioTimeStampWordClockTimeValid))
+ {
+ isLessThan = x.mWordClockTime < y.mWordClockTime;
+ // commented out to prevent this from being flagged as a dead store by the static analyzer
+ //isDone = true;
+ }
+ }
+
+ return isLessThan;
+}
+
+bool operator==(const AudioTimeStamp& x, const AudioTimeStamp& y)
+{
+ bool isEqual = false;
+ bool isDone = false;
+
+ // check the sample time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampSampleTimeValid) && (y.mFlags & kAudioTimeStampSampleTimeValid))
+ {
+ isEqual = x.mSampleTime == y.mSampleTime;
+ isDone = true;
+ }
+ }
+
+ // check the host time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampHostTimeValid) && (y.mFlags & kAudioTimeStampHostTimeValid))
+ {
+ isEqual = x.mHostTime == y.mHostTime;
+ isDone = true;
+ }
+ }
+
+ // check the word clock time
+ if(!isDone)
+ {
+ if((x.mFlags & kAudioTimeStampWordClockTimeValid) && (y.mFlags & kAudioTimeStampWordClockTimeValid))
+ {
+ isEqual = x.mWordClockTime == y.mWordClockTime;
+ // commented out to prevent this from being flagged as a dead store by the static analyzer
+ //isDone = true;
+ }
+ }
+
+ return isEqual;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.h
new file mode 100644
index 0000000000..9b8d6abe41
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioTimeStamp.h
@@ -0,0 +1,97 @@
+/*
+ File: CAAudioTimeStamp.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAAudioTimeStamp_h__)
+#define __CAAudioTimeStamp_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+#include <string.h>
+
+//=============================================================================
+// CAAudioTimeStamp
+//=============================================================================
+
+struct CAAudioTimeStamp
+:
+ public AudioTimeStamp
+{
+
+// Construction/Destruction
+public:
+ CAAudioTimeStamp() { memset(this, 0, sizeof(AudioTimeStamp)); }
+ CAAudioTimeStamp(const AudioTimeStamp& v) { memcpy(this, &v, sizeof(AudioTimeStamp)); }
+ CAAudioTimeStamp(Float64 inSampleTime) { memset(this, 0, sizeof(AudioTimeStamp)); mSampleTime = inSampleTime; mFlags = kAudioTimeStampSampleTimeValid; }
+ CAAudioTimeStamp(UInt64 inHostTime) { memset(this, 0, sizeof(AudioTimeStamp)); mHostTime = inHostTime; mFlags = kAudioTimeStampHostTimeValid; }
+ CAAudioTimeStamp(Float64 inSampleTime, UInt64 inHostTime) { memset(this, 0, sizeof(AudioTimeStamp)); mSampleTime = inSampleTime; mHostTime = inHostTime; mFlags = kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid; }
+ CAAudioTimeStamp(Float64 inSampleTime, UInt64 inHostTime, Float64 inRateScalar) { memset(this, 0, sizeof(AudioTimeStamp)); mSampleTime = inSampleTime; mHostTime = inHostTime; mRateScalar = inRateScalar; mFlags = kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid | kAudioTimeStampRateScalarValid; }
+
+// Assignment
+public:
+ CAAudioTimeStamp& operator=(const AudioTimeStamp& v) { memcpy(this, &v, sizeof(AudioTimeStamp)); return *this; }
+
+// Constants
+public:
+ static const AudioTimeStamp kZero;
+
+};
+
+bool operator<(const AudioTimeStamp& x, const AudioTimeStamp& y);
+bool operator==(const AudioTimeStamp& x, const AudioTimeStamp& y);
+inline bool operator!=(const AudioTimeStamp& x, const AudioTimeStamp& y) { return !(x == y); }
+inline bool operator<=(const AudioTimeStamp& x, const AudioTimeStamp& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioTimeStamp& x, const AudioTimeStamp& y) { return !(x < y); }
+inline bool operator>(const AudioTimeStamp& x, const AudioTimeStamp& y) { return !((x < y) || (x == y)); }
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.cpp
new file mode 100644
index 0000000000..53da5a1cc6
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.cpp
@@ -0,0 +1,1421 @@
+/*
+ File: CAAudioUnit.cpp
+ Abstract: CAAudioUnit.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAAudioUnit.h"
+
+#if !TARGET_OS_IPHONE
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Components.h>
+ #include <dlfcn.h>
+#else
+ #include <Components.h>
+#endif
+#endif
+
+#include "CAXException.h"
+#include "CAReferenceCounted.h"
+#include "AUOutputBL.h" //this is for the Preroll only
+
+struct StackAUChannelInfo {
+ StackAUChannelInfo (UInt32 inSize) : mChanInfo ((AUChannelInfo*)malloc (inSize)) {}
+ ~StackAUChannelInfo() { free (mChanInfo); }
+
+ AUChannelInfo* mChanInfo;
+};
+
+// is this symbol is not defined then we use the default setting which is that fast dispatch
+// is supported on a desktop environment
+#ifndef CA_AU_USE_FAST_DISPATCH
+ #define CA_AU_USE_FAST_DISPATCH !TARGET_OS_IPHONE
+#endif
+
+#if CA_AU_USE_FAST_DISPATCH
+static void *LoadGetComponentInstanceStorage (void *inst);
+#endif
+
+
+class CAAudioUnit::AUState : public CAReferenceCounted {
+public:
+ AUState (AudioComponent inComp)
+ : mUnit(0), mNode (0)
+ {
+ OSStatus result = ::AudioComponentInstanceNew (inComp, &mUnit);
+ if (result)
+ throw result;
+ Init();
+ }
+
+ AUState (const AUNode &inNode, const AudioUnit& inUnit)
+ : mUnit (inUnit), mNode (inNode)
+ {
+ Init();
+ }
+
+ ~AUState();
+
+ AudioUnit mUnit;
+ AUNode mNode;
+
+ OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const
+ {
+#if CA_AU_USE_FAST_DISPATCH
+ if (mGetParamProc != NULL) {
+ return (mGetParamProc) (mConnInstanceStorage, inID, scope, element, &outValue);
+ }
+#endif
+ return AudioUnitGetParameter(mUnit, inID, scope, element, &outValue);
+ }
+
+ OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames)
+ {
+#if CA_AU_USE_FAST_DISPATCH
+ if (mSetParamProc != NULL) {
+ return (mSetParamProc) (mConnInstanceStorage, inID, scope, element, value, bufferOffsetFrames);
+ }
+#endif
+ return AudioUnitSetParameter(mUnit, inID, scope, element, value, bufferOffsetFrames);
+ }
+
+ OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData)
+ {
+#if CA_AU_USE_FAST_DISPATCH
+ if (mRenderProc != NULL) {
+ return (mRenderProc) (mConnInstanceStorage, ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData);
+ }
+#endif
+ return AudioUnitRender(mUnit, ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData);
+ }
+
+ OSStatus MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame)
+ {
+#if !TARGET_OS_WIN32
+#if CA_AU_USE_FAST_DISPATCH
+ if (mMIDIEventProc != NULL) {
+ return (mMIDIEventProc) (mConnInstanceStorage, inStatus, inData1, inData2, inOffsetSampleFrame);
+ }
+#endif
+ return MusicDeviceMIDIEvent (mUnit, inStatus, inData1, inData2, inOffsetSampleFrame);
+#else // ON WINDOWS _ NO MIDI EVENT dispatch
+ return paramErr;
+#endif
+ }
+
+ OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+ {
+#if !TARGET_OS_WIN32
+#if CA_AU_USE_FAST_DISPATCH
+ if (mStartNoteProc != NULL) {
+ return (mStartNoteProc) (mConnInstanceStorage, inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams);
+ }
+#endif
+ return MusicDeviceStartNote (mUnit, inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams);
+#else
+ return paramErr;
+#endif
+ }
+ OSStatus StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame)
+ {
+#if !TARGET_OS_WIN32
+#if CA_AU_USE_FAST_DISPATCH
+ if (mStopNoteProc != NULL) {
+ return (mStopNoteProc) (mConnInstanceStorage, inGroupID, inNoteInstanceID, inOffsetSampleFrame);
+ }
+#endif
+ return MusicDeviceStopNote (mUnit, inGroupID, inNoteInstanceID, inOffsetSampleFrame);
+#else
+ return paramErr;
+#endif
+ }
+
+private:
+ // get the fast dispatch pointers
+ void Init()
+ {
+#if CA_AU_USE_FAST_DISPATCH
+ UInt32 size = sizeof(AudioUnitRenderProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitRenderSelect,
+ &mRenderProc, &size) != noErr)
+ mRenderProc = NULL;
+
+ size = sizeof(AudioUnitGetParameterProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitGetParameterSelect,
+ &mGetParamProc, &size) != noErr)
+ mGetParamProc = NULL;
+
+ size = sizeof(AudioUnitSetParameterProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitSetParameterSelect,
+ &mSetParamProc, &size) != noErr)
+ mSetParamProc = NULL;
+
+ size = sizeof(MusicDeviceMIDIEventProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kMusicDeviceMIDIEventSelect,
+ &mMIDIEventProc, &size) != noErr)
+ mMIDIEventProc = NULL;
+
+ size = sizeof(MusicDeviceStartNoteProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kMusicDeviceStartNoteSelect,
+ &mStartNoteProc, &size) != noErr)
+ mStartNoteProc = NULL;
+
+ size = sizeof(MusicDeviceStopNoteProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kMusicDeviceStopNoteSelect,
+ &mStopNoteProc, &size) != noErr)
+ mStopNoteProc = NULL;
+
+ if (mRenderProc || mGetParamProc || mSetParamProc || mMIDIEventProc || mStartNoteProc || mStopNoteProc) {
+ mConnInstanceStorage = LoadGetComponentInstanceStorage ( mUnit );
+ } else
+ mConnInstanceStorage = NULL;
+#else
+ mConnInstanceStorage = NULL;
+#endif
+ }
+
+#if CA_AU_USE_FAST_DISPATCH
+ AudioUnitRenderProc mRenderProc;
+ AudioUnitGetParameterProc mGetParamProc;
+ AudioUnitSetParameterProc mSetParamProc;
+ MusicDeviceMIDIEventProc mMIDIEventProc;
+ MusicDeviceStartNoteProc mStartNoteProc;
+ MusicDeviceStopNoteProc mStopNoteProc;
+#endif
+
+ void * mConnInstanceStorage;
+
+private:
+ // get the compiler to tell us when we do a bad thing!!!
+ AUState () {}
+ AUState (const AUState&);
+ AUState& operator= (const AUState&);
+};
+
+
+CAAudioUnit::AUState::~AUState ()
+{
+ if (mUnit && (mNode == 0)) {
+ ::AudioComponentInstanceDispose (mUnit);
+ }
+ mNode = 0;
+ mUnit = 0;
+}
+
+OSStatus CAAudioUnit::Open (const CAComponent& inComp, CAAudioUnit &outUnit)
+{
+ try {
+ outUnit = inComp;
+ return noErr;
+ } catch (OSStatus res) {
+ return res;
+ } catch (...) {
+ return -1;
+ }
+}
+
+CAAudioUnit::CAAudioUnit (const AudioUnit& inUnit)
+ : mComp (inUnit), mDataPtr (new AUState (kCAAU_DoNotKnowIfAUNode, inUnit))
+{
+}
+
+CAAudioUnit::CAAudioUnit (const CAComponent& inComp)
+ : mComp (inComp), mDataPtr (new AUState (mComp.Comp()))
+{
+}
+
+CAAudioUnit::CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit)
+ : mComp (inUnit), mDataPtr(new AUState (inNode, inUnit))
+{
+}
+
+CAAudioUnit::~CAAudioUnit ()
+{
+ Close();
+}
+
+void CAAudioUnit::Close()
+{
+ if (mDataPtr) {
+ mDataPtr->release();
+ mDataPtr = NULL;
+ }
+}
+
+CAAudioUnit& CAAudioUnit::operator= (const CAAudioUnit &a)
+{
+ if (mDataPtr != a.mDataPtr) {
+ if (mDataPtr)
+ mDataPtr->release();
+
+ if ((mDataPtr = a.mDataPtr) != NULL)
+ mDataPtr->retain();
+
+ mComp = a.mComp;
+ }
+
+ return *this;
+}
+
+bool CAAudioUnit::operator== (const CAAudioUnit& y) const
+{
+ if (mDataPtr == y.mDataPtr) return true;
+ AudioUnit au1 = mDataPtr ? mDataPtr->mUnit : 0;
+ AudioUnit au2 = y.mDataPtr ? y.mDataPtr->mUnit : 0;
+ return au1 == au2;
+}
+
+bool CAAudioUnit::operator== (const AudioUnit& y) const
+{
+ if (!mDataPtr) return false;
+ return mDataPtr->mUnit == y;
+}
+
+OSStatus CAAudioUnit::RemovePropertyListener (AudioUnitPropertyID inID,
+ AudioUnitPropertyListenerProc inProc,
+ void * inProcUserData)
+{
+ // we call this first. If it fails we call the old API as the failure can
+ // mean that the AU doesn't implement that selector.
+ OSStatus result = AudioUnitRemovePropertyListenerWithUserData(AU(), inID,
+ inProc, inProcUserData);
+ #if !__LP64__ && !TARGET_OS_IPHONE
+ if (result) result = AudioUnitRemovePropertyListener (AU(), inID, inProc);
+ #endif
+ return result;
+}
+
+#pragma mark __State Management
+
+bool CAAudioUnit::IsValid () const
+{
+ return mDataPtr ? mDataPtr->mUnit != 0 : false;
+}
+
+AudioUnit CAAudioUnit::AU() const
+{
+ return mDataPtr ? mDataPtr->mUnit : 0;
+}
+
+AUNode CAAudioUnit::GetAUNode () const
+{
+ return mDataPtr ? mDataPtr->mNode : 0;
+}
+
+#pragma mark __Format Handling
+
+bool CAAudioUnit::CanDo ( int inChannelsIn,
+ int inChannelsOut) const
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+ if (result)
+ {
+ if ((Comp().Desc().IsEffect() && inChannelsIn == inChannelsOut)
+ || (Comp().Desc().IsOffline() && inChannelsIn == inChannelsOut))
+ {
+ return true;
+ }
+ else
+ {
+ // the au should either really tell us about this
+ // or we will assume the worst
+ return false;
+ }
+ }
+
+ StackAUChannelInfo info (dataSize);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize);
+ if (result) { return false; }
+
+ return ValidateChannelPair (inChannelsIn, inChannelsOut, info.mChanInfo, (dataSize / sizeof (AUChannelInfo)));
+}
+
+int CAAudioUnit::GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt)
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+
+ if (result)
+ {
+ if (Comp().Desc().IsEffect())
+ {
+ return 1;
+ }
+ else if (Comp().Desc().IsGenerator() || Comp().Desc().IsMusicDevice()) {
+ // directly query Bus Formats
+ // Note that that these may refer to different subBusses
+ // (eg. Kick, Snare,.. on a Drummachine)
+ // eventually the Bus-Name for each configuration should be exposed
+ // for the User to select..
+
+ UInt32 elCountIn, elCountOut;
+
+ if (GetElementCount (kAudioUnitScope_Input, elCountIn)) return -1;
+ if (GetElementCount (kAudioUnitScope_Output, elCountOut)) return -1;
+
+ cnt = std::max(elCountIn, elCountOut);
+
+ *chaninfo = (AUChannelInfo*) malloc (sizeof (AUChannelInfo) * cnt);
+
+ for (unsigned int i = 0; i < elCountIn; ++i) {
+ UInt32 numChans;
+ if (NumberChannels (kAudioUnitScope_Input, i, numChans)) return -1;
+ (*chaninfo)[i].inChannels = numChans;
+ }
+ for (unsigned int i = elCountIn; i < cnt; ++i) {
+ (*chaninfo)[i].inChannels = 0;
+ }
+
+ for (unsigned int i = 0; i < elCountOut; ++i) {
+ UInt32 numChans;
+ if (NumberChannels (kAudioUnitScope_Output, i, numChans)) return -1;
+ (*chaninfo)[i].outChannels = numChans;
+ }
+ for (unsigned int i = elCountOut; i < cnt; ++i) {
+ (*chaninfo)[i].outChannels = 0;
+ }
+ return 0;
+ }
+ else
+ {
+ // the au should either really tell us about this
+ // or we will assume the worst
+ return -1;
+ }
+ }
+
+ *chaninfo = (AUChannelInfo*) malloc (dataSize);
+ cnt = dataSize / sizeof (AUChannelInfo);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ *chaninfo, &dataSize);
+
+ if (result) { return -1; }
+ return 0;
+}
+
+bool CAAudioUnit::ValidateChannelPair (int inChannelsIn,
+ int inChannelsOut,
+ const AUChannelInfo * info,
+ UInt32 numChanInfo) const
+{
+// we've the following cases (some combinations) to test here:
+/*
+>0 An explicit number of channels on either side
+0 that side (generally input!) has no elements
+-1 wild card:
+-1,-1 any num channels as long as same channels on in and out
+-1,-2 any num channels channels on in and out - special meaning
+-2+ indicates total num channs AU can handle
+ - elements configurable to any num channels,
+ - element count in scope must be writable
+*/
+
+ //now chan layout can contain -1 for either scope (ie. doesn't care)
+ for (unsigned int i = 0; i < numChanInfo; ++i)
+ {
+ //less than zero on both sides - check for special attributes
+ if ((info[i].inChannels < 0) && (info[i].outChannels < 0))
+ {
+ // these are our wild card matches
+ if (info[i].inChannels == -1 && info[i].outChannels == -1) {
+ if (inChannelsIn && inChannelsOut) {
+ if (inChannelsOut == inChannelsIn)
+ return true;
+ } else
+ return true; // if one of these is zero, then a -1 means any
+ }
+ else if ((info[i].inChannels == -1 && info[i].outChannels == -2)
+ || (info[i].inChannels == -2 && info[i].outChannels == -1))
+ {
+ return true;
+ }
+ // these are our total num channels matches
+ // element count MUST be writable
+ else {
+ bool outWrite = false; bool inWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Output, outWrite);
+ IsElementCountWritable (kAudioUnitScope_Input, inWrite);
+ if (inWrite && outWrite) {
+ if ((inChannelsOut <= abs(info[i].outChannels))
+ && (inChannelsIn <= abs(info[i].inChannels)))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ // special meaning on input, specific num on output
+ else if (info[i].inChannels < 0) {
+ if (info[i].outChannels == inChannelsOut)
+ {
+ // can do any in channels
+ if (info[i].inChannels == -1) {
+ return true;
+ }
+ // total chans on input
+ else {
+ bool inWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Input, inWrite);
+ if (inWrite && (inChannelsIn <= abs(info[i].inChannels))) {
+ return true;
+ }
+ }
+ }
+ }
+
+ // special meaning on output, specific num on input
+ else if (info[i].outChannels < 0) {
+ if (info[i].inChannels == inChannelsIn)
+ {
+ // can do any out channels
+ if (info[i].outChannels == -1) {
+ return true;
+ }
+ // total chans on output
+ else {
+ bool outWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Output, outWrite);
+ if (outWrite && (inChannelsOut <= abs(info[i].outChannels))) {
+ return true;
+ }
+ }
+ }
+ }
+
+ // both chans in struct >= 0 - thus has to explicitly match
+ else if ((info[i].inChannels == inChannelsIn) && (info[i].outChannels == inChannelsOut)) {
+ return true;
+ }
+
+ // now check to see if a wild card on the args (inChannelsIn or inChannelsOut chans is zero) is found
+ // tells us to match just one side of the scopes
+ else if (inChannelsIn == 0) {
+ if (info[i].outChannels == inChannelsOut) {
+ return true;
+ }
+ }
+ else if (inChannelsOut == 0) {
+ if (info[i].inChannels == inChannelsIn) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static
+bool CheckDynCount (SInt32 inTotalChans, const CAAUChanHelper &inHelper)
+{
+ int totalChans = 0;
+ for (unsigned int i = 0; i < inHelper.mNumEls; ++i)
+ totalChans += inHelper.mChans[i];
+ return (totalChans <= inTotalChans);
+}
+
+bool CAAudioUnit::CheckOneSide (const CAAUChanHelper &inHelper,
+ bool checkOutput,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const
+{
+ // now we can use the wildcard option (see above impl) to see if this matches
+ for (unsigned int el = 0; el < inHelper.mNumEls; ++el) {
+ bool testAlready = false;
+ for (unsigned int i = 0; i < el; ++i) {
+ if (inHelper.mChans[i] == inHelper.mChans[el]) {
+ testAlready = true;
+ break;
+ }
+ }
+ if (!testAlready) {
+ if (checkOutput) {
+ if (!ValidateChannelPair (0, inHelper.mChans[el], info, numInfo)) return false;
+ } else {
+ if (!ValidateChannelPair (inHelper.mChans[el], 0, info, numInfo)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool CAAudioUnit::CanDo (const CAAUChanHelper &inputs,
+ const CAAUChanHelper &outputs) const
+
+{
+// first check our state
+ // huh!
+ if (inputs.mNumEls == 0 && outputs.mNumEls == 0) return false;
+
+ UInt32 elCount;
+ if (GetElementCount (kAudioUnitScope_Input, elCount)) { return false; }
+ if (elCount != inputs.mNumEls) return false;
+
+ if (GetElementCount (kAudioUnitScope_Output, elCount)) { return false; }
+ if (elCount != outputs.mNumEls) return false;
+
+// (1) special cases (effects and sources (generators and instruments) only)
+ UInt32 dataSize = 0;
+ if (GetPropertyInfo (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0, &dataSize, NULL) != noErr)
+ {
+ if (Comp().Desc().IsEffect() || Comp().Desc().IsOffline()) {
+ UInt32 numChan = outputs.mNumEls > 0 ? outputs.mChans[0] : inputs.mChans[0];
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in)
+ if (numChan != inputs.mChans[in]) return false;
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out)
+ if (numChan != outputs.mChans[out]) return false;
+ return true;
+ }
+
+ // in this case, all the channels have to match the current config
+ if (Comp().Desc().IsGenerator() || Comp().Desc().IsMusicDevice()) {
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in) {
+ UInt32 chan;
+ if (NumberChannels (kAudioUnitScope_Input, in, chan)) return false;
+ if (chan != UInt32(inputs.mChans[in])) return false;
+ }
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
+ UInt32 chan;
+ if (NumberChannels (kAudioUnitScope_Output, out, chan)) return false;
+ if (chan != UInt32(outputs.mChans[out])) return false;
+ }
+ return true;
+ }
+
+ // if we get here we can't determine anything about channel capabilities
+ return false;
+ }
+
+ StackAUChannelInfo info (dataSize);
+
+ if (GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize) != noErr)
+ {
+ return false;
+ }
+
+ int numInfo = dataSize / sizeof(AUChannelInfo);
+
+// (2) Test for dynamic capability (or no elements on that scope)
+ SInt32 dynInChans = 0;
+ if (ValidateDynamicScope (kAudioUnitScope_Input, dynInChans, info.mChanInfo, numInfo)) {
+ if (CheckDynCount (dynInChans, inputs) == false) return false;
+ }
+
+ SInt32 dynOutChans = 0;
+ if (ValidateDynamicScope (kAudioUnitScope_Output, dynOutChans, info.mChanInfo, numInfo)) {
+ if (CheckDynCount (dynOutChans, outputs) == false) return false;
+ }
+
+ if (dynOutChans && dynInChans) { return true; }
+
+// (3) Just need to test one side
+ if (dynInChans || (inputs.mNumEls == 0)) {
+ return CheckOneSide (outputs, true, info.mChanInfo, numInfo);
+ }
+
+ if (dynOutChans || (outputs.mNumEls == 0)) {
+ return CheckOneSide (inputs, false, info.mChanInfo, numInfo);
+ }
+
+// (4) - not a dynamic AU, has ins and outs, and has channel constraints so we test every possible pairing
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in)
+ {
+ bool testInAlready = false;
+ for (unsigned int i = 0; i < in; ++i) {
+ if (inputs.mChans[i] == inputs.mChans[in]) {
+ testInAlready = true;
+ break;
+ }
+ }
+ if (!testInAlready) {
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
+ // try to save a little bit and not test the same pairing multiple times...
+ bool testOutAlready = false;
+ for (unsigned int i = 0; i < out; ++i) {
+ if (outputs.mChans[i] == outputs.mChans[out]) {
+ testOutAlready = true;
+ break;
+ }
+ }
+ if (!testOutAlready) {
+ if (!ValidateChannelPair (inputs.mChans[in], outputs.mChans[out],info.mChanInfo, numInfo)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CAAudioUnit::SupportsNumChannels () const
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+ if (result) {
+ if (Comp().Desc().IsEffect() || Comp().Desc().IsOffline())
+ return true;
+ }
+ return result == noErr;
+}
+
+OSStatus CAAudioUnit::GetChannelLayoutTags (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ ChannelTagVector &outChannelVector) const
+{
+ if (HasChannelLayouts (inScope, inEl) == false) return kAudioUnitErr_InvalidProperty;
+
+ UInt32 dataSize;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ &dataSize, NULL);
+
+ if (result) return result;
+
+ // OK lets get our channel layouts and see if the one we want is present
+ AudioChannelLayoutTag* info = (AudioChannelLayoutTag*)malloc (dataSize);
+ result = AudioUnitGetProperty (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ info, &dataSize);
+ if (result) goto home;
+
+ outChannelVector.erase (outChannelVector.begin(), outChannelVector.end());
+ for (unsigned int i = 0; i < (dataSize / sizeof (AudioChannelLayoutTag)); ++i)
+ outChannelVector.push_back (info[i]);
+
+home:
+ free (info);
+ return result;
+}
+
+bool CAAudioUnit::HasChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl) const
+{
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ NULL, NULL);
+ return !result;
+}
+
+bool CAAudioUnit::HasChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl) const
+{
+ Boolean writable;
+ UInt32 size;
+
+ return AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl,
+ &size, &writable) == noErr;
+}
+
+OSStatus CAAudioUnit::GetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &outLayout) const
+{
+ UInt32 size;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(), kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, &size, NULL);
+ if (result) return result;
+
+ AudioChannelLayout *layout = (AudioChannelLayout*)malloc (size);
+
+ ca_require_noerr (result = AudioUnitGetProperty (AU(), kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, layout, &size), home);
+
+ outLayout = CAAudioChannelLayout (layout);
+
+home:
+ free (layout);
+ return result;
+}
+
+OSStatus CAAudioUnit::SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const CAAudioChannelLayout &inLayout)
+{
+ OSStatus result = AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl,
+ inLayout, inLayout.Size());
+ return result;
+}
+
+OSStatus CAAudioUnit::SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioChannelLayout &inLayout,
+ UInt32 inSize)
+{
+ OSStatus result = AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl,
+ &inLayout, inSize);
+ return result;
+}
+
+OSStatus CAAudioUnit::ClearChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl)
+{
+ return AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, NULL, 0);
+}
+
+OSStatus CAAudioUnit::GetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioStreamBasicDescription &outFormat) const
+{
+ UInt32 dataSize = sizeof (AudioStreamBasicDescription);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_StreamFormat,
+ inScope, inEl,
+ &outFormat, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioStreamBasicDescription &inFormat)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_StreamFormat,
+ inScope, inEl,
+ const_cast<AudioStreamBasicDescription*>(&inFormat),
+ sizeof (AudioStreamBasicDescription));
+}
+
+OSStatus CAAudioUnit::GetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 &outRate) const
+{
+ UInt32 dataSize = sizeof (Float64);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_SampleRate,
+ inScope, inEl,
+ &outRate, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 inRate)
+{
+ AudioStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (result) return result;
+ desc.mSampleRate = inRate;
+ return SetFormat (inScope, inEl, desc);
+}
+
+OSStatus CAAudioUnit::SetSampleRate (Float64 inSampleRate)
+{
+ OSStatus result;
+
+ UInt32 elCount;
+ ca_require_noerr (result = GetElementCount(kAudioUnitScope_Input, elCount), home);
+ if (elCount) {
+ for (unsigned int i = 0; i < elCount; ++i) {
+ ca_require_noerr (result = SetSampleRate (kAudioUnitScope_Input, i, inSampleRate), home);
+ }
+ }
+
+ ca_require_noerr (result = GetElementCount(kAudioUnitScope_Output, elCount), home);
+ if (elCount) {
+ for (unsigned int i = 0; i < elCount; ++i) {
+ ca_require_noerr (result = SetSampleRate (kAudioUnitScope_Output, i, inSampleRate), home);
+ }
+ }
+
+home:
+ return result;
+}
+
+OSStatus CAAudioUnit::NumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const
+{
+ AudioStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (!result)
+ outChans = desc.mChannelsPerFrame;
+ return result;
+}
+
+OSStatus CAAudioUnit::SetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 inChans)
+{
+ // set this as the output of the AU
+ CAStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (result) return result;
+ desc.ChangeNumberChannels (inChans, desc.IsInterleaved());
+ result = SetFormat (inScope, inEl, desc);
+ return result;
+}
+
+OSStatus CAAudioUnit::IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const
+{
+ Boolean isWritable;
+ UInt32 outDataSize;
+ OSStatus result = GetPropertyInfo (kAudioUnitProperty_ElementCount, inScope, 0, &outDataSize, &isWritable);
+ if (result)
+ return result;
+ outWritable = isWritable ? true : false;
+ return noErr;
+}
+
+OSStatus CAAudioUnit::GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const
+{
+ UInt32 propSize = sizeof(outCount);
+ return GetProperty (kAudioUnitProperty_ElementCount, inScope, 0, &outCount, &propSize);
+}
+
+OSStatus CAAudioUnit::SetElementCount (AudioUnitScope inScope, UInt32 inCount)
+{
+ return SetProperty (kAudioUnitProperty_ElementCount, inScope, 0, &inCount, sizeof(inCount));
+}
+
+bool CAAudioUnit::HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const
+{
+ // ok - now we need to check the AU's capability here.
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ OSStatus result = GetPropertyInfo (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // AU has to explicitly tell us about this.
+ if (result) return false;
+
+ StackAUChannelInfo info (dataSize);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize);
+ if (result) return false;
+
+ return ValidateDynamicScope (inScope, outTotalNumChannels, info.mChanInfo, (dataSize / sizeof(AUChannelInfo)));
+}
+
+// as we've already checked that the element count is writable
+// the following conditions will match this..
+/*
+-1, -2 -> signifies no restrictions
+-2, -1 -> signifies no restrictions -> in this case outTotalNumChannels == -1 (any num channels)
+
+-N (where N is less than -2), signifies the total channel count on the scope side (in or out)
+*/
+bool CAAudioUnit::ValidateDynamicScope (AudioUnitScope inScope,
+ SInt32 &outTotalNumChannels,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const
+{
+ bool writable = false;
+ OSStatus result = IsElementCountWritable (inScope, writable);
+ if (result || (writable == false))
+ return false;
+
+ //now chan layout can contain -1 for either scope (ie. doesn't care)
+ for (unsigned int i = 0; i < numInfo; ++i)
+ {
+ // lets test the special wild card case first...
+ // this says the AU can do any num channels on input or output - for eg. Matrix Mixer
+ if (((info[i].inChannels == -1) && (info[i].outChannels == -2))
+ || ((info[i].inChannels == -2) && (info[i].outChannels == -1)))
+ {
+ outTotalNumChannels = -1;
+ return true;
+ }
+
+ // ok lets now test our special case....
+ if (inScope == kAudioUnitScope_Input) {
+ // isn't dynamic on this side at least
+ if (info[i].inChannels >= 0)
+ continue;
+
+ if (info[i].inChannels < -2) {
+ outTotalNumChannels = abs (info[i].inChannels);
+ return true;
+ }
+ }
+
+ else if (inScope == kAudioUnitScope_Output) {
+ // isn't dynamic on this side at least
+ if (info[i].outChannels >= 0)
+ continue;
+
+ if (info[i].outChannels < -2) {
+ outTotalNumChannels = abs (info[i].outChannels);
+ return true;
+ }
+ }
+
+ else {
+ break; // wrong scope was specified
+ }
+ }
+
+ return false;
+}
+
+OSStatus CAAudioUnit::ConfigureDynamicScope (AudioUnitScope inScope,
+ UInt32 inNumElements,
+ UInt32 *inChannelsPerElement,
+ Float64 inSampleRate)
+{
+ SInt32 numChannels = 0;
+ bool isDyamic = HasDynamicScope (inScope, numChannels);
+ if (isDyamic == false)
+ return kAudioUnitErr_InvalidProperty;
+
+ //lets to a sanity check...
+ // if numChannels == -1, then it can do "any"...
+ if (numChannels > 0) {
+ SInt32 count = 0;
+ for (unsigned int i = 0; i < inNumElements; ++i)
+ count += inChannelsPerElement[i];
+ if (count > numChannels)
+ return kAudioUnitErr_InvalidPropertyValue;
+ }
+
+ OSStatus result = SetElementCount (inScope, inNumElements);
+ if (result)
+ return result;
+
+ for (unsigned int i = 0; i < inNumElements; ++i) {
+ CAStreamBasicDescription desc;
+ result = GetFormat (inScope, i, desc);
+ if (result) return result;
+ desc.ChangeNumberChannels (inChannelsPerElement[i], desc.IsInterleaved());
+ desc.mSampleRate = inSampleRate;
+ result = SetFormat (inScope, i, desc);
+ if (result)
+ return result;
+ }
+ return noErr;
+}
+
+#pragma mark __Properties
+
+bool CAAudioUnit::CanBypass () const
+{
+ Boolean outWritable;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ NULL, &outWritable);
+ return (!result && outWritable);
+}
+
+bool CAAudioUnit::GetBypass () const
+{
+ UInt32 dataSize = sizeof (UInt32);
+ UInt32 outBypass;
+ OSStatus result = AudioUnitGetProperty (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ &outBypass, &dataSize);
+ return (result ? false : outBypass);
+}
+
+OSStatus CAAudioUnit::SetBypass (bool inBypass) const
+{
+ UInt32 bypass = inBypass ? 1 : 0;
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ &bypass, sizeof (UInt32));
+}
+
+OSStatus CAAudioUnit::GetMaxFramesPerSlice (UInt32& outMaxFrames) const
+{
+ UInt32 dataSize = sizeof(outMaxFrames);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_MaximumFramesPerSlice,
+ kAudioUnitScope_Global, 0,
+ &outMaxFrames, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetMaxFramesPerSlice (UInt32 inMaxFrames)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_MaximumFramesPerSlice,
+ kAudioUnitScope_Global, 0,
+ &inMaxFrames, sizeof (UInt32));
+}
+
+Float64 CAAudioUnit::Latency () const
+{
+ Float64 secs;
+ UInt32 size = sizeof(secs);
+ if (GetProperty (kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, &secs, &size))
+ return 0;
+ return secs;
+}
+
+OSStatus CAAudioUnit::GetAUPreset (CFPropertyListRef &outData) const
+{
+ UInt32 dataSize = sizeof(outData);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_ClassInfo,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetAUPreset (CFPropertyListRef &inData)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_ClassInfo,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (CFPropertyListRef));
+}
+
+#if !TARGET_OS_IPHONE
+OSStatus CAAudioUnit::SetAUPresetFromDocument (CFPropertyListRef &inData)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_ClassInfoFromDocument,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (CFPropertyListRef));
+}
+#endif
+
+OSStatus CAAudioUnit::GetPresentPreset (AUPreset &outData) const
+{
+ UInt32 dataSize = sizeof(outData);
+ OSStatus result = AudioUnitGetProperty (AU(), kAudioUnitProperty_PresentPreset,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+#if !TARGET_OS_IPHONE
+#ifndef __LP64__
+ if (result == kAudioUnitErr_InvalidProperty) {
+ dataSize = sizeof(outData);
+ result = AudioUnitGetProperty (AU(), kAudioUnitProperty_CurrentPreset,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+ if (result == noErr) {
+ // we now retain the CFString in the preset so for the client of this API
+ // it is consistent (ie. the string should be released when done)
+ if (outData.presetName)
+ CFRetain (outData.presetName);
+ }
+ }
+#endif
+#endif
+ return result;
+}
+
+OSStatus CAAudioUnit::SetPresentPreset (AUPreset &inData)
+{
+ OSStatus result = AudioUnitSetProperty (AU(), kAudioUnitProperty_PresentPreset,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (AUPreset));
+#if !TARGET_OS_IPHONE
+#ifndef __LP64__
+ if (result == kAudioUnitErr_InvalidProperty) {
+ result = AudioUnitSetProperty (AU(), kAudioUnitProperty_CurrentPreset,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (AUPreset));
+ }
+#endif
+#endif
+ return result;
+}
+
+bool CAAudioUnit::HasCustomView () const
+{
+#if !TARGET_OS_IPHONE
+ UInt32 dataSize = 0;
+ OSStatus result = -4/*unimpErr*/;
+#ifndef __LP64__
+ result = GetPropertyInfo(kAudioUnitProperty_GetUIComponentList,
+ kAudioUnitScope_Global, 0,
+ &dataSize, NULL);
+#endif
+ if (result || !dataSize) {
+ dataSize = 0;
+ result = GetPropertyInfo(kAudioUnitProperty_CocoaUI,
+ kAudioUnitScope_Global, 0,
+ &dataSize, NULL);
+ if (result || !dataSize)
+ return false;
+ }
+ return true;
+#else
+ return false;
+#endif
+
+}
+
+OSStatus CAAudioUnit::GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const
+{
+ return mDataPtr ? mDataPtr->GetParameter (inID, scope, element, outValue) : static_cast<OSStatus>(paramErr);
+}
+
+OSStatus CAAudioUnit::SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames)
+{
+ return mDataPtr ? mDataPtr->SetParameter (inID, scope, element, value, bufferOffsetFrames) : static_cast<OSStatus>(paramErr);
+}
+
+OSStatus CAAudioUnit::MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame)
+{
+ return mDataPtr ? mDataPtr->MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame) : paramErr;
+}
+
+OSStatus CAAudioUnit::StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+{
+ return mDataPtr ? mDataPtr->StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams)
+ : paramErr;
+}
+
+OSStatus CAAudioUnit::StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame)
+{
+ return mDataPtr ? mDataPtr->StopNote (inGroupID, inNoteInstanceID, inOffsetSampleFrame) : paramErr;
+}
+
+
+#pragma mark __Render
+
+OSStatus CAAudioUnit::Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData)
+{
+ return mDataPtr ? mDataPtr->Render (ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData) : static_cast<OSStatus>(paramErr);
+}
+
+extern "C" OSStatus
+AudioUnitProcess ( AudioUnit inUnit,
+ AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData);
+
+OSStatus CAAudioUnit::Process (AudioUnitRenderActionFlags & ioActionFlags,
+ const AudioTimeStamp & inTimeStamp,
+ UInt32 inNumberFrames,
+ AudioBufferList & ioData)
+{
+#if defined(__MAC_10_7) || defined(__IPHONE_4_0)
+ return AudioUnitProcess (AU(), &ioActionFlags, &inTimeStamp, inNumberFrames, &ioData);
+#else
+ return -4/*unimpErr*/;
+#endif
+}
+
+extern "C" OSStatus
+AudioUnitProcessMultiple ( AudioUnit inUnit,
+ AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inNumberFrames,
+ UInt32 inNumberInputBufferLists,
+ const AudioBufferList ** inInputBufferLists,
+ UInt32 inNumberOutputBufferLists,
+ AudioBufferList ** ioOutputBufferLists);
+
+OSStatus CAAudioUnit::ProcessMultiple (AudioUnitRenderActionFlags & ioActionFlags,
+ const AudioTimeStamp & inTimeStamp,
+ UInt32 inNumberFrames,
+ UInt32 inNumberInputBufferLists,
+ const AudioBufferList ** inInputBufferLists,
+ UInt32 inNumberOutputBufferLists,
+ AudioBufferList ** ioOutputBufferLists)
+{
+#if defined(__MAC_10_7) || defined(__IPHONE_4_0)
+ return AudioUnitProcessMultiple (AU(), &ioActionFlags, &inTimeStamp, inNumberFrames,
+ inNumberInputBufferLists, inInputBufferLists, inNumberOutputBufferLists, ioOutputBufferLists);
+#else
+ return -4/*unimpErr*/;
+#endif
+}
+
+#pragma mark __CAAUChanHelper
+
+CAAUChanHelper::CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope)
+ :mChans(NULL), mNumEls(0), mDidAllocate(false)
+{
+ UInt32 elCount;
+ if (inAU.GetElementCount (inScope, elCount)) return;
+ if (elCount > kStaticElCount) {
+ mChans = new UInt32[elCount];
+ mDidAllocate = true;
+ memset (mChans, 0, sizeof(int) * elCount);
+ } else {
+ mChans = mStaticChans;
+ memset (mChans, 0, sizeof(int) * kStaticElCount);
+ }
+ for (unsigned int i = 0; i < elCount; ++i) {
+ UInt32 numChans;
+ if (inAU.NumberChannels (inScope, i, numChans)) return;
+ mChans[i] = numChans;
+ }
+ mNumEls = elCount;
+}
+
+CAAUChanHelper::CAAUChanHelper(UInt32 inMaxElems)
+ : mNumEls(inMaxElems), mDidAllocate(false)
+{
+ if (inMaxElems > kStaticElCount) {
+ mChans = new UInt32[inMaxElems];
+ mDidAllocate = true;
+ memset (mChans, 0, sizeof(int) * inMaxElems);
+ } else {
+ mChans = mStaticChans;
+ memset (mChans, 0, sizeof(int) * kStaticElCount);
+ }
+}
+
+CAAUChanHelper::~CAAUChanHelper()
+{
+ if (mDidAllocate) delete [] mChans;
+}
+
+CAAUChanHelper& CAAUChanHelper::operator= (const CAAUChanHelper &c)
+{
+ if (mDidAllocate) delete [] mChans;
+ if (c.mDidAllocate) {
+ mChans = new UInt32[c.mNumEls];
+ mDidAllocate = true;
+ } else {
+ mDidAllocate = false;
+ mChans = mStaticChans;
+ }
+ memcpy (mChans, c.mChans, c.mNumEls * sizeof(int));
+
+ return *this;
+}
+
+
+#pragma mark __Print Utilities
+
+void CAAudioUnit::Print (FILE* file) const
+{
+ fprintf (file, "AudioUnit:%p\n", AU());
+ if (IsValid()) {
+ fprintf (file, "\tnode=%ld\t", (long)GetAUNode()); Comp().Print (file);
+ }
+}
+
+#if CA_AU_USE_FAST_DISPATCH
+// Handle GetComponentInstanceStorage(ComponentInstance aComponentInstance)
+static void *LoadGetComponentInstanceStorage (void *inst)
+{
+ typedef void* (*GetComponentInstanceStorageProc)(void* aComponentInstance);
+ static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL;
+
+ static int sDoCSLoad = 1;
+ if (sDoCSLoad) {
+ sDoCSLoad = 0;
+ void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY);
+ if (!theImage) return NULL;
+
+ sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage");
+ }
+ if (sGetComponentInstanceStorageProc)
+ return (*sGetComponentInstanceStorageProc)(inst);
+ return NULL;
+}
+#endif
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.h
new file mode 100644
index 0000000000..07a522e912
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnit.h
@@ -0,0 +1,439 @@
+/*
+ File: CAAudioUnit.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAudioUnit_h__
+#define __CAAudioUnit_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <AudioUnit/AudioUnit.h>
+ #include <AudioToolbox/AUGraph.h>
+ #include <AudioUnit/MusicDevice.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <CoreAudioTypes.h>
+ #include <AudioUnit.h>
+ #include <MusicDevice.h>
+ #include <AUGraph.h>
+ #include <MusicDevice.h>
+#endif
+
+#include <vector>
+#include "CAStreamBasicDescription.h"
+#include "CAComponent.h"
+#include "CAAudioChannelLayout.h"
+
+// defined below
+class CAAUChanHelper;
+
+// These constructors will NOT throw exceptions - so "check" after creation if AU IsValid()
+// The destructor will NOT automatically close the AU down
+// This state should be managed by the Caller
+// once closed, the unit represented by this object is no longer valid
+// it is up to the user of this object to ensure its validity is in sync
+// if it is removed from a graph
+
+// methods that can significantly change the state of the AU (like its format) are
+// NOT const whereas those that don't change the externally related state of the AU are not const
+
+class CAAudioUnit {
+ enum {
+ paramErr = -50,
+ badComponentSelector = (long)0x80008002
+ };
+public:
+ typedef std::vector<AudioChannelLayoutTag> ChannelTagVector;
+ typedef ChannelTagVector::iterator ChannelTagVectorIter;
+
+public:
+ CAAudioUnit ()
+ : mDataPtr(0) {}
+
+ CAAudioUnit (const AudioUnit& inUnit);
+
+ CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit);
+
+ CAAudioUnit (const CAAudioUnit& y)
+ : mDataPtr(0) { *this = y; }
+
+ static OSStatus Open (const CAComponent& inComp, CAAudioUnit &outUnit);
+
+ ~CAAudioUnit ();
+
+ void Close ();
+
+
+ CAAudioUnit& operator= (const CAAudioUnit& y);
+
+ bool operator== (const CAAudioUnit& y) const;
+
+ bool operator== (const AudioUnit& y) const;
+
+#pragma mark __State Management
+ bool IsValid () const;
+
+ AudioUnit AU() const;
+ operator AudioUnit () const { return AU(); }
+
+ const CAComponent& Comp() const { return mComp; }
+
+ const CAComponentDescription& Desc() const { return mComp.Desc(); }
+
+ bool FromAUGraph () const { return GetAUNode() != 0 && GetAUNode() != kCAAU_DoNotKnowIfAUNode; }
+
+ AUNode GetAUNode () const;
+ operator AUNode () const { return GetAUNode(); }
+
+#pragma mark __API Wrapper
+ OSStatus Initialize() const {
+ return AudioUnitInitialize(AU());
+ }
+ OSStatus Uninitialize() const {
+ return AudioUnitUninitialize(AU());
+ }
+ OSStatus GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ UInt32 *outDataSize, Boolean *outWritable) const
+ {
+ return AudioUnitGetPropertyInfo(AU(), propID, scope, element, outDataSize, outWritable);
+ }
+ OSStatus GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ void *outData, UInt32 *ioDataSize) const
+ {
+ return AudioUnitGetProperty(AU(), propID, scope, element, outData, ioDataSize);
+ }
+ OSStatus SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ const void *inData, UInt32 inDataSize)
+ {
+ return AudioUnitSetProperty(AU(), propID, scope, element, inData, inDataSize);
+ }
+ OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames=0);
+
+ OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const;
+
+ OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData);
+
+ OSStatus Process (AudioUnitRenderActionFlags & ioActionFlags,
+ const AudioTimeStamp & inTimeStamp,
+ UInt32 inNumberFrames,
+ AudioBufferList & ioData);
+
+ OSStatus ProcessMultiple (AudioUnitRenderActionFlags & ioActionFlags,
+ const AudioTimeStamp & inTimeStamp,
+ UInt32 inNumberFrames,
+ UInt32 inNumberInputBufferLists,
+ const AudioBufferList ** inInputBufferLists,
+ UInt32 inNumberOutputBufferLists,
+ AudioBufferList ** ioOutputBufferLists);
+
+
+ OSStatus Reset (AudioUnitScope scope, AudioUnitElement element)
+ {
+ return AudioUnitReset (AU(), scope, element);
+ }
+ OSStatus GlobalReset ()
+ {
+ return AudioUnitReset (AU(), kAudioUnitScope_Global, 0);
+ }
+
+ OSStatus AddRenderNotify (AURenderCallback inProc, void *inProcRefCon)
+ {
+ return AudioUnitAddRenderNotify (AU(), inProc, inProcRefCon);
+ }
+
+ OSStatus RemoveRenderNotify (AURenderCallback inProc, void *inProcRefCon)
+ {
+ return AudioUnitRemoveRenderNotify (AU(), inProc, inProcRefCon);
+ }
+
+ OSStatus AddPropertyListener (AudioUnitPropertyID inID,
+ AudioUnitPropertyListenerProc inProc,
+ void * inProcRefCon)
+ {
+ return AudioUnitAddPropertyListener (AU(), inID, inProc, inProcRefCon);
+ }
+
+ OSStatus RemovePropertyListener (AudioUnitPropertyID inID,
+ AudioUnitPropertyListenerProc inProc,
+ void * inProcUserData);
+
+ OSStatus MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame);
+
+ // uses the default VoiceForGroup value - this is the normal case
+ OSStatus StartNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+ {
+ return StartNote (kMusicNoteEvent_UseGroupInstrument,
+ inGroupID, outNoteInstanceID,
+ inOffsetSampleFrame, inParams);
+ }
+
+ OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams);
+
+ OSStatus StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame);
+
+#pragma mark __Format Utilities
+ // typically you ask this about an AU
+ // These Questions are asking about Input and Output...
+
+ // These ones just say whether an AU can do a single combination of channels
+ // and is fine if the AU has a single output (and if an input, a single input)
+ bool CanDo (int inChannelsInOut) const
+ {
+ return CanDo (inChannelsInOut, inChannelsInOut);
+ }
+
+ bool CanDo ( int inChannelsIn,
+ int inChannelsOut) const;
+
+ // This version does a more thorough test for ANY AU with ANY ins/outs
+ // you pass in the channel helper (for the current element count on that scope)
+
+ bool CanDo ( const CAAUChanHelper &input,
+ const CAAUChanHelper &output) const;
+
+ bool SupportsNumChannels () const;
+
+ bool HasChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl) const;
+
+ int GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt);
+ OSStatus GetChannelLayoutTags (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ ChannelTagVector &outChannelVector) const;
+
+ bool HasChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl) const;
+
+ OSStatus GetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &outLayout) const;
+
+ OSStatus SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const CAAudioChannelLayout &inLayout);
+
+ OSStatus SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioChannelLayout &inLayout,
+ UInt32 inSize);
+
+ OSStatus ClearChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl);
+
+ OSStatus GetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioStreamBasicDescription &outFormat) const;
+ // if an AudioChannelLayout is either required or set, this call can fail
+ // and the SetChannelLayout call should be used to set the format
+ OSStatus SetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioStreamBasicDescription &inFormat);
+
+ OSStatus GetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 &outRate) const;
+ OSStatus SetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 inRate);
+
+ // this sets the sample rate on all in/out buses of the AU
+ OSStatus SetSampleRate (Float64 inSampleRate);
+
+ OSStatus NumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const;
+
+ OSStatus GetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const
+ {
+ return NumberChannels (inScope, inEl, outChans);
+ }
+
+ OSStatus SetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 inChans);
+
+ OSStatus IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const;
+
+ OSStatus GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const;
+
+ OSStatus SetElementCount (AudioUnitScope inScope, UInt32 inCount);
+
+ // value of -1 for outTotalNumChannels indicates no restriction on num channels
+ // for ex. the Matrix Mixer satisfies this (its in/out element count is writable, and can be set to
+ // any number of channels.
+ // outTotalNumChannels is only valid if method returns true...
+ bool HasDynamicInputs (SInt32 &outTotalNumChannels) const
+ {
+ return HasDynamicScope (kAudioUnitScope_Input, outTotalNumChannels);
+ }
+
+ bool HasDynamicOutputs (SInt32 &outTotalNumChannels) const
+ {
+ return HasDynamicScope (kAudioUnitScope_Output, outTotalNumChannels);
+ }
+
+ // here, if the in (or out) elements are dynamic, then you supply the number of elements
+ // you want on in (or out) scope, and the number of channels on each consecutive element
+ OSStatus ConfigureDynamicInput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
+ {
+ return ConfigureDynamicScope (kAudioUnitScope_Input, inNumElements, inChannelsPerElement, inSampleRate);
+ }
+
+ OSStatus ConfigureDynamicOutput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
+ {
+ return ConfigureDynamicScope (kAudioUnitScope_Output, inNumElements, inChannelsPerElement, inSampleRate);
+ }
+
+ bool CanBypass () const;
+
+ bool GetBypass () const;
+
+ OSStatus SetBypass (bool inBypass) const;
+
+ OSStatus GetMaxFramesPerSlice (UInt32& outMaxFrames) const;
+
+ OSStatus SetMaxFramesPerSlice (UInt32 inMaxFrames);
+
+ Float64 Latency () const;
+
+ // these calls just deal with the global preset state
+ // you could rescope them to deal with presets on the part scope
+ OSStatus GetAUPreset (CFPropertyListRef &outData) const;
+
+ OSStatus SetAUPreset (CFPropertyListRef &inData);
+
+ OSStatus SetAUPresetFromDocument (CFPropertyListRef &inData);
+
+ OSStatus GetPresentPreset (AUPreset &outData) const;
+
+ OSStatus SetPresentPreset (AUPreset &inData);
+
+ bool HasCustomView () const;
+
+#pragma mark __Print
+ void Print () const { Print (stdout); }
+ void Print (FILE* file) const;
+
+private:
+ CAComponent mComp;
+
+ class AUState;
+ AUState* mDataPtr;
+
+ // this can throw - so wrap this up in a static that returns a result code...
+ CAAudioUnit (const CAComponent& inComp);
+
+ bool HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const;
+ OSStatus ConfigureDynamicScope (AudioUnitScope inScope,
+ UInt32 inNumElements,
+ UInt32 *inChannelsPerElement,
+ Float64 inSampleRate);
+ bool ValidateChannelPair (int inChannelsIn,
+ int inChannelsOut,
+ const AUChannelInfo * info,
+ UInt32 numChanInfo) const;
+
+ bool ValidateDynamicScope (AudioUnitScope inScope,
+ SInt32 &outTotalNumChannels,
+ const AUChannelInfo * info,
+ UInt32 numInfo) const;
+ bool CheckOneSide (const CAAUChanHelper &inHelper,
+ bool checkOutput,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const;
+ enum {
+ kCAAU_DoNotKnowIfAUNode = -1
+ };
+};
+
+class CAAUChanHelper {
+public:
+ CAAUChanHelper()
+ : mChans(mStaticChans), mNumEls(0), mDidAllocate(false)
+ {
+ memset (mChans, 0, sizeof(UInt32) * kStaticElCount);
+ }
+ CAAUChanHelper(UInt32 inMaxElems);
+ CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope);
+ CAAUChanHelper (const CAAUChanHelper &c)
+ : mChans(mStaticChans), mNumEls(0), mDidAllocate(false)
+ { *this = c; }
+
+ ~CAAUChanHelper();
+
+ CAAUChanHelper& operator= (const CAAUChanHelper &c);
+
+ UInt32 * mChans;
+ UInt32 mNumEls;
+
+private:
+ enum {
+ kStaticElCount = 8
+ };
+ UInt32 mStaticChans[kStaticElCount];
+ bool mDidAllocate;
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnitOutputCapturer.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnitOutputCapturer.h
new file mode 100644
index 0000000000..42bebfacc3
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioUnitOutputCapturer.h
@@ -0,0 +1,143 @@
+/*
+ File: CAAudioUnitOutputCapturer.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAAudioUnitOutputCapturer_h__
+#define __CAAudioUnitOutputCapturer_h__
+
+#include <AudioToolbox/ExtendedAudioFile.h>
+
+/*
+ Class to capture output from an AudioUnit for analysis.
+
+ example:
+
+ CFURL fileurl = CFURLCreateWithFileSystemPath(NULL, CFSTR("/tmp/recording.caf"), kCFURLPOSIXPathStyle, false);
+
+ CAAudioUnitOutputCapturer captor(someAU, fileurl, 'caff', anASBD);
+
+ {
+ captor.Start();
+ ...
+ captor.Stop();
+ } // can repeat
+
+ captor.Close(); // can be omitted; happens automatically from destructor
+*/
+
+class CAAudioUnitOutputCapturer {
+public:
+ enum { noErr = 0 };
+
+ CAAudioUnitOutputCapturer(AudioUnit au, CFURLRef outputFileURL, AudioFileTypeID fileType, const AudioStreamBasicDescription &format, UInt32 busNumber = 0) :
+ mFileOpen(false),
+ mClientFormatSet(false),
+ mAudioUnit(au),
+ mExtAudioFile(NULL),
+ mBusNumber (busNumber)
+ {
+ CFShow(outputFileURL);
+ OSStatus err = ExtAudioFileCreateWithURL(outputFileURL, fileType, &format, NULL, kAudioFileFlags_EraseFile, &mExtAudioFile);
+ if (!err)
+ mFileOpen = true;
+ }
+
+ void Start() {
+ if (mFileOpen) {
+ if (!mClientFormatSet) {
+ AudioStreamBasicDescription clientFormat;
+ UInt32 size = sizeof(clientFormat);
+ AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, mBusNumber, &clientFormat, &size);
+ ExtAudioFileSetProperty(mExtAudioFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
+ mClientFormatSet = true;
+ }
+ ExtAudioFileWriteAsync(mExtAudioFile, 0, NULL); // initialize async writes
+ AudioUnitAddRenderNotify(mAudioUnit, RenderCallback, this);
+ }
+ }
+
+ void Stop() {
+ if (mFileOpen)
+ AudioUnitRemoveRenderNotify(mAudioUnit, RenderCallback, this);
+ }
+
+ void Close() {
+ if (mExtAudioFile) {
+ ExtAudioFileDispose(mExtAudioFile);
+ mExtAudioFile = NULL;
+ }
+ }
+
+ ~CAAudioUnitOutputCapturer() {
+ Close();
+ }
+
+private:
+ static OSStatus RenderCallback( void * inRefCon,
+ AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData)
+ {
+ if (*ioActionFlags & kAudioUnitRenderAction_PostRender) {
+ CAAudioUnitOutputCapturer *This = (CAAudioUnitOutputCapturer *)inRefCon;
+ static int TEMP_kAudioUnitRenderAction_PostRenderError = (1 << 8);
+ if (This->mBusNumber == inBusNumber && !(*ioActionFlags & TEMP_kAudioUnitRenderAction_PostRenderError)) {
+ OSStatus result = ExtAudioFileWriteAsync(This->mExtAudioFile, inNumberFrames, ioData);
+ if (result) DebugMessageN1("ERROR WRITING FRAMES: %d\n", (int)result);
+ }
+ }
+ return noErr;
+ }
+
+ bool mFileOpen;
+ bool mClientFormatSet;
+ AudioUnit mAudioUnit;
+ ExtAudioFileRef mExtAudioFile;
+ UInt32 mBusNumber;
+};
+
+#endif // __CAAudioUnitOutputCapturer_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.cpp
new file mode 100644
index 0000000000..203e437af6
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.cpp
@@ -0,0 +1,262 @@
+/*
+ File: CAAudioValueRange.cpp
+ Abstract: CAAudioValueRange.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAAudioValueRange.h"
+
+// Standard Library
+#include <algorithm>
+
+//==================================================================================================
+// CAAudioValueRange
+//==================================================================================================
+
+Float64 CAAudioValueRange::BoundValue(const AudioValueRange& inRange, Float64 inValue)
+{
+ if (inValue <= inRange.mMinimum)
+ {
+ return inRange.mMinimum;
+ }
+ else if (inValue >= inRange.mMaximum)
+ {
+ return inRange.mMaximum;
+ }
+ else
+ {
+ return inValue;
+ }
+}
+
+Float64 CAAudioValueRange::PickCommonSampleRate(const AudioValueRange& inRange)
+{
+ // This routine will pick a "common" sample rate from the give range of rates or the maximum
+ // if no common rates can be found. It assumes that inRange contains a continuous range of
+ // sample rates.
+ Float64 theAnswer = inRange.mMaximum;
+
+ if(ContainsValue(inRange, 44100.0))
+ {
+ theAnswer = 44100.0;
+ }
+ else if(ContainsValue(inRange, 48000.0))
+ {
+ theAnswer = 48000.0;
+ }
+ else if(ContainsValue(inRange, 96000.0))
+ {
+ theAnswer = 96000.0;
+ }
+ else if(ContainsValue(inRange, 88200.0))
+ {
+ theAnswer = 88200.0;
+ }
+ else if(ContainsValue(inRange, 64000.0))
+ {
+ theAnswer = 64000.0;
+ }
+ else if(ContainsValue(inRange, 32000.0))
+ {
+ theAnswer = 32000.0;
+ }
+ else if(ContainsValue(inRange, 24000.0))
+ {
+ theAnswer = 24000.0;
+ }
+ else if(ContainsValue(inRange, 22050.0))
+ {
+ theAnswer = 22050.0;
+ }
+ else if(ContainsValue(inRange, 16000.0))
+ {
+ theAnswer = 16000.0;
+ }
+ else if(ContainsValue(inRange, 12000.0))
+ {
+ theAnswer = 12000.0;
+ }
+ else if(ContainsValue(inRange, 11025.0))
+ {
+ theAnswer = 11025.0;
+ }
+ else if(ContainsValue(inRange, 8000.0))
+ {
+ theAnswer = 8000.0;
+ }
+
+ return theAnswer;
+}
+
+bool CAAudioValueRange::Intersection(const AudioValueRange& x, const AudioValueRange& y, AudioValueRange& outRange)
+{
+ bool isNonEmpty;
+ if(!IsStrictlyLessThan(x, y) && !IsStrictlyGreaterThan(x, y))
+ {
+ outRange.mMinimum = std::max(x.mMinimum, y.mMinimum);
+ outRange.mMaximum = std::min(x.mMaximum, y.mMaximum);
+ isNonEmpty = true;
+ }
+ else
+ {
+ outRange.mMinimum = 0;
+ outRange.mMaximum = 0;
+ isNonEmpty = false;
+ }
+ return isNonEmpty;
+}
+
+bool CAAudioValueRange::Union(const AudioValueRange& x, const AudioValueRange& y, AudioValueRange& outRange)
+{
+ bool isDisjoint;
+ if(!IsStrictlyLessThan(x, y) && !IsStrictlyGreaterThan(x, y))
+ {
+ outRange.mMinimum = std::min(x.mMinimum, y.mMinimum);
+ outRange.mMaximum = std::max(x.mMaximum, y.mMaximum);
+ isDisjoint = false;
+ }
+ else
+ {
+ outRange.mMinimum = 0;
+ outRange.mMaximum = 0;
+ isDisjoint = true;
+ }
+ return isDisjoint;
+}
+
+void CAAudioValueRange_ComputeUnion(const AudioValueRange& inRange, const CAAudioValueRangeList& inRangeList, CAAudioValueRangeList& outUnion)
+{
+ // this method assumes that the ranges in inRangeList are disjoint and that they are sorted from low to high and
+ outUnion.clear();
+
+ // start at the beginning of inRangeList
+ CAAudioValueRangeList::const_iterator theIterator = inRangeList.begin();
+
+ // iterate through inRangeList and add all the ranges that are strictly less than inRange
+ while((theIterator != inRangeList.end()) && CAAudioValueRange::IsStrictlyLessThan(*theIterator, inRange))
+ {
+ // put this range in the union
+ outUnion.push_back(*theIterator);
+
+ // go to the next one
+ std::advance(theIterator, 1);
+ }
+
+ if(theIterator != inRangeList.end())
+ {
+ if(!CAAudioValueRange::IsStrictlyGreaterThan(*theIterator, inRange))
+ {
+ // inRange intersects the range that theIterator points at, but might actually intersect several contiguous ranges
+
+ // initialize the starting point, noting that we can skip the current one since we already know it's in the intersection
+ CAAudioValueRangeList::const_iterator theGreaterIterator = theIterator;
+ std::advance(theGreaterIterator, 1);
+
+ // iterate until we find a range that is strictly greater than inRange
+ while((theGreaterIterator != inRangeList.end()) && !CAAudioValueRange::IsStrictlyGreaterThan(*theGreaterIterator, inRange))
+ {
+ // go to the next one
+ std::advance(theGreaterIterator, 1);
+ }
+
+ // theGreaterIterator now points at either one past the highest range in the intersection or the end of the vector
+ // Either way, we have to adjust it to point at the true highest range in the intersection
+ std::advance(theGreaterIterator, -1);
+
+ // now theIterator points at the lowest range in the intersection and theGreaterIterator points at the highest
+ // so we can compute the coagulated range
+ AudioValueRange theCoagulation;
+ theCoagulation.mMinimum = std::min(theIterator->mMinimum, inRange.mMinimum);
+ theCoagulation.mMaximum = std::max(theGreaterIterator->mMaximum, inRange.mMaximum);
+
+ // add the coagulation to the union
+ outUnion.push_back(theCoagulation);
+
+ // adjust theIterator to point at the next range for processing
+ theIterator = theGreaterIterator;
+ std::advance(theIterator, 1);
+ }
+ else
+ {
+ // the range theIterator points at is strictly greater than inRange, so insert inRange in front of it and we're done
+ outUnion.push_back(inRange);
+ }
+
+ // we need to now copy the remaining higher ranges in inRangeList into the union
+ while(theIterator != inRangeList.end())
+ {
+ // put this range in the union
+ outUnion.push_back(*theIterator);
+
+ // go to the next one
+ std::advance(theIterator, 1);
+ }
+ }
+ else
+ {
+ // inRange is larger than all of the ranges in inRangeList, so just add it onto the end of the union and we're done
+ // This is also the case if inRangeList is empty
+ outUnion.push_back(inRange);
+ }
+}
+
+void CAAudioValueRange_ComputeIntersection(UInt32 inNumberRangeList1Items, AudioValueRange inRangeList1[], const CAAudioValueRangeList& inRangeList2, CAAudioValueRangeList& outIntersections)
+{
+ outIntersections.clear();
+ for(UInt32 theRangeList1Index = 0; theRangeList1Index < inNumberRangeList1Items; ++theRangeList1Index)
+ {
+ for(CAAudioValueRangeList::const_iterator theRangeList2Iterator = inRangeList2.begin(); theRangeList2Iterator != inRangeList2.end(); std::advance(theRangeList2Iterator, 1))
+ {
+ AudioValueRange theIntersection;
+ if(CAAudioValueRange::Intersection(inRangeList1[theRangeList1Index], *theRangeList2Iterator, theIntersection))
+ {
+ outIntersections.push_back(theIntersection);
+ }
+ }
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.h b/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.h
new file mode 100644
index 0000000000..e17c4574bc
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAudioValueRange.h
@@ -0,0 +1,121 @@
+/*
+ File: CAAudioValueRange.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAAudioValueRange_h__)
+#define __CAAudioValueRange_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+// Standard Library Includes
+#include <functional>
+#include <vector>
+
+//=============================================================================
+// CAAudioValueRange
+//=============================================================================
+
+struct CAAudioValueRange
+:
+ public AudioValueRange
+{
+
+// Construction/Destruction
+public:
+ CAAudioValueRange() { mMinimum = 0.0; mMaximum = 0.0; }
+ CAAudioValueRange(const AudioValueRange& v) { mMinimum = v.mMinimum; mMaximum = v.mMaximum; }
+ CAAudioValueRange(Float64 inMinimum, Float64 inMaximum) { mMinimum = inMinimum; mMaximum = inMaximum; }
+
+// Assignment
+public:
+ CAAudioValueRange& operator=(const AudioValueRange& v) { mMinimum = v.mMinimum; mMaximum = v.mMaximum; return *this; }
+
+// Operations
+public:
+ static bool ContainsValue(const AudioValueRange& inRange, Float64 inValue) { return (inValue >= inRange.mMinimum) && (inValue <= inRange.mMaximum); }
+ static Float64 BoundValue(const AudioValueRange& inRange, Float64 inValue);
+ static Float64 PickCommonSampleRate(const AudioValueRange& inRange);
+ static bool IsStrictlyLessThan(const AudioValueRange& x, const AudioValueRange& y) { return x.mMaximum < y.mMinimum; }
+ static bool IsStrictlyGreaterThan(const AudioValueRange& x, const AudioValueRange& y) { return x.mMinimum > y.mMaximum; }
+ static bool IsStrictlyContainedBy(const AudioValueRange& x, const AudioValueRange& y) { return (x.mMinimum >= y.mMinimum) && (x.mMaximum <= y.mMaximum); }
+ static bool OverlapsLow(const AudioValueRange& x, const AudioValueRange& y) { return (x.mMinimum < y.mMinimum) && (x.mMaximum >= y.mMinimum) && (x.mMaximum <= y.mMaximum); }
+ static bool OverlapsHigh(const AudioValueRange& x, const AudioValueRange& y) { return (x.mMinimum >= y.mMinimum) && (x.mMinimum <= y.mMaximum) && (x.mMaximum > y.mMaximum); }
+ static bool Intersection(const AudioValueRange& x, const AudioValueRange& y, AudioValueRange& outRange);
+ static bool Union(const AudioValueRange& x, const AudioValueRange& y, AudioValueRange& outRange);
+
+// STL Helpers
+public:
+ struct LessThan
+ :
+ public std::binary_function<AudioValueRange, AudioValueRange, bool>
+ {
+ bool operator()(const AudioValueRange& x, const AudioValueRange& y) const
+ {
+ return x.mMinimum < y.mMinimum;
+ }
+ };
+
+};
+
+inline bool operator<(const AudioValueRange& x, const AudioValueRange& y) { return x.mMinimum < y.mMinimum; }
+inline bool operator==(const AudioValueRange& x, const AudioValueRange& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
+inline bool operator!=(const AudioValueRange& x, const AudioValueRange& y) { return !(x == y); }
+inline bool operator<=(const AudioValueRange& x, const AudioValueRange& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioValueRange& x, const AudioValueRange& y) { return !(x < y); }
+inline bool operator>(const AudioValueRange& x, const AudioValueRange& y) { return !((x < y) || (x == y)); }
+
+typedef std::vector<CAAudioValueRange> CAAudioValueRangeList;
+void CAAudioValueRange_ComputeUnion(const AudioValueRange& inRange, const CAAudioValueRangeList& inRangeList, CAAudioValueRangeList& outUnion);
+void CAAudioValueRange_ComputeIntersection(UInt32 inNumberRangeList1Items, AudioValueRange inRangeList1[], const CAAudioValueRangeList& inRangeList2, CAAudioValueRangeList& outIntersections);
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h b/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h
new file mode 100644
index 0000000000..2da241506c
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAAutoDisposer.h
@@ -0,0 +1,508 @@
+/*
+ File: CAAutoDisposer.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAPtr_h__)
+#define __CAPtr_h__
+
+#include <stdlib.h> // for malloc
+#include <new> // for bad_alloc
+#include <string.h> // for memset
+
+inline void* CA_malloc(size_t size)
+{
+ void* p = malloc(size);
+ if (!p && size) throw std::bad_alloc();
+ return p;
+}
+
+inline void* CA_realloc(void* old, size_t size)
+{
+#if TARGET_OS_WIN32
+ void* p = realloc(old, size);
+#else
+ void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL).
+#endif
+ if (!p && size) throw std::bad_alloc();
+ return p;
+}
+
+#ifndef UINTPTR_MAX
+#if __LP64__
+#define UINTPTR_MAX 18446744073709551615ULL
+#else
+#define UINTPTR_MAX 4294967295U
+#endif
+#endif
+
+inline void* CA_calloc(size_t n, size_t size)
+{
+ // ensure that multiplication will not overflow
+ if (n && UINTPTR_MAX / n < size) throw std::bad_alloc();
+
+ size_t nsize = n*size;
+ void* p = malloc(nsize);
+ if (!p && nsize) throw std::bad_alloc();
+
+ memset(p, 0, nsize);
+ return p;
+}
+
+
+// helper class for automatic conversions
+template <typename T>
+struct CAPtrRef
+{
+ T* ptr_;
+
+ explicit CAPtrRef(T* ptr) : ptr_(ptr) {}
+};
+
+template <typename T>
+class CAAutoFree
+{
+private:
+ T* ptr_;
+
+public:
+
+ CAAutoFree() : ptr_(0) {}
+
+ explicit CAAutoFree(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership
+
+ CAAutoFree(size_t n, bool clear = false)
+ // this becomes an ambiguous call if n == 0
+ : ptr_(0)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (n > maxItems)
+ throw std::bad_alloc();
+
+ ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T)));
+ }
+
+ ~CAAutoFree() { free(); }
+
+ void alloc(size_t numItems, bool clear = false)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (numItems > maxItems) throw std::bad_alloc();
+
+ free();
+ ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T)));
+ }
+
+ void allocBytes(size_t numBytes, bool clear = false)
+ {
+ free();
+ ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes));
+ }
+
+ void reallocBytes(size_t numBytes)
+ {
+ ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes));
+ }
+
+ void reallocItems(size_t numItems)
+ {
+ size_t maxItems = ~size_t(0) / sizeof(T);
+ if (numItems > maxItems) throw std::bad_alloc();
+
+ ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T)));
+ }
+
+ template <typename U>
+ CAAutoFree& operator=(CAAutoFree<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoFree& operator=(CAAutoFree& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoFree& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoFree& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ ::free(ptr_);
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoFree& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoFree<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+template <typename T>
+class CAAutoDelete
+{
+private:
+ T* ptr_;
+
+public:
+ CAAutoDelete() : ptr_(0) {}
+
+ explicit CAAutoDelete(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership
+
+ ~CAAutoDelete() { free(); }
+
+ template <typename U>
+ CAAutoDelete& operator=(CAAutoDelete<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoDelete& operator=(CAAutoDelete& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoDelete& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoDelete& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ delete ptr_;
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoDelete& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoFree<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+template <typename T>
+class CAAutoArrayDelete
+{
+private:
+ T* ptr_;
+
+public:
+ CAAutoArrayDelete() : ptr_(0) {}
+
+ explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {}
+
+ template<typename U>
+ CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership
+
+ // C++ std says: a template constructor is never a copy constructor
+ CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership
+
+ // this becomes an ambiguous call if n == 0
+ CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {}
+
+ ~CAAutoArrayDelete() { free(); }
+
+ void alloc(size_t numItems)
+ {
+ free();
+ ptr_ = new T [numItems];
+ }
+
+ template <typename U>
+ CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoArrayDelete& operator=(CAAutoArrayDelete& that)
+ {
+ set(that.release()); // take ownership
+ return *this;
+ }
+
+ CAAutoArrayDelete& operator=(T* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ template <typename U>
+ CAAutoArrayDelete& operator=(U* ptr)
+ {
+ set(ptr);
+ return *this;
+ }
+
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ T* operator()() const { return ptr_; }
+ T* get() const { return ptr_; }
+ operator T*() const { return ptr_; }
+
+ bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; }
+ bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; }
+ bool operator==(T* ptr) const { return ptr_ == ptr; }
+ bool operator!=(T* ptr) const { return ptr_ != ptr; }
+
+ T* release()
+ {
+ // release ownership
+ T* result = ptr_;
+ ptr_ = 0;
+ return result;
+ }
+
+ void set(T* ptr)
+ {
+ if (ptr != ptr_)
+ {
+ delete [] ptr_;
+ ptr_ = ptr;
+ }
+ }
+
+ void free()
+ {
+ set(0);
+ }
+
+
+ // automatic conversions to allow assignment from results of functions.
+ // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
+ CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
+
+ CAAutoArrayDelete& operator=(CAPtrRef<T> ref)
+ {
+ set(ref.ptr_);
+ return *this;
+ }
+
+ template<typename U>
+ operator CAPtrRef<U>()
+ { return CAPtrRef<U>(release()); }
+
+ template<typename U>
+ operator CAAutoArrayDelete<U>()
+ { return CAAutoFree<U>(release()); }
+
+};
+
+
+
+
+
+// convenience function
+template <typename T>
+void free(CAAutoFree<T>& p)
+{
+ p.free();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+// example program showing ownership transfer
+
+CAAutoFree<char> source()
+{
+ // source allocates and returns ownership to the caller.
+ const char* str = "this is a test";
+ size_t size = strlen(str) + 1;
+ CAAutoFree<char> captr(size, false);
+ strlcpy(captr(), str, size);
+ printf("source %08X %08X '%s'\n", &captr, captr(), captr());
+ return captr;
+}
+
+void user(CAAutoFree<char> const& captr)
+{
+ // passed by const reference. user can access the pointer but does not take ownership.
+ printf("user: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+void sink(CAAutoFree<char> captr)
+{
+ // passed by value. sink takes ownership and frees the pointer on return.
+ printf("sink: %08X %08X '%s'\n", &captr, captr(), captr());
+}
+
+
+int main (int argc, char * const argv[])
+{
+
+ CAAutoFree<char> captr(source());
+ printf("main captr A %08X %08X\n", &captr, captr());
+ user(captr);
+ sink(captr);
+ printf("main captr B %08X %08X\n", &captr, captr());
+ return 0;
+}
+#endif
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABitOperations.h b/libs/appleutility/CoreAudio/PublicUtility/CABitOperations.h
new file mode 100644
index 0000000000..21cb516a60
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABitOperations.h
@@ -0,0 +1,206 @@
+/*
+ File: CABitOperations.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef _CABitOperations_h_
+#define _CABitOperations_h_
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ //#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
+ #include <CoreFoundation/CFBase.h>
+#else
+// #include <MacTypes.h>
+ #include "CFBase.h"
+#endif
+#include <TargetConditionals.h>
+
+// return whether a number is a power of two
+inline UInt32 IsPowerOfTwo(UInt32 x)
+{
+ return (x & (x-1)) == 0;
+}
+
+// count the leading zeros in a word
+// Metrowerks Codewarrior. powerpc native count leading zeros instruction:
+// I think it's safe to remove this ...
+//#define CountLeadingZeroes(x) ((int)__cntlzw((unsigned int)x))
+
+inline UInt32 CountLeadingZeroes(UInt32 arg)
+{
+// GNUC / LLVM have a builtin
+#if defined(__GNUC__) || defined(__llvm___)
+#if (TARGET_CPU_X86 || TARGET_CPU_X86_64)
+ if (arg == 0) return 32;
+#endif // TARGET_CPU_X86 || TARGET_CPU_X86_64
+ return __builtin_clz(arg);
+#elif TARGET_OS_WIN32
+ UInt32 tmp;
+ __asm{
+ bsr eax, arg
+ mov ecx, 63
+ cmovz eax, ecx
+ xor eax, 31
+ mov tmp, eax // this moves the result in tmp to return.
+ }
+ return tmp;
+#else
+#error "Unsupported architecture"
+#endif // defined(__GNUC__)
+}
+// Alias (with different spelling)
+#define CountLeadingZeros CountLeadingZeroes
+
+inline UInt32 CountLeadingZeroesLong(UInt64 arg)
+{
+// GNUC / LLVM have a builtin
+#if defined(__GNUC__) || defined(__llvm___)
+#if (TARGET_CPU_X86 || TARGET_CPU_X86_64)
+ if (arg == 0) return 64;
+#endif // TARGET_CPU_X86 || TARGET_CPU_X86_64
+ return __builtin_clzll(arg);
+#elif TARGET_OS_WIN32
+ UInt32 x = CountLeadingZeroes((UInt32)(arg >> 32));
+ if(x < 32)
+ return x;
+ else
+ return 32+CountLeadingZeroes((UInt32)arg);
+#else
+#error "Unsupported architecture"
+#endif // defined(__GNUC__)
+}
+#define CountLeadingZerosLong CountLeadingZeroesLong
+
+// count trailing zeroes
+inline UInt32 CountTrailingZeroes(UInt32 x)
+{
+ return 32 - CountLeadingZeroes(~x & (x-1));
+}
+
+// count leading ones
+inline UInt32 CountLeadingOnes(UInt32 x)
+{
+ return CountLeadingZeroes(~x);
+}
+
+// count trailing ones
+inline UInt32 CountTrailingOnes(UInt32 x)
+{
+ return 32 - CountLeadingZeroes(x & (~x-1));
+}
+
+// number of bits required to represent x.
+inline UInt32 NumBits(UInt32 x)
+{
+ return 32 - CountLeadingZeroes(x);
+}
+
+// base 2 log of next power of two greater or equal to x
+inline UInt32 Log2Ceil(UInt32 x)
+{
+ return 32 - CountLeadingZeroes(x - 1);
+}
+
+// base 2 log of next power of two less or equal to x
+inline UInt32 Log2Floor(UInt32 x)
+{
+ return 32 - CountLeadingZeroes(x) - 1;
+}
+
+// next power of two greater or equal to x
+inline UInt32 NextPowerOfTwo(UInt32 x)
+{
+ return 1 << Log2Ceil(x);
+}
+
+// counting the one bits in a word
+inline UInt32 CountOnes(UInt32 x)
+{
+ // secret magic algorithm for counting bits in a word.
+ x = x - ((x >> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
+}
+
+// counting the zero bits in a word
+inline UInt32 CountZeroes(UInt32 x)
+{
+ return CountOnes(~x);
+}
+
+// return the bit position (0..31) of the least significant bit
+inline UInt32 LSBitPos(UInt32 x)
+{
+ return CountTrailingZeroes(x & -(SInt32)x);
+}
+
+// isolate the least significant bit
+inline UInt32 LSBit(UInt32 x)
+{
+ return x & -(SInt32)x;
+}
+
+// return the bit position (0..31) of the most significant bit
+inline UInt32 MSBitPos(UInt32 x)
+{
+ return 31 - CountLeadingZeroes(x);
+}
+
+// isolate the most significant bit
+inline UInt32 MSBit(UInt32 x)
+{
+ return 1 << MSBitPos(x);
+}
+
+// Division optimized for power of 2 denominators
+inline UInt32 DivInt(UInt32 numerator, UInt32 denominator)
+{
+ if(IsPowerOfTwo(denominator))
+ return numerator >> (31 - CountLeadingZeroes(denominator));
+ else
+ return numerator/denominator;
+}
+
+#endif
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABool.h b/libs/appleutility/CoreAudio/PublicUtility/CABool.h
new file mode 100644
index 0000000000..719fd74bb2
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABool.h
@@ -0,0 +1,89 @@
+/*
+ File: CABool.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CABool_h__)
+#define __CABool_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+
+//=============================================================================
+// CABool
+//
+// This class implements a boolean value that has a third state that marks
+// it as uninitialized. Accessing the value of an instance of this class that
+// is uninitialized will throw an exception.
+//=============================================================================
+
+class CABool
+{
+
+// Construction/Destruction
+public:
+ CABool() : mValue(-1) {}
+ CABool(bool inValue) : mValue(inValue ? 1 : 0) {}
+ CABool(const CABool& inValue) : mValue(inValue.mValue) {}
+ ~CABool() {}
+
+ CABool& operator=(bool inValue) { mValue = inValue; return *this; }
+ CABool& operator=(const CABool& inValue) { mValue = inValue.mValue; return *this; }
+
+ operator bool() const { ThrowIf(mValue == -1, CAException('nope'), "CABool: uninitialized"); return mValue != 0; }
+ bool IsInitialized() const { return mValue != -1; }
+ void Uninitialize() { mValue = -1; }
+
+private:
+ SInt32 mValue;
+
+ CABool(const void*); // prevent accidental instantiation with a pointer via bool constructor
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABufferList.cpp b/libs/appleutility/CoreAudio/PublicUtility/CABufferList.cpp
new file mode 100644
index 0000000000..3249013b59
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABufferList.cpp
@@ -0,0 +1,259 @@
+/*
+ File: CABufferList.cpp
+ Abstract: CABufferList.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CABufferList.h"
+#include "CAByteOrder.h"
+
+void CABufferList::AllocateBuffers(UInt32 nBytes)
+{
+ if (nBytes <= GetNumBytes()) return;
+
+ if (mABL.mNumberBuffers > 1)
+ // align successive buffers for Altivec and to take alternating
+ // cache line hits by spacing them by odd multiples of 16
+ nBytes = ((nBytes + 15) & ~15) | 16;
+ UInt32 memorySize = nBytes * mABL.mNumberBuffers;
+ Byte *newMemory = new Byte[memorySize], *p = newMemory;
+ memset(newMemory, 0, memorySize); // get page faults now, not later
+
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ if (buf->mData != NULL && buf->mDataByteSize > 0)
+ // preserve existing buffer contents
+ memcpy(p, buf->mData, buf->mDataByteSize);
+ buf->mDataByteSize = nBytes;
+ buf->mData = p;
+ p += nBytes;
+ }
+ Byte *oldMemory = mBufferMemory;
+ mBufferMemory = newMemory;
+ mBufferCapacity = nBytes;
+ delete[] oldMemory;
+}
+
+void CABufferList::AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inSrcList, CABufferList *inSetPtrList)
+{
+ if (mABL.mNumberBuffers != inSrcList->mABL.mNumberBuffers) return;
+ if (mABL.mNumberBuffers != inSetPtrList->mABL.mNumberBuffers) return;
+ if (nBytes <= GetNumBytes()) {
+ CopyAllFrom(inSrcList, inSetPtrList);
+ return;
+ }
+ inSetPtrList->VerifyNotTrashingOwnedBuffer();
+ UInt32 fromByteSize = inSrcList->GetNumBytes();
+
+ if (mABL.mNumberBuffers > 1)
+ // align successive buffers for Altivec and to take alternating
+ // cache line hits by spacing them by odd multiples of 16
+ nBytes = ((nBytes + 15) & ~15) | 16;
+ UInt32 memorySize = nBytes * mABL.mNumberBuffers;
+ Byte *newMemory = new Byte[memorySize], *p = newMemory;
+ memset(newMemory, 0, memorySize); // make buffer "hot"
+
+ AudioBuffer *buf = mABL.mBuffers;
+ AudioBuffer *ptrBuf = inSetPtrList->mABL.mBuffers;
+ AudioBuffer *srcBuf = inSrcList->mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf, ++ptrBuf, ++srcBuf) {
+ if (srcBuf->mData != NULL && srcBuf->mDataByteSize > 0)
+ // preserve existing buffer contents
+ memmove(p, srcBuf->mData, srcBuf->mDataByteSize);
+ buf->mDataByteSize = nBytes;
+ buf->mData = p;
+ ptrBuf->mDataByteSize = srcBuf->mDataByteSize;
+ ptrBuf->mData = p;
+ p += nBytes;
+ }
+ Byte *oldMemory = mBufferMemory;
+ mBufferMemory = newMemory;
+ mBufferCapacity = nBytes;
+ if (inSrcList != inSetPtrList)
+ inSrcList->BytesConsumed(fromByteSize);
+ delete[] oldMemory;
+}
+
+void CABufferList::DeallocateBuffers()
+{
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ buf->mData = NULL;
+ buf->mDataByteSize = 0;
+ }
+ if (mBufferMemory != NULL) {
+ delete[] mBufferMemory;
+ mBufferMemory = NULL;
+ mBufferCapacity = 0;
+ }
+
+}
+
+static void show(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label, const char *fmtstr=NULL)
+{
+ printf("%s %p (%d fr%s):\n", label ? label : "AudioBufferList", &abl, framesToPrint, fmtstr ? fmtstr : "");
+ const AudioBuffer *buf = abl.mBuffers;
+ for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++buf) {
+ printf(" [%2d] %5dbytes %dch @ %p", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
+ if (framesToPrint && buf->mData != NULL) {
+ printf(":");
+ Byte *p = (Byte *)buf->mData;
+ for (int j = framesToPrint * buf->mNumberChannels; --j >= 0; )
+ switch (wordSize) {
+ case 0: // native float
+ printf(" %6.3f", *(Float32 *)p);
+ p += sizeof(Float32);
+ break;
+ // positive: big endian
+ case 1:
+ case -1:
+ printf(" %02X", *p);
+ p += 1;
+ break;
+ case 2:
+ printf(" %04X", CFSwapInt16BigToHost(*(UInt16 *)p));
+ p += 2;
+ break;
+ case 3:
+ printf(" %06X", (p[0] << 16) | (p[1] << 8) | p[2]);
+ p += 3;
+ break;
+ case 4:
+ printf(" %08X", (unsigned int)CFSwapInt32BigToHost(*(UInt32 *)p));
+ p += 4;
+ break;
+ case 10:
+ printf(" %6.3f", CASwapFloat32BigToHost(*(Float32 *)p));
+ p += sizeof(Float32);
+ break;
+ case -2:
+ printf(" %04X", CFSwapInt16LittleToHost(*(UInt16 *)p));
+ p += 2;
+ break;
+ case -3:
+ printf(" %06X", (p[2] << 16) | (p[1] << 8) | p[0]);
+ p += 3;
+ break;
+ case -4:
+ printf(" %08X", (unsigned int)CFSwapInt32LittleToHost(*(UInt32 *)p));
+ p += 4;
+ break;
+ case -10:
+ printf(" %6.3f", CASwapFloat32LittleToHost(*(Float32 *)p));
+ p += sizeof(Float32);
+ break;
+ }
+ }
+ printf("\n");
+ }
+}
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &asbd, const char *label)
+{
+ CAStreamBasicDescription fmt(asbd);
+ int wordSize = 1;
+ char fmtstr[80] = { 0 };
+
+ if (fmt.mFormatID == kAudioFormatLinearPCM) {
+ if (fmt.mFormatFlags & kLinearPCMFormatFlagIsFloat) {
+ if (fmt.mBitsPerChannel == 32) {
+ if (fmt.mFormatFlags & kLinearPCMFormatFlagIsBigEndian) {
+ wordSize = 10;
+ strlcpy(fmtstr, ", BEF", sizeof(fmtstr));
+ } else {
+ wordSize = -10;
+ strlcpy(fmtstr, ", LEF", sizeof(fmtstr));
+ }
+ }
+ } else {
+ wordSize = fmt.SampleWordSize();
+ if (wordSize > 0) {
+ int fracbits = (asbd.mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+ if (fracbits > 0)
+ snprintf(fmtstr, sizeof(fmtstr), ", %d.%d-bit", (int)asbd.mBitsPerChannel - fracbits, fracbits);
+ else
+ snprintf(fmtstr, sizeof(fmtstr), ", %d-bit", (int)asbd.mBitsPerChannel);
+
+ if (!(fmt.mFormatFlags & kLinearPCMFormatFlagIsBigEndian)) {
+ wordSize = -wordSize;
+ strlcat(fmtstr, " LEI", sizeof(fmtstr));
+ } else {
+ strlcat(fmtstr, " BEI", sizeof(fmtstr));
+ }
+ }
+ }
+ }
+ show(abl, framesToPrint, wordSize, label, fmtstr);
+}
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label)
+{
+ show(abl, framesToPrint, wordSize, label);
+}
+
+extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize)
+{
+ show(*abl, framesToPrint, wordSize, NULL);
+}
+
+// if the return result is odd, there was a null buffer.
+extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullok)
+{
+ const AudioBuffer *buf = abl->mBuffers, *bufend = buf + abl->mNumberBuffers;
+ int sum = 0; // defeat attempts by the compiler to optimize away the code that touches the buffers
+ int anyNull = 0;
+ for ( ; buf < bufend; ++buf) {
+ const int *p = (const int *)buf->mData;
+ if (p == NULL) {
+ anyNull = 1;
+ if (nullok) continue;
+ }
+ unsigned datasize = buf->mDataByteSize;
+ if (datasize >= sizeof(int) && p != NULL) {
+ sum += p[0];
+ sum += p[datasize / sizeof(int) - 1];
+ }
+ }
+ return anyNull | (sum & ~1);
+}
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABufferList.h b/libs/appleutility/CoreAudio/PublicUtility/CABufferList.h
new file mode 100644
index 0000000000..72c93f8626
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABufferList.h
@@ -0,0 +1,324 @@
+/*
+ File: CABufferList.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CABufferList_h__
+#define __CABufferList_h__
+
+#include <stddef.h>
+#include "CAStreamBasicDescription.h"
+#include "CAXException.h"
+
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &fmt, const char *label=NULL);
+void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label=NULL);
+extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize);
+extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullOK=false);
+
+/* ____________________________________________________________________________
+// CABufferList - variable length buffer list
+
+ This class is designed for use in non-simplistic cases. For AudioUnits, AUBufferList
+ is preferred.
+
+ CABufferList can be used in one of two ways:
+ - as mutable pointers into non-owned memory
+ - as an immutable array of buffers (owns its own memory).
+
+ All buffers are assumed to have the same format (number of channels, word size), so that
+ we can assume their mDataByteSizes are all the same.
+____________________________________________________________________________ */
+class CABufferList {
+public:
+ void * operator new(size_t /*size*/, int nBuffers) {
+ return ::operator new(sizeof(CABufferList) + (nBuffers-1) * sizeof(AudioBuffer));
+ }
+ static CABufferList * New(const char *name, const CAStreamBasicDescription &format)
+ {
+ UInt32 numBuffers = format.NumberChannelStreams(), channelsPerBuffer = format.NumberInterleavedChannels();
+ return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
+ }
+ static CABufferList * New(const CAStreamBasicDescription &format) { return New("", format); }
+
+ static CABufferList * New(UInt32 numBuffers, UInt32 channelsPerBuffer, const char *name="") {
+ return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
+ }
+
+protected:
+ CABufferList(const char *name, UInt32 numBuffers, UInt32 channelsPerBuffer) :
+ mName(name),
+ mBufferMemory(NULL),
+ mBufferCapacity(0)
+ {
+ //XAssert(numBuffers > 0 /*&& channelsPerBuffer > 0*/);
+ mABL.mNumberBuffers = numBuffers;
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ buf->mNumberChannels = channelsPerBuffer;
+ buf->mDataByteSize = 0;
+ buf->mData = NULL;
+ }
+ }
+
+public:
+ ~CABufferList()
+ {
+ if (mBufferMemory)
+ delete[] mBufferMemory;
+ }
+
+ const char * Name() { return mName; }
+
+ const AudioBufferList & GetBufferList() const { return mABL; }
+
+ AudioBufferList & GetModifiableBufferList() { return _GetBufferList(); }
+
+ UInt32 GetNumberBuffers() const { return mABL.mNumberBuffers; }
+
+ UInt32 GetNumBytes() const
+ {
+ return mABL.mBuffers[0].mDataByteSize;
+ }
+
+ void SetBytes(UInt32 nBytes, void *data)
+ {
+ VerifyNotTrashingOwnedBuffer();
+ XAssert(mABL.mNumberBuffers == 1);
+ mABL.mBuffers[0].mDataByteSize = nBytes;
+ mABL.mBuffers[0].mData = data;
+ }
+
+ void CopyAllFrom(CABufferList *srcbl, CABufferList *ptrbl)
+ // copies bytes from srcbl
+ // make ptrbl reflect the length copied
+ // note that srcbl may be same as ptrbl!
+ {
+ // Note that this buffer *can* own memory and its pointers/lengths are not
+ // altered; only its buffer contents, which are copied from srcbl.
+ // The pointers/lengths in ptrbl are updated to reflect the addresses/lengths
+ // of the copied data, and srcbl's contents are consumed.
+ ptrbl->VerifyNotTrashingOwnedBuffer();
+ UInt32 nBytes = srcbl->GetNumBytes();
+ AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = srcbl->mABL.mBuffers,
+ *ptrbuf = ptrbl->mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf, ++ptrbuf) {
+ memmove(mybuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
+ ptrbuf->mData = mybuf->mData;
+ ptrbuf->mDataByteSize = srcbuf->mDataByteSize;
+ }
+ if (srcbl != ptrbl)
+ srcbl->BytesConsumed(nBytes);
+ }
+
+ // copies data from another buffer list.
+ void CopyDataFrom(const AudioBufferList &other)
+ {
+ for (unsigned i = 0; i < other.mNumberBuffers; ++i) {
+ XAssert(mBufferCapacity == 0 || other.mBuffers[i].mDataByteSize <= mBufferCapacity);
+ memcpy(mABL.mBuffers[i].mData, other.mBuffers[i].mData,
+ mABL.mBuffers[i].mDataByteSize = other.mBuffers[i].mDataByteSize);
+ }
+ }
+
+ void AppendFrom(CABufferList *blp, UInt32 nBytes)
+ {
+ // this may mutate a buffer that owns memory.
+ AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = blp->mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
+ XAssert(nBytes <= srcbuf->mDataByteSize);
+ XAssert(mBufferCapacity == 0 || mybuf->mDataByteSize + nBytes <= mBufferCapacity);
+ memcpy((Byte *)mybuf->mData + mybuf->mDataByteSize, srcbuf->mData, nBytes);
+ mybuf->mDataByteSize += nBytes;
+ }
+ blp->BytesConsumed(nBytes);
+ }
+
+ void PadWithZeroes(UInt32 desiredBufferSize)
+ // for cases where an algorithm (e.g. SRC) requires some
+ // padding to create silence following end-of-file
+ {
+ XAssert(mBufferCapacity == 0 || desiredBufferSize <= mBufferCapacity);
+ if (GetNumBytes() > desiredBufferSize) return;
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ memset((Byte *)buf->mData + buf->mDataByteSize, 0, desiredBufferSize - buf->mDataByteSize);
+ buf->mDataByteSize = desiredBufferSize;
+ }
+ }
+
+ void SetToZeroes(UInt32 nBytes)
+ {
+ XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ memset((Byte *)buf->mData, 0, nBytes);
+ buf->mDataByteSize = nBytes;
+ }
+ }
+
+ void Reset()
+ {
+ DeallocateBuffers();
+ }
+
+ Boolean SameDataAs(const CABufferList* anotherBufferList)
+ {
+ // check to see if two buffer lists point to the same memory.
+ if (mABL.mNumberBuffers != anotherBufferList->mABL.mNumberBuffers) return false;
+
+ for (UInt32 i = 0; i < mABL.mNumberBuffers; ++i) {
+ if (mABL.mBuffers[i].mData != anotherBufferList->mABL.mBuffers[i].mData) return false;
+ }
+ return true;
+ }
+
+ void BytesConsumed(UInt32 nBytes)
+ // advance buffer pointers, decrease buffer sizes
+ {
+ VerifyNotTrashingOwnedBuffer();
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ XAssert(nBytes <= buf->mDataByteSize);
+ buf->mData = (Byte *)buf->mData + nBytes;
+ buf->mDataByteSize -= nBytes;
+ }
+ }
+
+ void SetFrom(const AudioBufferList *abl)
+ {
+ VerifyNotTrashingOwnedBuffer();
+ memcpy(&_GetBufferList(), abl, (char *)&abl->mBuffers[abl->mNumberBuffers] - (char *)abl);
+ }
+
+ void SetFrom(const CABufferList *blp)
+ {
+ SetFrom(&blp->GetBufferList());
+ }
+
+ void SetFrom(const AudioBufferList *abl, UInt32 nBytes)
+ {
+ VerifyNotTrashingOwnedBuffer();
+ AudioBuffer *mybuf = mABL.mBuffers;
+ const AudioBuffer *srcbuf = abl->mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
+ mybuf->mNumberChannels = srcbuf->mNumberChannels;
+ mybuf->mDataByteSize = nBytes;
+ mybuf->mData = srcbuf->mData;
+ }
+ }
+
+ void SetFrom(const CABufferList *blp, UInt32 nBytes)
+ {
+ SetFrom(&blp->GetBufferList(), nBytes);
+ }
+
+ AudioBufferList * ToAudioBufferList(AudioBufferList *abl) const
+ {
+ memcpy(abl, &GetBufferList(), (char *)&abl->mBuffers[mABL.mNumberBuffers] - (char *)abl);
+ return abl;
+ }
+
+ void AllocateBuffers(UInt32 nBytes);
+ void AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inCopyFromList, CABufferList *inSetPtrList);
+
+ void DeallocateBuffers();
+
+ void UseExternalBuffer(Byte *ptr, UInt32 nBytes);
+
+ void AdvanceBufferPointers(UInt32 nBytes) // $$$ ReducingSize
+ // this is for bufferlists that function simply as
+ // an array of pointers into another bufferlist, being advanced,
+ // as in RenderOutput implementations
+ {
+ VerifyNotTrashingOwnedBuffer();
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
+ buf->mData = (Byte *)buf->mData + nBytes;
+ buf->mDataByteSize -= nBytes;
+ }
+ }
+
+ void SetNumBytes(UInt32 nBytes)
+ {
+ XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
+ AudioBuffer *buf = mABL.mBuffers;
+ for (UInt32 i = mABL.mNumberBuffers; i--; ++buf)
+ buf->mDataByteSize = nBytes;
+ }
+
+ void Print(const char *label=NULL, int nframes=0, int wordSize=0) const
+ {
+ if (label == NULL)
+ label = mName;
+ printf("%s - ", label);
+ CAShowAudioBufferList(&GetBufferList(), nframes, wordSize);
+ if (mBufferMemory)
+ printf(" owned memory @ 0x%p:\n", mBufferMemory);
+ }
+
+ UInt32 GetCapacityBytes() const { return mBufferCapacity; }
+
+ template <typename T>
+ T* GetData(UInt32 inBuffer) {
+ return static_cast<T*>(mABL.mBuffers[inBuffer].mData);
+ }
+
+protected:
+ AudioBufferList & _GetBufferList() { return mABL; } // use with care
+ // if we make this public, then we lose ability to call VerifyNotTrashingOwnedBuffer
+ void VerifyNotTrashingOwnedBuffer()
+ {
+ // This needs to be called from places where we are modifying the buffer pointers.
+ // It's an error to modify the buffer pointers or lengths if we own the buffer memory.
+ XAssert(mBufferMemory == NULL);
+ }
+
+ const char * mName; // for debugging
+ Byte * mBufferMemory;
+ UInt32 mBufferCapacity; // max mDataByteSize of each buffer
+ AudioBufferList mABL;
+ // don't add anything here
+};
+
+#endif // __CABufferList_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.cpp b/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.cpp
new file mode 100644
index 0000000000..2161be7447
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.cpp
@@ -0,0 +1,84 @@
+/*
+ File: CABundleLocker.cpp
+ Abstract: CABundleLocker.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CABundleLocker.h"
+#include <pthread.h>
+
+/*
+some bundle operations are not thread safe, notably CFCopyLocalizedStringFromTableInBundle
+*/
+
+static pthread_mutex_t sCABundleLocker = PTHREAD_MUTEX_INITIALIZER;
+
+#define RECURSIVE_LOCK 0
+
+#if RECURSIVE_LOCK
+static pthread_once_t sOnce = PTHREAD_ONCE_INIT;
+
+static void InitCABundleLocker()
+{
+ // have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&sCABundleLocker, &attr);
+ pthread_mutexattr_destroy(&attr);
+}
+#endif
+
+CABundleLocker::CABundleLocker()
+{
+#if RECURSIVE_LOCK
+ pthread_once(&sOnce, InitCABundleLocker);
+#endif
+ pthread_mutex_lock(&sCABundleLocker);
+}
+
+CABundleLocker::~CABundleLocker()
+{
+ pthread_mutex_unlock(&sCABundleLocker);
+}
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.h b/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.h
new file mode 100644
index 0000000000..821ca34af0
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CABundleLocker.h
@@ -0,0 +1,69 @@
+/*
+ File: CABundleLocker.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef _CABundleLocker_h_
+#define _CABundleLocker_h_
+
+#include <TargetConditionals.h>
+
+/*
+some bundle operations are not thread safe, notably CFCopyLocalizedStringFromTableInBundle
+*/
+
+class CABundleLocker
+{
+public:
+
+#if TARGET_OS_MAC
+ CABundleLocker();
+ ~CABundleLocker();
+#else
+ CABundleLocker() {}
+ ~CABundleLocker() {}
+#endif
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAByteOrder.h b/libs/appleutility/CoreAudio/PublicUtility/CAByteOrder.h
new file mode 100644
index 0000000000..9a56c6d858
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAByteOrder.h
@@ -0,0 +1,161 @@
+/*
+ File: CAByteOrder.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAByteOrder_h__)
+#define __CAByteOrder_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include "CoreFoundation.h"
+#endif
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+CF_INLINE Float32 CASwapFloat32 (Float32 arg) {
+ union {
+ Float32 f;
+ UInt32 i;
+ } flip;
+
+ flip.f = arg;
+ flip.i = CFSwapInt32 (flip.i);
+
+ return flip.f;
+}
+
+CF_INLINE Float64 CASwapFloat64 (Float64 arg) {
+ union {
+ Float64 f;
+ UInt64 i;
+ } flip;
+
+ flip.f = arg;
+ flip.i = CFSwapInt64 (flip.i);
+
+ return flip.f;
+}
+
+#pragma mark -Flippers
+
+CF_INLINE Float32 CASwapFloat32BigToHost(Float32 arg) {
+#if defined(__BIG_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64BigToHost(Float64 arg) {
+#if defined(__BIG_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32HostToBig(Float32 arg) {
+#if defined(__BIG_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64HostToBig(Float64 arg) {
+#if defined(__BIG_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32LittleToHost(Float32 arg) {
+#if defined(__LITTLE_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64LittleToHost(Float64 arg) {
+#if defined(__LITTLE_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat64(arg);
+#endif
+}
+
+CF_INLINE Float32 CASwapFloat32HostToLittle(Float32 arg) {
+#if defined(__LITTLE_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat32(arg);
+#endif
+}
+
+CF_INLINE Float64 CASwapFloat64HostToLittle(Float64 arg) {
+#if defined(__LITTLE_ENDIAN__)
+ return arg;
+#else
+ return CASwapFloat64(arg);
+#endif
+}
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFArray.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFArray.cpp
new file mode 100644
index 0000000000..e7c057d8da
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFArray.cpp
@@ -0,0 +1,821 @@
+/*
+ File: CACFArray.cpp
+ Abstract: CACFArray.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CACFArray.h"
+
+// PublicUtility Includes
+#include "CACFDictionary.h"
+#include "CACFNumber.h"
+#include "CACFString.h"
+
+//=============================================================================
+// CACFArray
+//=============================================================================
+
+bool CACFArray::HasItem(const void* inItem) const
+{
+ bool theAnswer = false;
+ if(mCFArray != NULL)
+ {
+ CFRange theRange = { 0, CFArrayGetCount(mCFArray)};
+ theAnswer = CFArrayContainsValue(mCFArray, theRange, inItem);
+ }
+ return theAnswer;
+}
+
+bool CACFArray::GetIndexOfItem(const void* inItem, UInt32& outIndex) const
+{
+ bool theAnswer = false;
+ outIndex = 0;
+ if(mCFArray != NULL)
+ {
+ CFRange theRange = { 0, CFArrayGetCount(mCFArray)};
+ CFIndex theIndex = CFArrayGetFirstIndexOfValue(mCFArray, theRange, inItem);
+ if(theIndex != -1)
+ {
+ theAnswer = true;
+ outIndex = ToUInt32(theIndex);
+ }
+ }
+ return theAnswer;
+}
+
+bool CACFArray::GetBool(UInt32 inIndex, bool& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inIndex, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
+ {
+ outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
+ theAnswer = true;
+ }
+ else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ SInt32 theNumericValue = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
+ outValue = theNumericValue != 0;
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetSInt32(UInt32 inIndex, SInt32& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt32Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetUInt32(UInt32 inIndex, UInt32& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt32Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetSInt64(UInt32 inIndex, SInt64& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt64Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetUInt64(UInt32 inIndex, UInt64& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt64Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetFloat32(UInt32 inIndex, Float32& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberFloat32Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetFloat64(UInt32 inIndex, Float64& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberFloat64Type, &outItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::Get4CC(UInt32 inIndex, UInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inIndex, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ else if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ CFStringRef theString = static_cast<CFStringRef>(theValue);
+ if(CFStringGetLength(theString) == 4)
+ {
+ char theCString[5];
+ CFStringGetCString(theString, theCString, 5, kCFStringEncodingASCII);
+ outValue = CFSwapInt32BigToHost(*reinterpret_cast<UInt32*>(theCString));
+ }
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetString(UInt32 inIndex, CFStringRef& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFStringGetTypeID()))
+ {
+ outItem = static_cast<CFStringRef>(theItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetArray(UInt32 inIndex, CFArrayRef& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFArrayGetTypeID()))
+ {
+ outItem = static_cast<CFArrayRef>(theItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetDictionary(UInt32 inIndex, CFDictionaryRef& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFDictionaryGetTypeID()))
+ {
+ outItem = static_cast<CFDictionaryRef>(theItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetData(UInt32 inIndex, CFDataRef& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFDataGetTypeID()))
+ {
+ outItem = static_cast<CFDataRef>(theItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetUUID(UInt32 inIndex, CFUUIDRef& outItem) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFUUIDGetTypeID()))
+ {
+ outItem = static_cast<CFUUIDRef>(theItem);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::GetCFType(UInt32 inIndex, CFTypeRef& outItem) const
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && (inIndex < GetNumberItems()))
+ {
+ outItem = CFArrayGetValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex));
+ theAnswer = outItem != NULL;
+ }
+
+ return theAnswer;
+}
+
+void CACFArray::GetCACFString(UInt32 inIndex, CACFString& outItem) const
+{
+ outItem = static_cast<CFStringRef>(NULL);
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFStringGetTypeID()))
+ {
+ outItem = static_cast<CFStringRef>(theItem);
+ }
+ }
+}
+
+void CACFArray::GetCACFArray(UInt32 inIndex, CACFArray& outItem) const
+{
+ outItem = static_cast<CFArrayRef>(NULL);
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFArrayGetTypeID()))
+ {
+ outItem = static_cast<CFArrayRef>(theItem);
+ }
+ }
+}
+
+void CACFArray::GetCACFDictionary(UInt32 inIndex, CACFDictionary& outItem) const
+{
+ outItem = static_cast<CFDictionaryRef>(NULL);
+ CFTypeRef theItem = NULL;
+ if(GetCFType(inIndex, theItem))
+ {
+ if((theItem != NULL) && (CFGetTypeID(theItem) == CFDictionaryGetTypeID()))
+ {
+ outItem = static_cast<CFDictionaryRef>(theItem);
+ }
+ }
+}
+
+bool CACFArray::AppendBool(bool inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFBoolean theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFBoolean());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendSInt32(SInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendUInt32(UInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendSInt64(SInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendUInt64(UInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendFloat32(Float32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendFloat64(Float64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = AppendCFType(theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::AppendString(const CFStringRef inItem)
+{
+ return AppendCFType(inItem);
+}
+
+bool CACFArray::AppendArray(const CFArrayRef inItem)
+{
+ return AppendCFType(inItem);
+}
+
+bool CACFArray::AppendDictionary(const CFDictionaryRef inItem)
+{
+ return AppendCFType(inItem);
+}
+
+bool CACFArray::AppendData(const CFDataRef inItem)
+{
+ return AppendCFType(inItem);
+}
+
+bool CACFArray::AppendCFType(const CFTypeRef inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CFArrayAppendValue(mCFArray, inItem);
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertBool(UInt32 inIndex, bool inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFBoolean theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFBoolean());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertSInt32(UInt32 inIndex, SInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertUInt32(UInt32 inIndex, UInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertSInt64(UInt32 inIndex, SInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertUInt64(UInt32 inIndex, UInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertFloat32(UInt32 inIndex, Float32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertFloat64(UInt32 inIndex, Float64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::InsertString(UInt32 inIndex, const CFStringRef inItem)
+{
+ return InsertCFType(inIndex, inItem);
+}
+
+bool CACFArray::InsertArray(UInt32 inIndex, const CFArrayRef inItem)
+{
+ return InsertCFType(inIndex, inItem);
+}
+
+bool CACFArray::InsertDictionary(UInt32 inIndex, const CFDictionaryRef inItem)
+{
+ return InsertCFType(inIndex, inItem);
+}
+
+bool CACFArray::InsertData(UInt32 inIndex, const CFDataRef inItem)
+{
+ return InsertCFType(inIndex, inItem);
+}
+
+bool CACFArray::InsertCFType(UInt32 inIndex, const CFTypeRef inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable)
+ {
+ if(inIndex < GetNumberItems())
+ {
+ CFArrayInsertValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex), inItem);
+ }
+ else
+ {
+ CFArrayAppendValue(mCFArray, inItem);
+ }
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetBool(UInt32 inIndex, bool inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFBoolean theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFBoolean());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetSInt32(UInt32 inIndex, SInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetUInt32(UInt32 inIndex, UInt32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetSInt64(UInt32 inIndex, SInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetUInt64(UInt32 inIndex, UInt64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetFloat32(UInt32 inIndex, Float32 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetFloat64(UInt32 inIndex, Float64 inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CACFNumber theItem(inItem);
+ if(theItem.IsValid())
+ {
+ theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFArray::SetString(UInt32 inIndex, const CFStringRef inItem)
+{
+ return SetCFType(inIndex, inItem);
+}
+
+bool CACFArray::SetArray(UInt32 inIndex, const CFArrayRef inItem)
+{
+ return SetCFType(inIndex, inItem);
+}
+
+bool CACFArray::SetDictionary(UInt32 inIndex, const CFDictionaryRef inItem)
+{
+ return SetCFType(inIndex, inItem);
+}
+
+bool CACFArray::SetData(UInt32 inIndex, const CFDataRef inItem)
+{
+ return SetCFType(inIndex, inItem);
+}
+
+bool CACFArray::SetCFType(UInt32 inIndex, const CFTypeRef inItem)
+{
+ bool theAnswer = false;
+
+ if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
+ {
+ CFArraySetValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex), inItem);
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFArray.h b/libs/appleutility/CoreAudio/PublicUtility/CACFArray.h
new file mode 100644
index 0000000000..89c8c559e4
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFArray.h
@@ -0,0 +1,195 @@
+/*
+ File: CACFArray.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFArray_h__)
+#define __CACFArray_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CoreFoundation.h>
+#endif
+
+#include "CADebugMacros.h"
+
+//=============================================================================
+// Types
+//=============================================================================
+
+class CACFDictionary;
+class CACFString;
+
+//=============================================================================
+// CACFArray
+//=============================================================================
+
+class CACFArray
+{
+
+// Construction/Destruction
+public:
+ CACFArray() : mCFArray(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)), mRelease(true), mMutable(true) {}
+ explicit CACFArray(bool inRelease) : mCFArray(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)), mRelease(inRelease), mMutable(true) {}
+ CACFArray(UInt32 inMaxNumberItems, bool inRelease) : mCFArray(CFArrayCreateMutable(NULL, static_cast<CFIndex>(inMaxNumberItems), &kCFTypeArrayCallBacks)), mRelease(inRelease), mMutable(true) {}
+ CACFArray(CFArrayRef inCFArray, bool inRelease) : mCFArray(const_cast<CFMutableArrayRef>(inCFArray)), mRelease(inRelease), mMutable(false) {}
+ CACFArray(CFMutableArrayRef inCFArray, bool inRelease) : mCFArray(inCFArray), mRelease(inRelease), mMutable(true) {}
+ CACFArray(const CACFArray& inArray) : mCFArray(inArray.mCFArray), mRelease(inArray.mRelease), mMutable(inArray.mMutable) { Retain(); }
+ CACFArray& operator=(const CACFArray& inArray) { Release(); mCFArray = inArray.mCFArray; mRelease = inArray.mRelease; mMutable = inArray.mMutable; Retain(); return *this; }
+ CACFArray& operator=(CFArrayRef inCFArray) { Release(); mCFArray = const_cast<CFMutableArrayRef>(inCFArray); mMutable = false; Retain(); return *this; }
+ CACFArray& operator=(CFMutableArrayRef inCFArray) { Release(); mCFArray = inCFArray; mMutable = true; Retain(); return *this; }
+ ~CACFArray() { Release(); }
+
+private:
+ void Retain() { if(mRelease && (mCFArray != NULL)) { CFRetain(mCFArray); } }
+ void Release() { if(mRelease && (mCFArray != NULL)) { CFRelease(mCFArray); } }
+
+// Attributes
+public:
+ bool IsValid() const { return mCFArray != NULL; }
+ bool IsMutable() const { return mMutable; }
+ bool CanModify() const { return mMutable && (mCFArray != NULL); }
+
+ bool WillRelease() const { return mRelease; }
+ void ShouldRelease(bool inRelease) { mRelease = inRelease; }
+
+ CFTypeID GetTypeID() const { return CFGetTypeID(mCFArray); }
+
+ CFArrayRef GetCFArray() const { return mCFArray; }
+ CFArrayRef CopyCFArray() const { if(mCFArray != NULL) { CFRetain(mCFArray); } return mCFArray; }
+
+ CFMutableArrayRef GetCFMutableArray() const { return mCFArray; }
+ CFMutableArrayRef CopyCFMutableArray() const { if(mCFArray != NULL) { CFRetain(mCFArray); } return mCFArray; }
+ CFPropertyListRef AsPropertyList() const { return mCFArray; }
+
+ void SetCFMutableArrayFromCopy(CFArrayRef inArray, bool inRelease = true) { Release(); mCFArray = CFArrayCreateMutableCopy(NULL, 0, inArray); mMutable = true; mRelease = inRelease; }
+
+// Item Operations
+public:
+ UInt32 GetNumberItems() const { UInt32 theAnswer = 0; if(mCFArray != NULL) { theAnswer = ToUInt32(CFArrayGetCount(mCFArray)); } return theAnswer; }
+ bool HasItem(const void* inItem) const;
+ void RemoveItem(const void* inItem) { UInt32 theIndex; if(CanModify() && GetIndexOfItem(inItem, theIndex)) { RemoveItemAtIndex(theIndex); } }
+ bool GetIndexOfItem(const void* inItem, UInt32& outIndex) const;
+ void RemoveItemAtIndex(UInt32 inIndex) { if(CanModify()) { CFArrayRemoveValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex)); } }
+ void Clear() { if(CanModify()) { CFArrayRemoveAllValues(mCFArray); } }
+ void Sort(CFComparatorFunction inCompareFunction) { if(CanModify()) { CFRange theRange = { 0, CFArrayGetCount(mCFArray) }; CFArraySortValues(mCFArray, theRange, inCompareFunction, NULL); } }
+ void SortNumbers() { Sort((CFComparatorFunction)CFNumberCompare); }
+ void SortStrings() { Sort((CFComparatorFunction)CFStringCompare); }
+
+ bool GetBool(UInt32 inIndex, bool& outValue) const;
+ bool GetSInt32(UInt32 inIndex, SInt32& outItem) const;
+ bool GetUInt32(UInt32 inIndex, UInt32& outItem) const;
+ bool GetSInt64(UInt32 inIndex, SInt64& outItem) const;
+ bool GetUInt64(UInt32 inIndex, UInt64& outItem) const;
+ bool GetFloat32(UInt32 inIndex, Float32& outItem) const;
+ bool GetFloat64(UInt32 inIndex, Float64& outItem) const;
+ bool Get4CC(UInt32 inIndex, UInt32& outValue) const;
+ bool GetString(UInt32 inIndex, CFStringRef& outItem) const;
+ bool GetArray(UInt32 inIndex, CFArrayRef& outItem) const;
+ bool GetDictionary(UInt32 inIndex, CFDictionaryRef& outItem) const;
+ bool GetData(UInt32 inIndex, CFDataRef& outItem) const;
+ bool GetUUID(UInt32 inIndex, CFUUIDRef& outItem) const;
+ bool GetCFType(UInt32 inIndex, CFTypeRef& outItem) const;
+
+ void GetCACFString(UInt32 inIndex, CACFString& outItem) const;
+ void GetCACFArray(UInt32 inIndex, CACFArray& outItem) const;
+ void GetCACFDictionary(UInt32 inIndex, CACFDictionary& outItem) const;
+
+ bool AppendBool(bool inItem);
+ bool AppendSInt32(SInt32 inItem);
+ bool AppendUInt32(UInt32 inItem);
+ bool AppendSInt64(SInt64 inItem);
+ bool AppendUInt64(UInt64 inItem);
+ bool AppendFloat32(Float32 inItem);
+ bool AppendFloat64(Float64 inItem);
+ bool AppendString(const CFStringRef inItem);
+ bool AppendArray(const CFArrayRef inItem);
+ bool AppendDictionary(const CFDictionaryRef inItem);
+ bool AppendData(const CFDataRef inItem);
+ bool AppendCFType(const CFTypeRef inItem);
+
+ bool InsertBool(UInt32 inIndex, bool inItem);
+ bool InsertSInt32(UInt32 inIndex, SInt32 inItem);
+ bool InsertUInt32(UInt32 inIndex, UInt32 inItem);
+ bool InsertSInt64(UInt32 inIndex, SInt64 inItem);
+ bool InsertUInt64(UInt32 inIndex, UInt64 inItem);
+ bool InsertFloat32(UInt32 inIndex, Float32 inItem);
+ bool InsertFloat64(UInt32 inIndex, Float64 inItem);
+ bool InsertString(UInt32 inIndex, const CFStringRef inItem);
+ bool InsertArray(UInt32 inIndex, const CFArrayRef inItem);
+ bool InsertDictionary(UInt32 inIndex, const CFDictionaryRef inItem);
+ bool InsertData(UInt32 inIndex, const CFDataRef inItem);
+ bool InsertCFType(UInt32 inIndex, const CFTypeRef inItem);
+
+ bool SetBool(UInt32 inIndex, bool inItem);
+ bool SetSInt32(UInt32 inIndex, SInt32 inItem);
+ bool SetUInt32(UInt32 inIndex, UInt32 inItem);
+ bool SetSInt64(UInt32 inIndex, SInt64 inItem);
+ bool SetUInt64(UInt32 inIndex, UInt64 inItem);
+ bool SetFloat32(UInt32 inIndex, Float32 inItem);
+ bool SetFloat64(UInt32 inIndex, Float64 inItem);
+ bool SetString(UInt32 inIndex, const CFStringRef inItem);
+ bool SetArray(UInt32 inIndex, const CFArrayRef inItem);
+ bool SetDictionary(UInt32 inIndex, const CFDictionaryRef inItem);
+ bool SetData(UInt32 inIndex, const CFDataRef inItem);
+ bool SetCFType(UInt32 inIndex, const CFTypeRef inItem);
+
+// Implementation
+private:
+ CFMutableArrayRef mCFArray;
+ bool mRelease;
+ bool mMutable;
+
+ CACFArray(const void*); // prevent accidental instantiation with a pointer via bool constructor
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFData.h b/libs/appleutility/CoreAudio/PublicUtility/CACFData.h
new file mode 100644
index 0000000000..7ce08dcf13
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFData.h
@@ -0,0 +1,108 @@
+/*
+ File: CACFData.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFData_h__)
+#define __CACFData_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CFData.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CFData.h>
+#endif
+
+#include "CADebugMacros.h"
+
+//=============================================================================
+// CACFData
+//=============================================================================
+
+class CACFData
+{
+
+// Construction/Destruction
+public:
+ explicit CACFData(CFDataRef inCFData) : mCFData(inCFData), mWillRelease(true) {}
+ CACFData(CFDataRef inCFData, bool inWillRelease) : mCFData(inCFData), mWillRelease(inWillRelease) {}
+ CACFData(const void* inData, UInt32 inDataSize) : mCFData(NULL), mWillRelease(true) { mCFData = CFDataCreate(NULL, static_cast<const UInt8*>(inData), static_cast<CFIndex>(inDataSize)); }
+ ~CACFData() { Release(); }
+ CACFData(const CACFData& inNumber) : mCFData(inNumber.mCFData), mWillRelease(inNumber.mWillRelease) { Retain(); }
+ CACFData& operator=(const CACFData& inNumber) { Release(); mCFData = inNumber.mCFData; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
+ CACFData& operator=(CFDataRef inCFData) { Release(); mCFData = inCFData; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFData != NULL)) { CFRetain(mCFData); } }
+ void Release() { if(mWillRelease && (mCFData != NULL)) { CFRelease(mCFData); } }
+
+ CFDataRef mCFData;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() { return mCFData != NULL; }
+
+// Value Access
+public:
+ CFDataRef GetCFData() const { return mCFData; }
+ CFDataRef CopyCFData() const { if(mCFData != NULL) { CFRetain(mCFData); } return mCFData; }
+
+ UInt32 GetSize() const { return ToUInt32(CFDataGetLength(mCFData)); }
+ const void* GetDataPtr() const { return CFDataGetBytePtr(mCFData); }
+ void CopyData(UInt32 inStartOffset, void* outData, UInt32 inDataSize) const { CFRange theRange = { static_cast<CFIndex>(inStartOffset), static_cast<CFIndex>(inDataSize) }; CFDataGetBytes(mCFData, theRange, static_cast<UInt8*>(outData)); }
+
+ SInt32 GetSInt32() const { SInt32 theAnswer = 0; CopyData(0, &theAnswer, SizeOf32(SInt32)); return theAnswer; }
+ Float32 GetFloat32() const { Float32 theAnswer = 0; CopyData(0, &theAnswer, SizeOf32(Float32)); return theAnswer; }
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.cpp
new file mode 100644
index 0000000000..fbac774ab5
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.cpp
@@ -0,0 +1,581 @@
+/*
+ File: CACFDictionary.cpp
+ Abstract: CACFDictionary.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CACFDictionary.h"
+
+// PublicUtility Includes
+#include "CACFArray.h"
+#include "CACFNumber.h"
+#include "CACFString.h"
+
+//=============================================================================
+// CACFDictionary
+//=============================================================================
+
+bool CACFDictionary::HasKey(const CFStringRef inKey) const
+{
+ return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
+}
+
+UInt32 CACFDictionary::Size () const
+{
+ return mCFDictionary ? ToUInt32(CFDictionaryGetCount(mCFDictionary)) : 0;
+}
+
+void CACFDictionary::GetKeys (const void **keys) const
+{
+ CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
+}
+
+void CACFDictionary::GetKeysAndValues (const void **keys, const void **values) const
+{
+ CFDictionaryGetKeysAndValues(mCFDictionary, keys, values);
+}
+
+bool CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
+ {
+ outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
+ theAnswer = true;
+ }
+ else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ SInt32 theNumericValue = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
+ outValue = theNumericValue != 0;
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFloat32FromString(const CFStringRef inKey, Float32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ outValue = static_cast<Float32>(CFStringGetDoubleValue(static_cast<CFStringRef>(theValue)));
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetUInt32FromString(const CFStringRef inKey, UInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ outValue = CFStringGetIntValue(static_cast<CFStringRef>(theValue));
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFixed32(const CFStringRef inKey, Float32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ SInt32 theFixed32 = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theFixed32);
+
+ // this is a 16.16 value so convert it to a float
+ Float32 theSign = theFixed32 < 0 ? -1.0f : 1.0f;
+ theFixed32 *= (SInt32)theSign;
+ Float32 theWholePart = (theFixed32 & 0x7FFF0000) >> 16;
+ Float32 theFractPart = theFixed32 & 0x0000FFFF;
+ theFractPart /= 65536.0f;
+ outValue = theSign * (theWholePart + theFractPart);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFixed64(const CFStringRef inKey, Float64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ SInt64 theFixed64 = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &theFixed64);
+ outValue = static_cast<Float64>(theFixed64 >> 32);
+ outValue += static_cast<Float64>(theFixed64 & 0x00000000FFFFFFFFLL) / static_cast<Float64>(0x0000000100000000LL);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::Get4CC(const CFStringRef inKey, UInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ else if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ CFStringRef theString = static_cast<CFStringRef>(theValue);
+ if(CFStringGetLength(theString) == 4)
+ {
+ char theCString[5];
+ CFStringGetCString(theString, theCString, 5, kCFStringEncodingASCII);
+ outValue = CFSwapInt32BigToHost(*reinterpret_cast<UInt32*>(theCString));
+ }
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ outValue = static_cast<CFStringRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
+ {
+ outValue = static_cast<CFArrayRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
+ {
+ outValue = static_cast<CFDictionaryRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
+ {
+ outValue = static_cast<CFDataRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
+{
+ bool theAnswer = false;
+
+ if(mCFDictionary != NULL)
+ {
+ outValue = CFDictionaryGetValue(mCFDictionary, inKey);
+ theAnswer = (outValue != NULL);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetURL(const CFStringRef inKey, CFURLRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFURLGetTypeID()))
+ {
+ outValue = static_cast<CFURLRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
+{
+ bool theAnswer = false;
+
+ if(mCFDictionary != NULL)
+ {
+ CACFString theKey(inKey);
+ if(theKey.IsValid())
+ {
+ theAnswer = GetCFType(theKey.GetCFString(), outValue);
+ }
+ }
+
+ return theAnswer;
+}
+
+void CACFDictionary::GetCACFString(const CFStringRef inKey, CACFString& outValue) const
+{
+ outValue = static_cast<CFStringRef>(NULL);
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ outValue = static_cast<CFStringRef>(theValue);
+ }
+ }
+}
+
+void CACFDictionary::GetCACFArray(const CFStringRef inKey, CACFArray& outValue) const
+{
+ outValue = static_cast<CFArrayRef>(NULL);
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
+ {
+ outValue = static_cast<CFArrayRef>(theValue);
+ }
+ }
+}
+
+void CACFDictionary::GetCACFDictionary(const CFStringRef inKey, CACFDictionary& outValue) const
+{
+ outValue = static_cast<CFDictionaryRef>(NULL);
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
+ {
+ outValue = static_cast<CFDictionaryRef>(theValue);
+ }
+ }
+}
+
+bool CACFDictionary::AddBool(const CFStringRef inKey, bool inValue)
+{
+ CACFBoolean theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFBoolean());
+}
+
+bool CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
+{
+ CACFNumber theValue(inValue);
+ return AddCFType(inKey, theValue.GetCFNumber());
+}
+
+bool CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
+{
+ return AddCFType(inKey, inValue);
+}
+
+bool CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
+{
+ return AddCFType(inKey, inValue);
+}
+
+bool CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
+{
+ return AddCFType(inKey, inValue);
+}
+
+bool CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
+{
+ return AddCFType(inKey, inValue);
+}
+
+bool CACFDictionary::AddData(const CFStringRef inKey, const CFDataRef inValue)
+{
+ return AddCFType(inKey, inValue);
+}
+
+bool CACFDictionary::AddURL(const CFStringRef inKey, const CFURLRef inValue)
+{
+ return AddCFType (inKey, inValue);
+}
+
+bool CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
+{
+ bool theAnswer = false;
+
+ if (inKey)
+ {
+ CACFString theKey(inKey);
+ if(theKey.IsValid())
+ {
+ theAnswer = AddCFType(theKey.GetCFString(), inValue);
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
+{
+ bool theAnswer = false;
+
+ if (inValue)
+ {
+ CACFString theValue(inValue);
+ if(theValue.IsValid())
+ {
+ theAnswer = AddCFType(inKey, theValue.GetCFString());
+ }
+ }
+ return theAnswer;
+}
+
+bool CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL) && inValue)
+ {
+ CFDictionarySetValue(mCFDictionary, inKey, inValue);
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.h b/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.h
new file mode 100644
index 0000000000..c389e50042
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFDictionary.h
@@ -0,0 +1,176 @@
+/*
+ File: CACFDictionary.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFDictionary_h__)
+#define __CACFDictionary_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreFoundation.h>
+#endif
+
+//=============================================================================
+// Types
+//=============================================================================
+
+class CACFArray;
+class CACFString;
+
+//=============================================================================
+// CACFDictionary
+//=============================================================================
+
+class CACFDictionary
+{
+
+// Construction/Destruction
+public:
+ CACFDictionary() : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(true), mMutable(true) {}
+ explicit CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
+ CACFDictionary(CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(false) {}
+ CACFDictionary(CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
+ CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { Retain(); }
+ CACFDictionary& operator=(const CACFDictionary& inDictionary) { Release(); mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; Retain(); return *this; }
+ CACFDictionary& operator=(CFDictionaryRef inDictionary) { Release(); mCFDictionary = const_cast<CFMutableDictionaryRef>(inDictionary); mMutable = false; Retain(); return *this; }
+ CACFDictionary& operator=(CFMutableDictionaryRef inDictionary) { Release(); mCFDictionary = inDictionary; mMutable = true; Retain(); return *this; }
+ ~CACFDictionary() { Release(); }
+
+private:
+ void Retain() { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
+ void Release() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
+
+// Attributes
+public:
+ bool IsValid() const { return mCFDictionary != NULL; }
+ bool IsMutable() const { return mMutable;}
+ bool CanModify() const { return mMutable && (mCFDictionary != NULL); }
+
+ bool WillRelease() const { return mRelease; }
+ void ShouldRelease(bool inRelease) { mRelease = inRelease; }
+
+ CFDictionaryRef GetDict() const { return mCFDictionary; }
+ CFDictionaryRef GetCFDictionary() const { return mCFDictionary; }
+ CFDictionaryRef CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
+
+ CFMutableDictionaryRef GetMutableDict() { return mCFDictionary; }
+ CFMutableDictionaryRef GetCFMutableDictionary() const { return mCFDictionary; }
+ CFMutableDictionaryRef CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
+ void SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { Release(); mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }
+ void SetCFMutableDictionaryToEmpty(bool inRelease = true) { Release(); mCFDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); mMutable = true; mRelease = inRelease; }
+
+ CFPropertyListRef AsPropertyList() const { return mCFDictionary; }
+ OSStatus GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }
+
+// Item Operations
+public:
+ bool HasKey(const CFStringRef inKey) const;
+ UInt32 Size() const;
+ void GetKeys(const void** keys) const;
+ void GetKeysAndValues (const void **keys, const void **values) const;
+
+ bool GetBool(const CFStringRef inKey, bool& outValue) const;
+ bool GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
+ bool GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
+ bool GetUInt32FromString(const CFStringRef inKey, UInt32& outValue) const;
+ bool GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
+ bool GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
+ bool GetFloat32(const CFStringRef inKey, Float32& outValue) const;
+ bool GetFloat32FromString(const CFStringRef inKey, Float32& outValue) const;
+ bool GetFloat64(const CFStringRef inKey, Float64& outValue) const;
+ bool GetFixed32(const CFStringRef inKey, Float32& outValue) const;
+ bool GetFixed64(const CFStringRef inKey, Float64& outValue) const;
+ bool Get4CC(const CFStringRef inKey, UInt32& outValue) const;
+ bool GetString(const CFStringRef inKey, CFStringRef& outValue) const;
+ bool GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;
+ bool GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;
+ bool GetData(const CFStringRef inKey, CFDataRef& outValue) const;
+ bool GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
+ bool GetURL(const CFStringRef inKey, CFURLRef& outValue) const;
+ bool GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;
+
+ void GetCACFString(const CFStringRef inKey, CACFString& outItem) const;
+ void GetCACFArray(const CFStringRef inKey, CACFArray& outItem) const;
+ void GetCACFDictionary(const CFStringRef inKey, CACFDictionary& outItem) const;
+
+ bool AddBool(const CFStringRef inKey, bool inValue);
+ bool AddSInt32(const CFStringRef inKey, SInt32 inValue);
+ bool AddUInt32(const CFStringRef inKey, UInt32 inValue);
+ bool AddSInt64(const CFStringRef inKey, SInt64 inValue);
+ bool AddUInt64(const CFStringRef inKey, UInt64 inValue);
+ bool AddFloat32(const CFStringRef inKey, Float32 inValue);
+ bool AddFloat64(const CFStringRef inKey, Float64 inValue);
+ bool AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
+ bool AddString(const CFStringRef inKey, const CFStringRef inValue);
+ bool AddArray(const CFStringRef inKey, const CFArrayRef inValue);
+ bool AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
+ bool AddData(const CFStringRef inKey, const CFDataRef inValue);
+ bool AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
+ bool AddURL(const CFStringRef inKey, const CFURLRef inValue);
+
+ bool AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
+ bool AddCString(const CFStringRef inKey, const char* inValue);
+
+ void RemoveKey(const CFStringRef inKey) { if(CanModify()) { CFDictionaryRemoveValue(mCFDictionary, inKey); } }
+ void Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
+
+ void Show() { CFShow(mCFDictionary); }
+
+// Implementation
+private:
+ CFMutableDictionaryRef mCFDictionary;
+ bool mRelease;
+ bool mMutable;
+
+ CACFDictionary(const void*); // prevent accidental instantiation with a pointer via bool constructor
+};
+
+#endif //__CACFDictionary_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.cpp
new file mode 100644
index 0000000000..36c6923e2d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.cpp
@@ -0,0 +1,107 @@
+/*
+ File: CACFDistributedNotification.cpp
+ Abstract: CACFDistributedNotification.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CACFDistributedNotification.h"
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+
+//==================================================================================================
+// CACFDistributedNotification
+//==================================================================================================
+
+void CACFDistributedNotification::AddObserver(const void* inObserver, CFNotificationCallback inCallback, CFStringRef inName, CFNotificationSuspensionBehavior inSuspensionBehavior)
+{
+#if !TARGET_OS_IPHONE
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDistributedCenter();
+ CFNotificationSuspensionBehavior theSuspensionBehavior = inSuspensionBehavior;
+#else
+ #pragma unused(inSuspensionBehavior)
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDarwinNotifyCenter();
+ CFNotificationSuspensionBehavior theSuspensionBehavior = static_cast<CFNotificationSuspensionBehavior>(0);
+#endif
+
+ CFNotificationCenterAddObserver(theCenter, inObserver, inCallback, inName, NULL, theSuspensionBehavior);
+}
+
+void CACFDistributedNotification::RemoveObserver(const void* inObserver, CFStringRef inName)
+{
+#if !TARGET_OS_IPHONE
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDistributedCenter();
+#else
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDarwinNotifyCenter();
+#endif
+
+ CFNotificationCenterRemoveObserver(theCenter, inObserver, inName, NULL);
+}
+
+void CACFDistributedNotification::PostNotification(CFStringRef inName, CFDictionaryRef inUserInfo, bool inPostToAllSessions)
+{
+#if !TARGET_OS_IPHONE
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDistributedCenter();
+ CFDictionaryRef theUserInfo = inUserInfo;
+ CFOptionFlags theFlags = kCFNotificationDeliverImmediately;
+ if(inPostToAllSessions)
+ {
+ theFlags += kCFNotificationPostToAllSessions;
+ }
+#else
+ // flag unsupported features
+ Assert(inUserInfo == NULL, "CACFDistributedNotification::PostNotification: distributed notifications do not support a payload");
+ Assert(inPostToAllSessions, "CACFDistributedNotification::PostNotification: distributed notifications do not support per-session delivery");
+
+ CFNotificationCenterRef theCenter = CFNotificationCenterGetDarwinNotifyCenter();
+ CFDictionaryRef theUserInfo = NULL;
+ CFOptionFlags theFlags = 0;
+#endif
+
+ CFNotificationCenterPostNotificationWithOptions(theCenter, inName, NULL, theUserInfo, theFlags);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.h b/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.h
new file mode 100644
index 0000000000..d75e23bd8a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFDistributedNotification.h
@@ -0,0 +1,73 @@
+/*
+ File: CACFDistributedNotification.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFDistributedNotification_h__)
+#define __CACFDistributedNotification_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+//==================================================================================================
+// CACFDistributedNotification
+//==================================================================================================
+
+class CACFDistributedNotification
+{
+
+// Operations
+public:
+ static void AddObserver(const void* inObserver, CFNotificationCallback inCallback, CFStringRef inName, CFNotificationSuspensionBehavior inSuspensionBehavior = CFNotificationSuspensionBehaviorCoalesce);
+ static void RemoveObserver(const void* inObserver, CFStringRef inName);
+ static void PostNotification(CFStringRef inName, CFDictionaryRef inUserInfo, bool inPostToAllSessions);
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.cpp
new file mode 100644
index 0000000000..9a33d5dae1
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.cpp
@@ -0,0 +1,168 @@
+/*
+ File: CACFMachPort.cpp
+ Abstract: CACFMachPort.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+#include "CACFMachPort.h"
+#include "CAException.h"
+#include "CADebugMacros.h"
+
+//==================================================================================================
+// CACFMachPort
+//==================================================================================================
+
+// This constructor is the short form. The CFMachPort will own the send and receive rights.
+CACFMachPort::CACFMachPort(CFMachPortCallBack inCallBack, void* inUserData)
+:
+ mMachPort(NULL),
+ mRunLoopSource(NULL),
+ mOwnsPort(true)
+{
+ CFMachPortContext theContext = { 1, inUserData, NULL, NULL, NULL };
+ mMachPort = CFMachPortCreate(NULL, inCallBack, &theContext, NULL);
+ ThrowIfNULL(mMachPort, CAException('what'), "CACFMachPort::CACFMachPort(s): couldn't create the CFMachPort");
+
+ mRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mMachPort, 0);
+ if(mRunLoopSource == NULL)
+ {
+ CFMachPortInvalidate(mMachPort);
+ CFRelease(mMachPort);
+ mMachPort = NULL;
+ DebugMessage("CACFMachPort::CACFMachPort(s): couldn't create the CFRunLoopSource");
+ throw CAException('what');
+ }
+}
+
+// This constructor is the general form:
+// - If inMachPort is MACH_PORT_NULL, the CFMachPort will allocate the port and own the send and
+// receive rights. Otherwise, the caller owns the rights and is resposible for cleaning them
+// up.
+// - If inCallBack is NULL, then received messages will just get swallowed by the CFMachPort.
+// This is useful if you are only using the CFMachPort to track port death (aka invalidation).
+// - If inInvalidationCallBack is non-NULL, then it will be installed as the invalidation
+// callback on the CFMachPort.
+CACFMachPort::CACFMachPort(mach_port_t inMachPort, CFMachPortCallBack inCallBack, CFMachPortInvalidationCallBack inInvalidationCallBack, void* inUserData)
+:
+ mMachPort(NULL),
+ mRunLoopSource(NULL),
+ mOwnsPort(false)
+{
+ CFMachPortContext theContext = { 1, inUserData, NULL, NULL, NULL };
+
+ if(inMachPort == MACH_PORT_NULL)
+ {
+ mMachPort = CFMachPortCreate(NULL, inCallBack, &theContext, NULL);
+ ThrowIfNULL(mMachPort, CAException('what'), "CACFMachPort::CACFMachPort: couldn't create the CFMachPort");
+ mOwnsPort = true;
+ }
+ else
+ {
+ mMachPort = CFMachPortCreateWithPort(NULL, inMachPort, inCallBack, &theContext, NULL);
+ ThrowIfNULL(mMachPort, CAException('what'), "CACFMachPort::CACFMachPort: couldn't create the CFMachPort with a port");
+ mOwnsPort = false;
+ }
+
+ mRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mMachPort, 0);
+ if(mRunLoopSource == NULL)
+ {
+ if(mOwnsPort)
+ {
+ CFMachPortInvalidate(mMachPort);
+ }
+ CFRelease(mMachPort);
+ mMachPort = NULL;
+ DebugMessage("CACFMachPort::CACFMachPort: couldn't create the CFRunLoopSource");
+ throw CAException('what');
+ }
+
+ if(inInvalidationCallBack != NULL)
+ {
+ CFMachPortSetInvalidationCallBack(mMachPort, inInvalidationCallBack);
+ }
+}
+
+CACFMachPort::~CACFMachPort()
+{
+ if(mRunLoopSource != NULL)
+ {
+ CFRelease(mRunLoopSource);
+ }
+
+ if(mMachPort != NULL)
+ {
+ if(mOwnsPort)
+ {
+ CFMachPortInvalidate(mMachPort);
+ }
+ CFRelease(mMachPort);
+ }
+}
+
+kern_return_t CACFMachPort::ReceiveMessage(UInt32 inMaxMessageSize, mach_msg_header_t* outMessage, mach_msg_timeout_t inTimeOut)
+{
+ // snag the port
+ mach_port_t thePort = CFMachPortGetPort(mMachPort);
+
+ // fill out the message header
+ outMessage->msgh_bits = 0;
+ outMessage->msgh_size = 0;
+ outMessage->msgh_remote_port = MACH_PORT_NULL;
+ outMessage->msgh_local_port = thePort;
+ outMessage->msgh_reserved = 0;
+ outMessage->msgh_id = 0;
+
+ // figure the options
+ mach_msg_options_t theOptions = MACH_RCV_MSG;
+ if(inTimeOut > 0)
+ {
+ theOptions |= MACH_RCV_TIMEOUT;
+ }
+
+ // receive the messsage
+ return mach_msg(outMessage, theOptions, 0, inMaxMessageSize, thePort, inTimeOut, MACH_PORT_NULL);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.h b/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.h
new file mode 100644
index 0000000000..18b8ccc6c2
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFMachPort.h
@@ -0,0 +1,95 @@
+/*
+ File: CACFMachPort.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFMachPort_h__)
+#define __CACFMachPort_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#include <CoreFoundation/CFMachPort.h>
+#include <mach/mach.h>
+
+//==================================================================================================
+// CACFMachPort
+//
+// This class wraps a CFMachPort.
+//
+// Note that when you create a CFMachPort object, CF will attach the run loop source for the the
+// Mach Port that handles Port Death notifications (aka the Invalidation Callback) to the current
+// thread's run loop. This is something over which there is no control, so be sure to create the
+// CFMachPort on the thread on which you want to handle Port Death notificaitons on.
+//==================================================================================================
+
+class CACFMachPort
+{
+
+// Construction/Destruction
+public:
+ CACFMachPort(CFMachPortCallBack inCallBack, void* inUserData = NULL);
+ CACFMachPort(mach_port_t inMachPort, CFMachPortCallBack inCallBack, CFMachPortInvalidationCallBack inInvalidationCallBack, void* inUserData);
+ virtual ~CACFMachPort();
+
+// Attributes
+public:
+ CFMachPortRef GetMachPortRef() const { return mMachPort; }
+ mach_port_t GetMachPort() const { return CFMachPortGetPort(mMachPort); }
+ CFRunLoopSourceRef GetRunLoopSource() const { return mRunLoopSource; }
+
+// Operations
+public:
+ kern_return_t ReceiveMessage(UInt32 inMaxMessageSize, mach_msg_header_t* outMessage, mach_msg_timeout_t inTimeOut);
+
+// Implementation
+protected:
+ CFMachPortRef mMachPort;
+ CFRunLoopSourceRef mRunLoopSource;
+ bool mOwnsPort;
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.cpp
new file mode 100644
index 0000000000..97b5da1dd9
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.cpp
@@ -0,0 +1,163 @@
+/*
+ File: CACFMessagePort.cpp
+ Abstract: CACFMessagePort.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CACFMessagePort.h"
+#include "CADebugMacros.h"
+#include "CAException.h"
+
+//=============================================================================
+// CACFLocalMessagePort
+//=============================================================================
+
+CACFLocalMessagePort::CACFLocalMessagePort(CFStringRef inName, CFMessagePortCallBack inPortCallBack, CFMessagePortInvalidationCallBack inInvalidationCallBack, void* inUserData)
+:
+ mMessagePort(NULL),
+ mRunLoopSource(NULL),
+ mDispatchQueue(NULL)
+{
+ // create the CFMessagePort
+ CFMessagePortContext theContext = { 0, inUserData, NULL, NULL, NULL };
+ mMessagePort = CFMessagePortCreateLocal(NULL, inName, inPortCallBack, &theContext, NULL);
+ if(mMessagePort != NULL)
+ {
+ // add the invalidation callback, if any
+ if(inInvalidationCallBack != NULL)
+ {
+ CFMessagePortSetInvalidationCallBack(mMessagePort, inInvalidationCallBack);
+ }
+ }
+}
+
+CACFLocalMessagePort::~CACFLocalMessagePort()
+{
+ if(mRunLoopSource != NULL)
+ {
+ CFRelease(mRunLoopSource);
+ }
+ if(mMessagePort != NULL)
+ {
+ CFMessagePortInvalidate(mMessagePort);
+ CFRelease(mMessagePort);
+ }
+}
+
+CFRunLoopSourceRef CACFLocalMessagePort::GetRunLoopSource() const
+{
+ Assert(mDispatchQueue == NULL, "CACFLocalMessagePort::SetDispatchQueue: should have both a run loop source and a dispatch queue");
+ if(mRunLoopSource == NULL)
+ {
+ const_cast<CACFLocalMessagePort*>(this)->mRunLoopSource = CFMessagePortCreateRunLoopSource(NULL, mMessagePort, 0);
+ }
+ return mRunLoopSource;
+}
+
+void CACFLocalMessagePort::SetDispatchQueue(dispatch_queue_t inDispatchQueue)
+{
+ Assert(mRunLoopSource == NULL, "CACFLocalMessagePort::SetDispatchQueue: should have both a run loop source and a dispatch queue");
+ mDispatchQueue = inDispatchQueue;
+ CFMessagePortSetDispatchQueue(mMessagePort, mDispatchQueue);
+}
+
+//=============================================================================
+// CACFRemoteMessagePort
+//=============================================================================
+
+CACFRemoteMessagePort::CACFRemoteMessagePort(CFStringRef inName, CFMessagePortInvalidationCallBack inInvalidationCallBack)
+:
+ mMessagePort(NULL),
+ mRunLoopSource(NULL),
+ mDispatchQueue(NULL)
+{
+ // create the CFMessagePort
+ mMessagePort = CFMessagePortCreateRemote(NULL, inName);
+ if(mMessagePort != NULL)
+ {
+ // failure to create a remote port does not need to throw an exception
+ // because it isn't really an error since the port in question may not
+ // exist and this fact requires a more complex response than an excpeption
+ // provides for.
+
+ // add the invalidation callback, if any
+ if(inInvalidationCallBack != NULL)
+ {
+ CFMessagePortSetInvalidationCallBack(mMessagePort, inInvalidationCallBack);
+ }
+ }
+}
+
+CACFRemoteMessagePort::~CACFRemoteMessagePort()
+{
+ if(mRunLoopSource != NULL)
+ {
+ CFRelease(mRunLoopSource);
+ }
+ if(mMessagePort != NULL)
+ {
+ //CFMessagePortInvalidate(mMessagePort);
+ CFRelease(mMessagePort);
+ }
+}
+
+CFRunLoopSourceRef CACFRemoteMessagePort::GetRunLoopSource() const
+{
+ Assert(mDispatchQueue == NULL, "CACFRemoteMessagePort::SetDispatchQueue: should have both a run loop source and a dispatch queue");
+ if(mRunLoopSource == NULL)
+ {
+ const_cast<CACFRemoteMessagePort*>(this)->mRunLoopSource = CFMessagePortCreateRunLoopSource(NULL, mMessagePort, 0);
+ }
+ return mRunLoopSource;
+}
+
+void CACFRemoteMessagePort::SetDispatchQueue(dispatch_queue_t inDispatchQueue)
+{
+ Assert(mRunLoopSource == NULL, "CACFRemoteMessagePort::SetDispatchQueue: should have both a run loop source and a dispatch queue");
+ mDispatchQueue = inDispatchQueue;
+ CFMessagePortSetDispatchQueue(mMessagePort, mDispatchQueue);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.h b/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.h
new file mode 100644
index 0000000000..c369251664
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFMessagePort.h
@@ -0,0 +1,119 @@
+/*
+ File: CACFMessagePort.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFMessagePort_h__)
+#define __CACFMessagePort_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CFMessagePort.h>
+#else
+ #include <CFMessagePort.h>
+#endif
+
+//=============================================================================
+// CACFLocalMessagePort
+//=============================================================================
+
+class CACFLocalMessagePort
+{
+
+// Construction/Destruction
+public:
+ CACFLocalMessagePort(CFStringRef inName, CFMessagePortCallBack inPortCallBack, CFMessagePortInvalidationCallBack inInvalidationCallBack, void* inUserData = NULL);
+ virtual ~CACFLocalMessagePort();
+
+// Attributes
+public:
+ bool IsValid() const { return mMessagePort != NULL; }
+ CFMessagePortRef GetMessagePortRef() const { return mMessagePort; }
+ CFRunLoopSourceRef GetRunLoopSource() const;
+ void SetDispatchQueue(dispatch_queue_t inDispatchQueue);
+
+// Implementation
+protected:
+ CFMessagePortRef mMessagePort;
+ CFRunLoopSourceRef mRunLoopSource;
+ dispatch_queue_t mDispatchQueue;
+
+};
+
+//=============================================================================
+// CACFRemoteMessagePort
+//=============================================================================
+
+class CACFRemoteMessagePort
+{
+
+// Construction/Destruction
+public:
+ CACFRemoteMessagePort(CFStringRef inName, CFMessagePortInvalidationCallBack inInvalidationCallBack);
+ virtual ~CACFRemoteMessagePort();
+
+// Attributes
+public:
+ bool IsValid() const { return mMessagePort != NULL; }
+ CFMessagePortRef GetMessagePortRef() const { return mMessagePort; }
+ CFRunLoopSourceRef GetRunLoopSource() const;
+ void SetDispatchQueue(dispatch_queue_t inDispatchQueue);
+
+// Operations
+public:
+ SInt32 SendRequest(SInt32 inMessageID, CFDataRef inData, CFTimeInterval inSendTimeout, CFTimeInterval inReceiveTimout) const { return CFMessagePortSendRequest(mMessagePort, inMessageID, inData, inSendTimeout, inReceiveTimout, NULL, NULL); }
+ SInt32 SendRequest(SInt32 inMessageID, CFDataRef inData, CFTimeInterval inSendTimeout, CFTimeInterval inReceiveTimout, CFStringRef inReplyMode, CFDataRef& outReturnData) const { return CFMessagePortSendRequest(mMessagePort, inMessageID, inData, inSendTimeout, inReceiveTimout, inReplyMode, &outReturnData); }
+
+// Implementation
+protected:
+ CFMessagePortRef mMessagePort;
+ CFRunLoopSourceRef mRunLoopSource;
+ dispatch_queue_t mDispatchQueue;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.cpp
new file mode 100644
index 0000000000..36d1c2e2e2
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.cpp
@@ -0,0 +1,83 @@
+/*
+ File: CACFNumber.cpp
+ Abstract: CACFNumber.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CACFNumber.h"
+
+//=============================================================================
+// CACFNumber
+//=============================================================================
+
+Float32 CACFNumber::GetFixed32() const
+{
+ SInt32 theFixedValue = GetSInt32();
+
+ // this is a 16.16 value so convert it to a float
+ Float32 theSign = theFixedValue < 0 ? -1.0f : 1.0f;
+ theFixedValue *= (SInt32)theSign;
+ Float32 theWholePart = (theFixedValue & 0x7FFF0000) >> 16;
+ Float32 theFractPart = theFixedValue & 0x0000FFFF;
+ theFractPart /= 65536.0f;
+
+ return theSign * (theWholePart + theFractPart);
+}
+
+Float64 CACFNumber::GetFixed64() const
+{
+ SInt64 theFixedValue = GetSInt64();
+
+ // this is a 32.32 value so convert it to a double
+ Float64 theSign = theFixedValue < 0 ? -1.0 : 1.0;
+ theFixedValue *= (SInt64)theSign;
+ Float64 theWholePart = (theFixedValue & 0x7FFFFFFF00000000LL) >> 32;
+ Float64 theFractPart = theFixedValue & 0x00000000FFFFFFFFLL;
+ theFractPart /= 4294967296.0;
+
+ return theSign * (theWholePart + theFractPart);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.h b/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.h
new file mode 100644
index 0000000000..25887f6ca1
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFNumber.h
@@ -0,0 +1,151 @@
+/*
+ File: CACFNumber.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFNumber_h__)
+#define __CACFNumber_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CFNumber.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CFNumber.h>
+#endif
+
+//=============================================================================
+// CACFBoolean
+//=============================================================================
+
+class CACFBoolean
+{
+// Construction/Destruction
+public:
+ explicit CACFBoolean(CFBooleanRef inCFBoolean) : mCFBoolean(inCFBoolean), mWillRelease(true) {}
+ CACFBoolean(CFBooleanRef inCFBoolean, bool inWillRelease) : mCFBoolean(inCFBoolean), mWillRelease(inWillRelease) {}
+ explicit CACFBoolean(bool inValue) : mCFBoolean(inValue ? kCFBooleanTrue : kCFBooleanFalse), mWillRelease(true) { Retain(); }
+ ~CACFBoolean() { Release(); }
+ CACFBoolean(const CACFBoolean& inBoolean) : mCFBoolean(inBoolean.mCFBoolean), mWillRelease(inBoolean.mWillRelease) { Retain(); }
+ CACFBoolean& operator=(const CACFBoolean& inBoolean) { Release(); mCFBoolean = inBoolean.mCFBoolean; mWillRelease = inBoolean.mWillRelease; Retain(); return *this; }
+ CACFBoolean& operator=(CFBooleanRef inCFBoolean) { Release(); mCFBoolean = inCFBoolean; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFBoolean != NULL)) { CFRetain(mCFBoolean); } }
+ void Release() { if(mWillRelease && (mCFBoolean != NULL)) { CFRelease(mCFBoolean); } }
+
+ CFBooleanRef mCFBoolean;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() { return mCFBoolean != NULL; }
+
+// Value Access
+public:
+ CFBooleanRef GetCFBoolean() const { return mCFBoolean; }
+ CFBooleanRef CopyCFBoolean() const { if(mCFBoolean != NULL) { CFRetain(mCFBoolean); } return mCFBoolean; }
+
+ bool GetBoolean() const { bool theAnswer = false; if(mCFBoolean != NULL) { theAnswer = CFEqual(mCFBoolean, kCFBooleanTrue); } return theAnswer; }
+
+ CACFBoolean(const void*); // prevent accidental instantiation with a pointer via bool constructor
+};
+
+//=============================================================================
+// CACFNumber
+//=============================================================================
+
+class CACFNumber
+{
+// Construction/Destruction
+public:
+ explicit CACFNumber(CFNumberRef inCFNumber) : mCFNumber(inCFNumber), mWillRelease(true) {}
+ CACFNumber(CFNumberRef inCFNumber, bool inWillRelease) : mCFNumber(inCFNumber), mWillRelease(inWillRelease) {}
+ CACFNumber(SInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(UInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(SInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(UInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(Float32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(Float64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat64Type, &inValue)), mWillRelease(true) {}
+ ~CACFNumber() { Release(); }
+ CACFNumber(const CACFNumber& inNumber) : mCFNumber(inNumber.mCFNumber), mWillRelease(inNumber.mWillRelease) { Retain(); }
+ CACFNumber& operator=(const CACFNumber& inNumber) { Release(); mCFNumber = inNumber.mCFNumber; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
+ CACFNumber& operator=(CFNumberRef inCFNumber) { Release(); mCFNumber = inCFNumber; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFNumber != NULL)) { CFRetain(mCFNumber); } }
+ void Release() { if(mWillRelease && (mCFNumber != NULL)) { CFRelease(mCFNumber); } }
+
+ CFNumberRef mCFNumber;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() const { return mCFNumber != NULL; }
+
+// Value Access
+public:
+ CFNumberRef GetCFNumber() const { return mCFNumber; }
+ CFNumberRef CopyCFNumber() const { if(mCFNumber != NULL) { CFRetain(mCFNumber); } return mCFNumber; }
+
+ SInt8 GetSInt8() const { SInt8 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt8Type, &theAnswer); } return theAnswer; }
+ SInt32 GetSInt32() const { SInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
+ UInt32 GetUInt32() const { UInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
+ Float32 GetFloat32() const { Float32 theAnswer = 0.0f; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberFloat32Type, &theAnswer); } return theAnswer; }
+ Float32 GetFixed32() const;
+ Float64 GetFixed64() const;
+ SInt64 GetSInt64() const { SInt64 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt64Type, &theAnswer); } return theAnswer; }
+
+ CACFNumber(const void*); // prevent accidental instantiation with a pointer via bool constructor
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFObject.h b/libs/appleutility/CoreAudio/PublicUtility/CACFObject.h
new file mode 100644
index 0000000000..748016b48f
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFObject.h
@@ -0,0 +1,138 @@
+/*
+ File: CACFObject.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFObject_h__)
+#define __CACFObject_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CoreFoundation.h>
+#endif
+
+//=============================================================================
+// Wrappers for CFRetain and CFRelease that check for NULL
+//=============================================================================
+
+template <typename CFObjectType>
+CFObjectType CACFRetain(CFObjectType inObject)
+{
+ CFObjectType theAnswer = inObject;
+ if(inObject != NULL)
+ {
+ theAnswer = reinterpret_cast<CFObjectType>(CFRetain(inObject));
+ }
+ return theAnswer;
+}
+
+inline void CACFRelease(CFTypeRef inObject)
+{
+ if(inObject != NULL)
+ {
+ CFRelease(inObject);
+ }
+}
+
+//=============================================================================
+// CACFObject
+//
+// Notes
+// - Using the AssignWithoutRetain() method will fool the static analyzer into thinking that the
+// CFObject being assigned will be leaked. This is because the static analyzer is not smart
+// enough to understand that the destructor will release the object.
+//=============================================================================
+
+template <class CFObjectType>
+class CACFObject
+{
+
+// Construction/Destruction
+public:
+ CACFObject() : mCFObject(NULL), mWillRelease(true) {}
+ explicit CACFObject(CFObjectType inCFObject) : mCFObject(inCFObject), mWillRelease(true) {}
+ CACFObject(CFObjectType inCFObject, bool inWillRelease) : mCFObject(inCFObject), mWillRelease(inWillRelease) {}
+ ~CACFObject() { Release(); }
+ CACFObject(const CACFObject& inObject) : mCFObject(inObject.mCFObject), mWillRelease(inObject.mWillRelease) { Retain(); }
+ CACFObject& operator=(const CACFObject& inObject) { Release(); mCFObject = inObject.mCFObject; mWillRelease = inObject.mWillRelease; Retain(); return *this; }
+ CACFObject& operator=(CFObjectType inCFObject) { Release(); mCFObject = inCFObject; mWillRelease = true; Retain(); return *this; }
+ void AssignWithoutRetain(CFObjectType inObject) { if (inObject != mCFObject) { Release(); mCFObject = inObject; } mWillRelease = true; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFObject != NULL)) { CFRetain(mCFObject); } }
+ void Release() { if(mWillRelease && (mCFObject != NULL)) { CFRelease(mCFObject); mCFObject = NULL; } }
+
+ CFObjectType mCFObject;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() const { return mCFObject != NULL; }
+ CFTypeID GetTypeID() const { return CFGetTypeID(mCFObject); }
+ bool IsEqual(CFObjectType inCFObject) const { return CFEqual(inCFObject, mCFObject) != 0; }
+
+// Value Access
+public:
+ CFObjectType GetCFObject() const { return mCFObject; }
+ CFObjectType CopyCFObject() const { if(mCFObject != NULL) { CFRetain(mCFObject); } return mCFObject; }
+ const CFObjectType* GetPointerToStorage() const { return &mCFObject; }
+
+};
+
+typedef CACFObject<CFBundleRef> CACFBundle;
+typedef CACFObject<CFPropertyListRef> CACFPropertyList;
+typedef CACFObject<CFTypeRef> CACFType;
+typedef CACFObject<CFUUIDRef> CACFUUID;
+typedef CACFObject<CFURLRef> CACFURL;
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFPlugIn.h b/libs/appleutility/CoreAudio/PublicUtility/CACFPlugIn.h
new file mode 100644
index 0000000000..babde13b90
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFPlugIn.h
@@ -0,0 +1,101 @@
+/*
+ File: CACFPlugIn.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFPlugIn_h__)
+#define __CACFPlugIn_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreFoundation/CFPlugIn.h>
+
+//==================================================================================================
+// CACFPlugIn
+//==================================================================================================
+
+class CACFPlugIn
+{
+
+// Construction/Destruction
+public:
+ CACFPlugIn() : mCFPlugIn(NULL), mWillRelease(true) {}
+ CACFPlugIn(CFPlugInRef inCFPlugIn, bool inWillRelease = true) : mCFPlugIn(inCFPlugIn), mWillRelease(inWillRelease) {}
+ CACFPlugIn(CFURLRef inURL, bool inWillRelease = true) : mCFPlugIn(CFPlugInCreate(NULL, inURL)), mWillRelease(inWillRelease) {}
+ ~CACFPlugIn() { Release(); }
+ CACFPlugIn(const CACFPlugIn& inObject) : mCFPlugIn(inObject.mCFPlugIn), mWillRelease(inObject.mWillRelease) { Retain(); }
+ CACFPlugIn& operator=(const CACFPlugIn& inObject) { Release(); mCFPlugIn = inObject.mCFPlugIn; mWillRelease = inObject.mWillRelease; Retain(); return *this; }
+ CACFPlugIn& operator=(CFPlugInRef inCFPlugIn) { Release(); mCFPlugIn = inCFPlugIn; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFPlugIn != NULL)) { CFRetain(mCFPlugIn); } }
+ void Release() { if(mWillRelease && (mCFPlugIn != NULL)) { CFRelease(mCFPlugIn); mCFPlugIn = NULL; } }
+
+ CFPlugInRef mCFPlugIn;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() const { return mCFPlugIn != NULL; }
+
+ CFBundleRef GetBundle() const { CFBundleRef theAnswer = NULL; if(IsValid()) { theAnswer = CFPlugInGetBundle(mCFPlugIn); } return theAnswer; }
+ CFStringRef CopyBundleID() const { CFStringRef theAnswer = NULL; CFBundleRef theBundle = GetBundle(); if(IsValid() && (theBundle != NULL)) { theAnswer = CFBundleGetIdentifier(theBundle); if(theAnswer != NULL) { CFRetain(theAnswer); } } return theAnswer; }
+ UInt32 GetBundleVersion() const { UInt32 theAnswer = 0; CFBundleRef theBundle = GetBundle(); if(IsValid() && (theBundle != NULL)) { theAnswer = CFBundleGetVersionNumber(theBundle); } return theAnswer; }
+ CFDictionaryRef CopyBundleInfo() const { CFDictionaryRef theAnswer = NULL; CFBundleRef theBundle = GetBundle(); if(IsValid() && (theBundle != NULL)) { theAnswer = CFBundleGetInfoDictionary(theBundle); if(theAnswer != NULL) { CFRetain(theAnswer); } } return theAnswer; }
+ CFArrayRef FindFactoriesForType(CFUUIDRef inTypeUUID) const { CFArrayRef theAnswer = NULL; if(IsValid()) { theAnswer = CFPlugInFindFactoriesForPlugInTypeInPlugIn(inTypeUUID, mCFPlugIn); } return theAnswer; }
+
+// Value Access
+public:
+ CFPlugInRef GetCFPlugIn() const { return mCFPlugIn; }
+ CFPlugInRef CopyCFPlugIn() const { if(mCFPlugIn != NULL) { CFRetain(mCFPlugIn); } return mCFPlugIn; }
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.cpp
new file mode 100644
index 0000000000..cb2e86c34d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.cpp
@@ -0,0 +1,287 @@
+/*
+ File: CACFPreferences.cpp
+ Abstract: CACFPreferences.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CACFPreferences.h"
+
+// PublicUtility Includes
+#include "CACFDistributedNotification.h"
+#include "CADebugMacros.h"
+
+//==================================================================================================
+// CACFPreferences
+//==================================================================================================
+
+CFPropertyListRef CACFPreferences::CopyValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost)
+{
+ // synchronize to make sure that what's in memory matches what's on disk
+ Synchronize(inCurrentUser, inCurrentHost, false);
+
+ CFPropertyListRef theAnswer = NULL;
+ CFStringRef theUser = inCurrentUser ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
+ CFStringRef theHost = inCurrentHost ? kCFPreferencesCurrentHost : kCFPreferencesAnyHost;
+
+ theAnswer = CFPreferencesCopyValue(inKey, kCFPreferencesAnyApplication, theUser, theHost);
+
+ return theAnswer;
+}
+
+CFStringRef CACFPreferences::CopyStringValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost)
+{
+ CFStringRef theAnswer = NULL;
+
+ // get the raw value
+ CFPropertyListRef theRawValue = CopyValue(inKey, inCurrentUser, inCurrentHost);
+
+ if(theRawValue != NULL)
+ {
+ // get it's type ID and make sure it's a CFString
+ CFTypeID theTypeID = CFGetTypeID(theRawValue);
+ if(theTypeID == CFStringGetTypeID())
+ {
+ // cast the value
+ theAnswer = static_cast<CFStringRef>(theRawValue);
+ }
+ else
+ {
+ CFRelease(theRawValue);
+ DebugMessage("CACFPreferences::CopyStringValue: not a CFString");
+ }
+ }
+
+ return theAnswer;
+}
+
+CFNumberRef CACFPreferences::CopyNumberValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost)
+{
+ CFNumberRef theAnswer = NULL;
+
+ // get the raw value
+ CFPropertyListRef theRawValue = CopyValue(inKey, inCurrentUser, inCurrentHost);
+
+ if(theRawValue != NULL)
+ {
+ // get it's type ID and make sure it's a CFNumber
+ CFTypeID theTypeID = CFGetTypeID(theRawValue);
+ if(theTypeID == CFNumberGetTypeID())
+ {
+ // cast the value
+ theAnswer = static_cast<CFNumberRef>(theRawValue);
+ }
+ else
+ {
+ CFRelease(theRawValue);
+ DebugMessage("CACFPreferences::CopyNumberValue: not a CFNumber");
+ }
+ }
+
+ return theAnswer;
+}
+
+CFArrayRef CACFPreferences::CopyArrayValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost)
+{
+ CFArrayRef theAnswer = NULL;
+
+ // get the raw value
+ CFPropertyListRef theRawValue = CopyValue(inKey, inCurrentUser, inCurrentHost);
+
+ if(theRawValue != NULL)
+ {
+ // get it's type ID and make sure it's a CFArray
+ CFTypeID theTypeID = CFGetTypeID(theRawValue);
+ if(theTypeID == CFArrayGetTypeID())
+ {
+ // cast the value
+ theAnswer = static_cast<CFArrayRef>(theRawValue);
+ }
+ else
+ {
+ CFRelease(theRawValue);
+ DebugMessage("CACFPreferences::CopyArrayValue: not a CFArray");
+ }
+ }
+
+ return theAnswer;
+}
+
+CFDictionaryRef CACFPreferences::CopyDictionaryValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost)
+{
+ CFDictionaryRef theAnswer = NULL;
+
+ // get the raw value
+ CFPropertyListRef theRawValue = CopyValue(inKey, inCurrentUser, inCurrentHost);
+
+ if(theRawValue != NULL)
+ {
+ // get it's type ID and make sure it's a CFDictionary
+ CFTypeID theTypeID = CFGetTypeID(theRawValue);
+ if(theTypeID == CFDictionaryGetTypeID())
+ {
+ // cast the value
+ theAnswer = static_cast<CFDictionaryRef>(theRawValue);
+ }
+ else
+ {
+ CFRelease(theRawValue);
+ DebugMessage("CACFPreferences::CopyDictionaryValue: not a CFDictionary");
+ }
+ }
+
+ return theAnswer;
+}
+
+void CACFPreferences::SetValue(CFStringRef inKey, CFPropertyListRef inValue, bool inCurrentUser, bool inCurrentHost, bool inSynchronize)
+{
+ CFStringRef theUser = inCurrentUser ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
+ CFStringRef theHost = inCurrentHost ? kCFPreferencesCurrentHost : kCFPreferencesAnyHost;
+ CFPreferencesSetValue(inKey, inValue, kCFPreferencesAnyApplication, theUser, theHost);
+
+ if(inSynchronize)
+ {
+ Synchronize(inCurrentUser, inCurrentHost, true);
+ }
+}
+
+void CACFPreferences::DeleteValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost, bool inSynchronize)
+{
+ CFStringRef theUser = inCurrentUser ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
+ CFStringRef theHost = inCurrentHost ? kCFPreferencesCurrentHost : kCFPreferencesAnyHost;
+ CFPreferencesSetValue(inKey, NULL, kCFPreferencesAnyApplication, theUser, theHost);
+
+ if(inSynchronize)
+ {
+ Synchronize(theUser, inCurrentHost, true);
+ }
+}
+
+void CACFPreferences::Synchronize(bool inCurrentUser, bool inCurrentHost, bool inForce)
+{
+ if(inForce || ArePrefsOutOfDate(inCurrentUser, inCurrentHost))
+ {
+ CFStringRef theUser = inCurrentUser ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
+ CFStringRef theHost = inCurrentHost ? kCFPreferencesCurrentHost : kCFPreferencesAnyHost;
+ CFPreferencesSynchronize(kCFPreferencesAnyApplication, theUser, theHost);
+ MarkPrefsClean(inCurrentUser, inCurrentHost);
+ }
+}
+
+void CACFPreferences::MarkPrefsOutOfDate(bool inCurrentUser, bool inCurrentHost)
+{
+ if(!inCurrentUser && !inCurrentHost)
+ {
+ sAnyUserAnyHostPrefsOutOfDate = true;
+ }
+ else if(!inCurrentUser && inCurrentHost)
+ {
+ sAnyUserCurrentHostPrefsOutOfDate = true;
+ }
+ else if(inCurrentUser && !inCurrentHost)
+ {
+ sCurrentUserAnyHostPrefsOutOfDate = true;
+ }
+ else if(inCurrentUser && inCurrentHost)
+ {
+ sCurrentUserCurrentHostPrefsOutOfDate = true;
+ }
+}
+
+void CACFPreferences::MarkPrefsClean(bool inCurrentUser, bool inCurrentHost)
+{
+ if(!inCurrentUser && !inCurrentHost)
+ {
+ sAnyUserAnyHostPrefsOutOfDate = false;
+ }
+ else if(!inCurrentUser && inCurrentHost)
+ {
+ sAnyUserCurrentHostPrefsOutOfDate = false;
+ }
+ else if(inCurrentUser && !inCurrentHost)
+ {
+ sCurrentUserAnyHostPrefsOutOfDate = false;
+ }
+ else if(inCurrentUser && inCurrentHost)
+ {
+ sCurrentUserCurrentHostPrefsOutOfDate = false;
+ }
+}
+
+void CACFPreferences::SendNotification(CFStringRef inName)
+{
+ CACFDistributedNotification::PostNotification(inName, NULL, true);
+}
+
+bool CACFPreferences::ArePrefsOutOfDate(bool inCurrentUser, bool inCurrentHost)
+{
+ bool theAnswer = false;
+
+ if(!inCurrentUser && !inCurrentHost)
+ {
+ theAnswer = sAnyUserAnyHostPrefsOutOfDate;
+ }
+ else if(!inCurrentUser && inCurrentHost)
+ {
+ theAnswer = sAnyUserCurrentHostPrefsOutOfDate;
+ }
+ else if(inCurrentUser && !inCurrentHost)
+ {
+ theAnswer = sCurrentUserAnyHostPrefsOutOfDate;
+ }
+ else if(inCurrentUser && inCurrentHost)
+ {
+ theAnswer = sCurrentUserCurrentHostPrefsOutOfDate;
+ }
+
+ return theAnswer;
+}
+
+bool CACFPreferences::sAnyUserAnyHostPrefsOutOfDate = false;
+bool CACFPreferences::sAnyUserCurrentHostPrefsOutOfDate = false;
+bool CACFPreferences::sCurrentUserAnyHostPrefsOutOfDate = false;
+bool CACFPreferences::sCurrentUserCurrentHostPrefsOutOfDate = false;
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.h b/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.h
new file mode 100644
index 0000000000..040490f74e
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFPreferences.h
@@ -0,0 +1,92 @@
+/*
+ File: CACFPreferences.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFPreferences_h__)
+#define __CACFPreferences_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreFoundation.h>
+#endif
+
+//==================================================================================================
+// CACFPreferences
+//==================================================================================================
+
+class CACFPreferences
+{
+
+// Operations
+public:
+ static CFPropertyListRef CopyValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost);
+ static CFStringRef CopyStringValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost);
+ static CFNumberRef CopyNumberValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost);
+ static CFArrayRef CopyArrayValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost);
+ static CFDictionaryRef CopyDictionaryValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost);
+ static void SetValue(CFStringRef inKey, CFPropertyListRef inValue, bool inCurrentUser, bool inCurrentHost, bool inSynchronize);
+ static void DeleteValue(CFStringRef inKey, bool inCurrentUser, bool inCurrentHost, bool inSynchronize);
+ static void Synchronize(bool inCurrentUser, bool inCurrentHost, bool inForce);
+ static void MarkPrefsOutOfDate(bool inCurrentUser, bool inCurrentHost);
+ static void MarkPrefsClean(bool inCurrentUser, bool inCurrentHost);
+ static void SendNotification(CFStringRef inName);
+
+private:
+ static bool ArePrefsOutOfDate(bool inCurrentUser, bool inCurrentHost);
+
+ static bool sAnyUserAnyHostPrefsOutOfDate;
+ static bool sAnyUserCurrentHostPrefsOutOfDate;
+ static bool sCurrentUserAnyHostPrefsOutOfDate;
+ static bool sCurrentUserCurrentHostPrefsOutOfDate;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFString.cpp b/libs/appleutility/CoreAudio/PublicUtility/CACFString.cpp
new file mode 100644
index 0000000000..3ce81a56f4
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFString.cpp
@@ -0,0 +1,110 @@
+/*
+ File: CACFString.cpp
+ Abstract: CACFString.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CACFString.h"
+
+//=============================================================================
+// CACFString
+//=============================================================================
+
+UInt32 CACFString::GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding)
+{
+ CFIndex theAnswer = 0;
+
+ if(inCFString != NULL)
+ {
+ CFRange theRange = { 0, CFStringGetLength(inCFString) };
+ CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, NULL, 0x7FFFFFFF, &theAnswer);
+ }
+
+ return UInt32(theAnswer);
+}
+
+void CACFString::GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding)
+{
+ if(ioStringSize > 0)
+ {
+ if(inCFString != NULL)
+ {
+ CFIndex theLength = 0;
+ CFRange theRange = { 0, CFStringGetLength(inCFString) };
+ CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, (UInt8*)outString, static_cast<CFIndex>(ioStringSize - 1), &theLength);
+ outString[theLength] = 0;
+ ioStringSize = ToUInt32(theLength) + 1;
+ }
+ else
+ {
+ outString[0] = 0;
+ ioStringSize = 1;
+ }
+ }
+}
+
+void CACFString::GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize)
+{
+ if(ioStringSize > 0)
+ {
+ if(inCFString != NULL)
+ {
+ CFRange theStringRange = { 0, CFStringGetLength(inCFString) };
+ if(static_cast<UInt32>(theStringRange.length) > ioStringSize)
+ {
+ theStringRange.length = static_cast<CFIndex>(ioStringSize);
+ }
+ CFStringGetCharacters(inCFString, theStringRange, outString);
+ ioStringSize = ToUInt32(theStringRange.length);
+ }
+ else
+ {
+ outString[0] = 0;
+ ioStringSize = 0;
+ }
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CACFString.h b/libs/appleutility/CoreAudio/PublicUtility/CACFString.h
new file mode 100644
index 0000000000..3abce514bf
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CACFString.h
@@ -0,0 +1,196 @@
+/*
+ File: CACFString.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CACFString_h__)
+#define __CACFString_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CADebugMacros.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CFString.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CFString.h>
+#endif
+
+//=============================================================================
+// CACFString
+//
+// Notes
+// - Using the AssignWithoutRetain() method will fool the static analyzer into thinking that the
+// CFString being assigned will be leaked. This is because the static analyzer is not smart
+// enough to understand that the destructor will release the object.
+//=============================================================================
+
+class CACFString
+{
+// Construction/Destruction
+public:
+ CACFString() : mCFString(NULL), mWillRelease(true) {}
+ explicit CACFString(CFStringRef inCFString) : mCFString(inCFString), mWillRelease(true) {}
+ CACFString(const char* inCString) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(true) {}
+ CACFString(CFStringRef inCFString, bool inWillRelease) : mCFString(inCFString), mWillRelease(inWillRelease) {}
+ CACFString(const char* inCString, bool inWillRelease) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(inWillRelease) {}
+ CACFString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, inCStringEncoding)), mWillRelease(inWillRelease) {}
+ ~CACFString() { Release(); }
+ CACFString(const CACFString& inString) : mCFString(inString.mCFString), mWillRelease(inString.mWillRelease) { Retain(); }
+ CACFString& operator=(const CACFString& inString) { if (inString.mCFString != mCFString) { Release(); mCFString = inString.mCFString; mWillRelease = inString.mWillRelease; Retain(); } return *this; }
+ CACFString& operator=(CFStringRef inCFString) { if (inCFString != mCFString) { Release(); mCFString = inCFString; } mWillRelease = true; Retain(); return *this; }
+ void AssignWithoutRetain(CFStringRef inCFString) { if (inCFString != mCFString) { Release(); mCFString = inCFString; } mWillRelease = true; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFString != NULL)) { CFRetain(mCFString); } }
+ void Release() { if(mWillRelease && (mCFString != NULL)) { CFRelease(mCFString); } }
+
+ CFStringRef mCFString;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() const { return mCFString != NULL; }
+ bool IsEqualTo(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringCompare(inString, mCFString, 0) == kCFCompareEqualTo; } return theAnswer; }
+ bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasPrefix(mCFString, inString); } return theAnswer; }
+ bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasSuffix(mCFString, inString); } return theAnswer; }
+
+// Value Access
+public:
+ CFStringRef GetCFString() const { return mCFString; }
+ CFStringRef CopyCFString() const { if(mCFString != NULL) { CFRetain(mCFString); } return mCFString; }
+ const CFStringRef* GetPointerToStorage() const { return &mCFString; }
+ CFStringRef& GetStorage() { Release(); mWillRelease = true; return mCFString; }
+ UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = ToUInt32(CFStringGetLength(mCFString)); } return theAnswer; }
+ UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = GetStringByteLength(mCFString, inEncoding); } return theAnswer; }
+ void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { GetCString(mCFString, outString, ioStringSize, inEncoding); }
+ void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { GetUnicodeString(mCFString, outString, ioStringSize); }
+ SInt32 GetAsInteger() { return GetAsInteger(mCFString); }
+ Float64 GetAsFloat64() { return GetAsFloat64(mCFString); }
+
+ static UInt32 GetStringLength(CFStringRef inCFString) { UInt32 theAnswer = 0; if(inCFString != NULL) { theAnswer = ToUInt32(CFStringGetLength(inCFString)); } return theAnswer; }
+ static UInt32 GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
+ static void GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
+ static void GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize);
+ static SInt32 GetAsInteger(CFStringRef inCFString) { SInt32 theAnswer = 0; if(inCFString != NULL){ theAnswer = CFStringGetIntValue(inCFString); } return theAnswer; }
+ static Float64 GetAsFloat64(CFStringRef inCFString) { Float64 theAnswer = 0; if(inCFString != NULL){ theAnswer = CFStringGetDoubleValue(inCFString); } return theAnswer; }
+
+};
+
+inline bool operator<(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareLessThan; }
+inline bool operator==(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareEqualTo; }
+inline bool operator!=(const CACFString& x, const CACFString& y) { return !(x == y); }
+inline bool operator<=(const CACFString& x, const CACFString& y) { return (x < y) || (x == y); }
+inline bool operator>=(const CACFString& x, const CACFString& y) { return !(x < y); }
+inline bool operator>(const CACFString& x, const CACFString& y) { return !((x < y) || (x == y)); }
+
+inline bool operator<(const CACFString& x, CFStringRef y) { return CFStringCompare(x.GetCFString(), y, 0) == kCFCompareLessThan; }
+inline bool operator==(const CACFString& x, CFStringRef y) { return CFStringCompare(x.GetCFString(), y, 0) == kCFCompareEqualTo; }
+inline bool operator!=(const CACFString& x, CFStringRef y) { return !(x == y); }
+inline bool operator<=(const CACFString& x, CFStringRef y) { return (x < y) || (x == y); }
+inline bool operator>=(const CACFString& x, CFStringRef y) { return !(x < y); }
+inline bool operator>(const CACFString& x, CFStringRef y) { return !((x < y) || (x == y)); }
+
+inline bool operator<(CFStringRef x, const CACFString& y) { return CFStringCompare(x, y.GetCFString(), 0) == kCFCompareLessThan; }
+inline bool operator==(CFStringRef x, const CACFString& y) { return CFStringCompare(x, y.GetCFString(), 0) == kCFCompareEqualTo; }
+inline bool operator!=(CFStringRef x, const CACFString& y) { return !(x == y); }
+inline bool operator<=(CFStringRef x, const CACFString& y) { return (x < y) || (x == y); }
+inline bool operator>=(CFStringRef x, const CACFString& y) { return !(x < y); }
+inline bool operator>(CFStringRef x, const CACFString& y) { return !((x < y) || (x == y)); }
+
+//=============================================================================
+// CACFMutableString
+//=============================================================================
+
+class CACFMutableString
+{
+// Construction/Destruction
+public:
+ CACFMutableString() : mCFMutableString(NULL), mWillRelease(true) {}
+ CACFMutableString(CFMutableStringRef inCFMutableString, bool inWillRelease = true) : mCFMutableString(inCFMutableString), mWillRelease(inWillRelease) {}
+ CACFMutableString(CFStringRef inStringToCopy, bool /*inMakeCopy*/, bool inWillRelease = true) : mCFMutableString(CFStringCreateMutableCopy(NULL, 0, inStringToCopy)), mWillRelease(inWillRelease) {}
+ CACFMutableString(const char* inCString, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
+ CACFMutableString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString, inCStringEncoding); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
+ ~CACFMutableString() { Release(); }
+ CACFMutableString(const CACFMutableString& inString) : mCFMutableString(inString.mCFMutableString), mWillRelease(inString.mWillRelease) { Retain(); }
+ CACFMutableString& operator=(const CACFMutableString& inString) { Release(); mCFMutableString = inString.mCFMutableString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
+ CACFMutableString& operator=(CFMutableStringRef inCFMutableString) { Release(); mCFMutableString = inCFMutableString; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFMutableString != NULL)) { CFRetain(mCFMutableString); } }
+ void Release() { if(mWillRelease && (mCFMutableString != NULL)) { CFRelease(mCFMutableString); } }
+
+ CFMutableStringRef mCFMutableString;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() { return mCFMutableString != NULL; }
+ bool IsEqualTo(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringCompare(inString, mCFMutableString, 0) == kCFCompareEqualTo; } return theAnswer; }
+ bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasPrefix(mCFMutableString, inString); } return theAnswer; }
+ bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasSuffix(mCFMutableString, inString); } return theAnswer; }
+ void Append(CFStringRef inString) { if(mCFMutableString != NULL) { CFStringAppend(mCFMutableString, inString); } }
+
+// Value Access
+public:
+ CFMutableStringRef GetCFMutableString() const { return mCFMutableString; }
+ CFMutableStringRef CopyCFMutableString() const { if(mCFMutableString != NULL) { CFRetain(mCFMutableString); } return mCFMutableString; }
+ UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = ToUInt32(CFStringGetLength(mCFMutableString)); } return theAnswer; }
+ UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CACFString::GetStringByteLength(mCFMutableString, inEncoding); } return theAnswer; }
+ void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { CACFString::GetCString(mCFMutableString, outString, ioStringSize, inEncoding); }
+ void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { CACFString::GetUnicodeString(mCFMutableString, outString, ioStringSize); }
+ SInt32 GetAsInteger() { return CACFString::GetAsInteger(mCFMutableString); }
+ Float64 GetAsFloat64() { return CACFString::GetAsFloat64(mCFMutableString); }
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAComponent.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAComponent.cpp
new file mode 100644
index 0000000000..04eae545cf
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAComponent.cpp
@@ -0,0 +1,182 @@
+/*
+ File: CAComponent.cpp
+ Abstract: CAComponent.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAComponent.h"
+#include "CAComponentDescription.h"
+#include "CACFDictionary.h"
+#include <stdlib.h>
+#include "CAAutoDisposer.h"
+
+CAComponent::CAComponent (const AudioComponentDescription& inDesc, CAComponent* next)
+ : mManuName(0), mAUName(0), mCompName(0)
+{
+ mComp = AudioComponentFindNext ((next ? next->Comp() : NULL), &inDesc);
+ if (mComp)
+ AudioComponentGetDescription(Comp(), &mDesc);
+ else
+ memcpy (&mDesc, &inDesc, sizeof(AudioComponentDescription));
+}
+
+CAComponent::CAComponent (const AudioComponent& comp)
+ : mComp (comp),
+ mManuName(0),
+ mAUName(0),
+ mCompName(0)
+{
+ AudioComponentGetDescription (Comp(), &mDesc);
+}
+
+CAComponent::CAComponent (const AudioComponentInstance& compInst)
+ : mComp (NULL),
+ mManuName(0),
+ mAUName(0),
+ mCompName(0)
+{
+ mComp = AudioComponentInstanceGetComponent (compInst);
+ AudioComponentGetDescription (Comp(), &mDesc);
+}
+
+CAComponent::CAComponent (OSType inType, OSType inSubtype, OSType inManu)
+ : mDesc (inType, inSubtype, inManu),
+ mManuName(0), mAUName(0), mCompName(0)
+{
+ mComp = AudioComponentFindNext (NULL, &mDesc);
+ AudioComponentGetDescription (Comp(), &mDesc);
+}
+
+CAComponent::~CAComponent ()
+{
+ Clear();
+}
+
+OSStatus CAComponent::GetVersion (UInt32 &outVersion) const
+{
+ return AudioComponentGetVersion (mComp, &outVersion);
+}
+
+void CAComponent::Clear ()
+{
+ if (mManuName) { CFRelease (mManuName); mManuName = 0; }
+ if (mAUName) { CFRelease (mAUName); mAUName = 0; }
+ if (mCompName) { CFRelease (mCompName); mCompName = 0; }
+}
+
+CAComponent& CAComponent::operator= (const CAComponent& y)
+{
+ Clear();
+
+ mComp = y.mComp;
+ mDesc = y.mDesc;
+
+ if (y.mManuName) { mManuName = y.mManuName; CFRetain (mManuName); }
+ if (y.mAUName) { mAUName = y.mAUName; CFRetain (mAUName); }
+ if (y.mCompName) { mCompName = y.mCompName; CFRetain (mCompName); }
+
+ return *this;
+}
+
+void CAComponent::SetCompNames () const
+{
+ if (!mCompName) {
+
+ CFStringRef compName;
+ OSStatus result = AudioComponentCopyName (Comp(), &compName);
+ if (result) return;
+
+ const_cast<CAComponent*>(this)->mCompName = compName;
+ if (compName)
+ {
+ CFArrayRef splitStrArray = CFStringCreateArrayBySeparatingStrings(NULL, compName, CFSTR(":"));
+
+ // we need to retain these values so the strings are not lost when the array is released
+ const_cast<CAComponent*>(this)->mManuName = (CFStringRef)CFArrayGetValueAtIndex(splitStrArray, 0);
+ CFRetain(this->mManuName);
+ if (CFArrayGetCount(splitStrArray) > 1)
+ {
+ CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(splitStrArray, 1);
+
+ CFMutableStringRef mstr = CFStringCreateMutableCopy (NULL, CFStringGetLength(str), str);
+
+ // this needs to trim out white space:
+
+ CFStringTrimWhitespace (mstr);
+
+ const_cast<CAComponent*>(this)->mAUName = mstr;
+ } else
+ const_cast<CAComponent*>(this)->mAUName = NULL;
+
+ CFRelease(splitStrArray);
+ }
+ }
+}
+
+static void _ShowCF (FILE* file, CFStringRef str)
+{
+ if (CFGetTypeID(str) != CFStringGetTypeID()) {
+ CFShow(str);
+ return;
+ }
+
+ CFIndex len = CFStringGetLength(str);
+ char* chars = (char*)CA_malloc (len * 2); // give us plenty of room for unichar chars
+ if (CFStringGetCString (str, chars, len * 2, kCFStringEncodingUTF8))
+ fprintf (file, "%s", chars);
+ else
+ CFShow (str);
+
+ free (chars);
+}
+
+void CAComponent::Print(FILE* file) const
+{
+ fprintf (file, "CAComponent: %p", Comp());
+ if (mManuName) {
+ fprintf (file, ", Manu:"); _ShowCF (file, mManuName);
+ if (mAUName) fprintf (file, ", Name:"); _ShowCF (file, mAUName);
+ }
+ fprintf (file, ", ");
+ Desc ().Print(file);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAComponent.h b/libs/appleutility/CoreAudio/PublicUtility/CAComponent.h
new file mode 100644
index 0000000000..5ff24ee01a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAComponent.h
@@ -0,0 +1,121 @@
+/*
+ File: CAComponent.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAComponent_h__
+#define __CAComponent_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+#else
+ #include <ConditionalMacros.h>
+#endif
+
+#include "CAComponentDescription.h"
+
+class CAComponent
+{
+public:
+ CAComponent ()
+ : mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0) {}
+
+ // if next is specifed that is used to find the next component after that one
+ CAComponent (const AudioComponentDescription& inDesc, CAComponent* next = 0);
+
+ CAComponent (const CAComponent& y)
+ : mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0) { *this = y; }
+
+ CAComponent (const AudioComponent& comp);
+
+ CAComponent (const AudioComponentInstance& compInst);
+
+ CAComponent (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
+
+ ~CAComponent ();
+
+ CAComponent& operator= (const CAComponent& y);
+
+ // returns true if this object references a valid component
+ bool IsValid () const { return Comp() != 0; }
+
+ bool HasAUStrings() const { SetCompNames (); return mManuName != 0; }
+
+ // CFStringRef should be retained by caller if needed beyond lifetime of this object
+
+ // Can return NULL if component doesn't follow AU naming conventions
+ CFStringRef GetAUManu () const { SetCompNames (); return mManuName; }
+ CFStringRef GetAUName () const { SetCompNames (); return mAUName ? mAUName : mCompName; }
+
+ // Return value of NULL indicates a problem getting that information from the component
+ CFStringRef GetCompName () const { SetCompNames(); return mCompName; }
+
+ const CAComponentDescription& Desc () const { return mDesc; }
+
+ OSStatus Open (AudioComponentInstance& outInst) const
+ {
+ return AudioComponentInstanceNew (Comp(), &outInst);
+ }
+
+ OSStatus GetVersion (UInt32 &outVersion) const;
+
+ const AudioComponent& Comp() const { return mComp; }
+
+ void Print(FILE* file = stdout) const;
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ AudioComponent mComp;
+ CAComponentDescription mDesc;
+
+ CFStringRef mManuName, mAUName, mCompName;
+
+ void SetCompNames () const;
+ void SetCompInfo () const;
+ void Clear ();
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.cpp
new file mode 100644
index 0000000000..a3c877b6fe
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.cpp
@@ -0,0 +1,110 @@
+/*
+ File: CAComponentDescription.cpp
+ Abstract: CAComponentDescription.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAComponentDescription.h"
+#include "CAStreamBasicDescription.h"
+#include <ctype.h>
+
+void CAShowComponentDescription(const AudioComponentDescription *desc)
+{
+ CAComponentDescription::_CAShowComponentDescription (desc, stdout);
+}
+
+void CAComponentDescription::_CAShowComponentDescription(const AudioComponentDescription *desc, FILE* file)
+{
+ if (desc)
+ {
+ char str[24];
+ fprintf (file, "AudioComponentDescription: %s - ", CAStringForOSType(desc->componentType, str, sizeof(str)));
+ fprintf (file, "%s - ", CAStringForOSType(desc->componentSubType, str, sizeof(str)));
+ fprintf (file, "%s", CAStringForOSType(desc->componentManufacturer, str, sizeof(str)));
+ fprintf (file, ", 0x%X, 0x%X\n", (int)desc->componentFlags, (int)desc->componentFlagsMask);
+ }
+}
+
+CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu)
+{
+ componentType = inType;
+ componentSubType = inSubtype;
+ componentManufacturer = inManu;
+ componentFlags = 0;
+ componentFlagsMask = 0;
+}
+
+bool CAComponentDescription::IsAU () const
+{
+ bool flag = IsEffect() || IsMusicDevice() || IsOffline();
+ if (flag) return true;
+
+ switch (componentType) {
+ case kAudioUnitType_Output:
+ case kAudioUnitType_FormatConverter:
+ case kAudioUnitType_Mixer:
+ return true;
+ }
+ return false;
+}
+
+inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB)
+{
+ return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB));
+}
+
+bool CAComponentDescription::Matches (const AudioComponentDescription &desc) const
+{
+ bool matches = false;
+
+ // see if the type matches
+ matches = _MatchTest (componentType, desc.componentType);
+
+ if (matches)
+ matches = _MatchTest (componentSubType, desc.componentSubType);
+
+ if (matches)
+ matches = _MatchTest (componentManufacturer, desc.componentManufacturer);
+
+ return matches;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.h b/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.h
new file mode 100644
index 0000000000..5c756eaebf
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAComponentDescription.h
@@ -0,0 +1,145 @@
+/*
+ File: CAComponentDescription.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAComponentDescription_h__
+#define __CAComponentDescription_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioUnit/AudioUnit.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <AudioUnit.h>
+#endif
+
+#include "CACFDictionary.h"
+#include <stdio.h>
+#include <string.h>
+
+void CAShowComponentDescription(const AudioComponentDescription *desc);
+
+// ____________________________________________________________________________
+//
+// CAComponentDescription
+class CAComponentDescription : public AudioComponentDescription {
+public:
+ CAComponentDescription() { memset (this, 0, sizeof (AudioComponentDescription)); }
+
+ CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
+
+ CAComponentDescription(const AudioComponentDescription& desc) { memcpy (this, &desc, sizeof (AudioComponentDescription)); }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // interrogation
+
+ bool IsAU () const;
+
+ bool IsAUFX() const { return componentType == kAudioUnitType_Effect; }
+ bool IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; }
+
+ bool IsAUMI() const { return componentType == 'aumi' /*kAudioUnitType_MIDIProcessor*/; }
+
+ bool IsAUAX () const { return componentType == 'auax' /*kAudioUnitType_Auxiliary*/; }
+
+ bool IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); }
+
+ bool IsOffline () const { return componentType == 'auol' /*kAudioUnitType_Offline*/; }
+
+ bool IsFConv () const { return componentType == kAudioUnitType_FormatConverter; }
+
+ bool IsPanner () const { return componentType == kAudioUnitType_Panner; }
+
+ bool IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; }
+
+#ifndef MAC_OS_X_VERSION_10_4
+ bool IsGenerator () const { return componentType =='augn'; }
+#else
+ bool IsGenerator () const { return componentType ==kAudioUnitType_Generator; }
+#endif
+
+ bool IsOutput () const { return componentType == kAudioUnitType_Output; }
+
+ bool IsSource () const { return IsMusicDevice() || IsGenerator(); }
+
+ OSType Type () const { return componentType; }
+ OSType SubType () const { return componentSubType; }
+ OSType Manu () const { return componentManufacturer; }
+
+ int Count() const { return AudioComponentCount(const_cast<CAComponentDescription*>(this)); }
+
+ // does a semantic match where "wild card" values for type, subtype, manu will match
+ bool Matches (const AudioComponentDescription &desc) const;
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // other
+
+ void Print(FILE* file = stdout) const { _CAShowComponentDescription (this, file); }
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ static void _CAShowComponentDescription (const AudioComponentDescription *desc, FILE* file);
+ friend void CAShowComponentDescription (const AudioComponentDescription *desc);
+};
+
+inline bool operator< (const AudioComponentDescription& x, const AudioComponentDescription& y)
+{
+ return memcmp (&x, &y, offsetof (AudioComponentDescription, componentFlags)) < 0;
+}
+
+inline bool operator== (const AudioComponentDescription& x, const AudioComponentDescription& y)
+{
+ return !memcmp (&x, &y, offsetof (AudioComponentDescription, componentFlags));
+}
+
+inline bool operator!= (const AudioComponentDescription& x, const AudioComponentDescription& y)
+{
+ return !(x == y);
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.cpp b/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.cpp
new file mode 100644
index 0000000000..9739e3753c
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.cpp
@@ -0,0 +1,90 @@
+/*
+ File: CADebugMacros.cpp
+ Abstract: CADebugMacros.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CADebugMacros.h"
+#include <stdio.h>
+#include <stdarg.h>
+#if TARGET_API_MAC_OSX
+ #include <syslog.h>
+#endif
+
+#if DEBUG
+#include <stdio.h>
+
+void DebugPrint(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
+#endif // DEBUG
+
+void LogError(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#if DEBUG
+ vprintf(fmt, args);
+#endif
+#if TARGET_API_MAC_OSX
+ vsyslog(LOG_ERR, fmt, args);
+#endif
+ va_end(args);
+}
+
+void LogWarning(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#if DEBUG
+ vprintf(fmt, args);
+#endif
+#if TARGET_API_MAC_OSX
+ vsyslog(LOG_WARNING, fmt, args);
+#endif
+ va_end(args);
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.h b/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.h
new file mode 100644
index 0000000000..15af91909f
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugMacros.h
@@ -0,0 +1,581 @@
+/*
+ File: CADebugMacros.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CADebugMacros_h__)
+#define __CADebugMacros_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+// CADebugMacros
+//=============================================================================
+
+//#define CoreAudio_StopOnFailure 1
+//#define CoreAudio_TimeStampMessages 1
+//#define CoreAudio_ThreadStampMessages 1
+//#define CoreAudio_FlushDebugMessages 1
+
+#if TARGET_RT_BIG_ENDIAN
+ #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
+ #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; }
+#else
+ #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 }
+ #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; }
+#endif
+
+// This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the
+// places where -wshorten64-32 catches assigning a sizeof expression to a UInt32.
+// For want of a better place to park this, we'll park it here.
+#define SizeOf32(X) ((UInt32)sizeof(X))
+
+// This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the
+// places where -wshorten64-32 catches assigning an offsetof expression to a UInt32.
+// For want of a better place to park this, we'll park it here.
+#define OffsetOf32(X, Y) ((UInt32)offsetof(X, Y))
+
+// This macro casts the expression to a UInt32. It is called out specially to allow us to track casts
+// that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms.
+// For want of a better place to park this, we'll park it here.
+#define ToUInt32(X) ((UInt32)(X))
+#define ToSInt32(X) ((SInt32)(X))
+
+#pragma mark Basic Definitions
+
+#if DEBUG || CoreAudio_Debug
+ // can be used to break into debugger immediately, also see CADebugger
+ #define BusError() { long* p=NULL; *p=0; }
+
+ // basic debugging print routines
+ #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
+ extern void DebugStr(const unsigned char* debuggerMsg);
+ #define DebugMessage(msg) DebugStr("\p"msg)
+ #define DebugMessageN1(msg, N1)
+ #define DebugMessageN2(msg, N1, N2)
+ #define DebugMessageN3(msg, N1, N2, N3)
+ #else
+ #include "CADebugPrintf.h"
+
+ #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
+ #define FlushRtn ,fflush(DebugPrintfFile)
+ #else
+ #define FlushRtn
+ #endif
+
+ #if CoreAudio_ThreadStampMessages
+ #include <pthread.h>
+ #include "CAHostTimeBase.h"
+ #if TARGET_RT_64_BIT
+ #define DebugPrintfThreadIDFormat "%16p"
+ #else
+ #define DebugPrintfThreadIDFormat "%8p"
+ #endif
+ #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " DebugPrintfThreadIDFormat " " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), pthread_self(), ## __VA_ARGS__) FlushRtn
+ #elif CoreAudio_TimeStampMessages
+ #include "CAHostTimeBase.h"
+ #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), ## __VA_ARGS__) FlushRtn
+ #else
+ #define DebugMsg(inFormat, ...) DebugPrintf(inFormat, ## __VA_ARGS__) FlushRtn
+ #endif
+ #endif
+ void DebugPrint(const char *fmt, ...); // can be used like printf
+ #ifndef DEBUGPRINT
+ #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h)
+ #endif
+ #if VERBOSE
+ #define vprint(msg) DEBUGPRINT(msg)
+ #else
+ #define vprint(msg)
+ #endif
+
+ // Original macro keeps its function of turning on and off use of CADebuggerStop() for both asserts and throws.
+ // For backwards compat, it overrides any setting of the two sub-macros.
+ #if CoreAudio_StopOnFailure
+ #include "CADebugger.h"
+ #undef CoreAudio_StopOnAssert
+ #define CoreAudio_StopOnAssert 1
+ #undef CoreAudio_StopOnThrow
+ #define CoreAudio_StopOnThrow 1
+ #define STOP CADebuggerStop()
+ #else
+ #define STOP
+ #endif
+
+ #if CoreAudio_StopOnAssert
+ #if !CoreAudio_StopOnFailure
+ #include "CADebugger.h"
+ #define STOP
+ #endif
+ #define __ASSERT_STOP CADebuggerStop()
+ #else
+ #define __ASSERT_STOP
+ #endif
+
+ #if CoreAudio_StopOnThrow
+ #if !CoreAudio_StopOnFailure
+ #include "CADebugger.h"
+ #define STOP
+ #endif
+ #define __THROW_STOP CADebuggerStop()
+ #else
+ #define __THROW_STOP
+ #endif
+
+#else
+ #define DebugMsg(inFormat, ...)
+ #ifndef DEBUGPRINT
+ #define DEBUGPRINT(msg)
+ #endif
+ #define vprint(msg)
+ #define STOP
+ #define __ASSERT_STOP
+ #define __THROW_STOP
+#endif
+
+// Old-style numbered DebugMessage calls are implemented in terms of DebugMsg() now
+#define DebugMessage(msg) DebugMsg(msg)
+#define DebugMessageN1(msg, N1) DebugMsg(msg, N1)
+#define DebugMessageN2(msg, N1, N2) DebugMsg(msg, N1, N2)
+#define DebugMessageN3(msg, N1, N2, N3) DebugMsg(msg, N1, N2, N3)
+#define DebugMessageN4(msg, N1, N2, N3, N4) DebugMsg(msg, N1, N2, N3, N4)
+#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugMsg(msg, N1, N2, N3, N4, N5)
+#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugMsg(msg, N1, N2, N3, N4, N5, N6)
+#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7)
+#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8)
+#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
+
+void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging)
+void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging)
+
+#define NO_ACTION (void)0
+
+#if DEBUG || CoreAudio_Debug
+
+#pragma mark Debug Macros
+
+#define Assert(inCondition, inMessage) \
+ if(!(inCondition)) \
+ { \
+ DebugMessage(inMessage); \
+ __ASSERT_STOP; \
+ }
+
+#define AssertFileLine(inCondition, inMessage) \
+ if(!(inCondition)) \
+ { \
+ DebugMessageN3("%s, line %d: %s", __FILE__, __LINE__, inMessage); \
+ __ASSERT_STOP; \
+ }
+
+#define AssertNoError(inError, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define AssertNoKernelError(inError, inMessage) \
+ { \
+ unsigned int __Err = (unsigned int)(inError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define AssertNotNULL(inPtr, inMessage) \
+ { \
+ if((inPtr) == NULL) \
+ { \
+ DebugMessage(inMessage); \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define FailIf(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \
+ { \
+ unsigned int __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#define FailIfError(inError, inAction, inHandler, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %ld (%s)", (long int)__Err, __4CC); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#define FailIfNoMessage(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \
+ { \
+ unsigned int __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#if defined(__cplusplus)
+
+#define Throw(inException) __THROW_STOP; throw (inException)
+
+#define ThrowIf(inCondition, inException, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ Throw(inException); \
+ }
+
+#define ThrowIfNULL(inPointer, inException, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ DebugMessage(inMessage); \
+ Throw(inException); \
+ }
+
+#define ThrowIfKernelError(inKernelError, inException, inMessage) \
+ { \
+ int __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ Throw(inException); \
+ } \
+ }
+
+#define ThrowIfError(inError, inException, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \
+ Throw(inException); \
+ } \
+ }
+
+#if TARGET_OS_WIN32
+#define ThrowIfWinError(inError, inException, inMessage) \
+ { \
+ HRESULT __Err = (inError); \
+ if(FAILED(__Err)) \
+ { \
+ DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \
+ Throw(inException); \
+ } \
+ }
+#endif
+
+#define SubclassResponsibility(inMethodName, inException) \
+ { \
+ DebugMessage(inMethodName": Subclasses must implement this method"); \
+ Throw(inException); \
+ }
+
+#endif // defined(__cplusplus)
+
+#else
+
+#pragma mark Release Macros
+
+#define Assert(inCondition, inMessage) \
+ if(!(inCondition)) \
+ { \
+ __ASSERT_STOP; \
+ }
+
+#define AssertFileLine(inCondition, inMessage) Assert(inCondition, inMessage)
+
+#define AssertNoError(inError, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define AssertNoKernelError(inError, inMessage) \
+ { \
+ unsigned int __Err = (unsigned int)(inError); \
+ if(__Err != 0) \
+ { \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define AssertNotNULL(inPtr, inMessage) \
+ { \
+ if((inPtr) == NULL) \
+ { \
+ __ASSERT_STOP; \
+ } \
+ }
+
+#define FailIf(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \
+ if((inKernelError) != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfError(inError, inAction, inHandler, inMessage) \
+ if((inError) != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNoMessage(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \
+ { \
+ unsigned int __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#if defined(__cplusplus)
+
+#define Throw(inException) __THROW_STOP; throw (inException)
+
+#define ThrowIf(inCondition, inException, inMessage) \
+ if(inCondition) \
+ { \
+ Throw(inException); \
+ }
+
+#define ThrowIfNULL(inPointer, inException, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ Throw(inException); \
+ }
+
+#define ThrowIfKernelError(inKernelError, inException, inMessage) \
+ { \
+ int __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ Throw(inException); \
+ } \
+ }
+
+#define ThrowIfError(inError, inException, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ Throw(inException); \
+ } \
+ }
+
+#if TARGET_OS_WIN32
+#define ThrowIfWinError(inError, inException, inMessage) \
+ { \
+ HRESULT __Err = (inError); \
+ if(FAILED(__Err)) \
+ { \
+ Throw(inException); \
+ } \
+ }
+#endif
+
+#define SubclassResponsibility(inMethodName, inException) \
+ { \
+ Throw(inException); \
+ }
+
+#endif // defined(__cplusplus)
+
+#endif // DEBUG || CoreAudio_Debug
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.cpp b/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.cpp
new file mode 100644
index 0000000000..d691de3cd5
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.cpp
@@ -0,0 +1,89 @@
+/*
+ File: CADebugPrintf.cpp
+ Abstract: CADebugPrintf.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CADebugPrintf.h"
+
+#if DEBUG || CoreAudio_Debug
+
+ #if TARGET_OS_WIN32
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <Windows.h>
+ extern "C"
+ int CAWin32DebugPrintf(char* inFormat, ...)
+ {
+ char theMessage[1024];
+ va_list theArguments;
+ va_start(theArguments, inFormat);
+ _vsnprintf(theMessage, 1024, inFormat, theArguments);
+ va_end(theArguments);
+ OutputDebugString(theMessage);
+ return 0;
+ }
+ #endif
+
+ #if defined(CoreAudio_UseSideFile)
+ #include <unistd.h>
+ FILE* sDebugPrintfSideFile = NULL;
+ extern "C"
+ void OpenDebugPrintfSideFile()
+ {
+ if(sDebugPrintfSideFile == NULL)
+ {
+ char theFileName[1024];
+ snprintf(theFileName, sizeof(theFileName), CoreAudio_UseSideFile, getpid());
+ sDebugPrintfSideFile = fopen(theFileName, "a+");
+ DebugPrintfRtn(DebugPrintfFileComma "\n------------------------------\n");
+ }
+ }
+ #endif
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.h b/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.h
new file mode 100644
index 0000000000..79aa15dafa
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugPrintf.h
@@ -0,0 +1,115 @@
+/*
+ File: CADebugPrintf.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CADebugPrintf_h__)
+#define __CADebugPrintf_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+// Macros to redirect debugging output to various logging services
+//=============================================================================
+
+//#define CoreAudio_UseSysLog 1
+//#define CoreAudio_UseSideFile "/CoreAudio-%d.txt"
+
+#if DEBUG || CoreAudio_Debug
+
+ #if TARGET_OS_WIN32
+ #if defined(__cplusplus)
+ extern "C"
+ #endif
+ extern int CAWin32DebugPrintf(char* inFormat, ...);
+ #define DebugPrintfRtn CAWin32DebugPrintf
+ #define DebugPrintfFile
+ #define DebugPrintfLineEnding "\n"
+ #define DebugPrintfFileComma
+ #else
+ #if CoreAudio_UseSysLog
+ #include <sys/syslog.h>
+ #define DebugPrintfRtn syslog
+ #define DebugPrintfFile LOG_NOTICE
+ #define DebugPrintfLineEnding ""
+ #define DebugPrintfFileComma DebugPrintfFile,
+ #elif defined(CoreAudio_UseSideFile)
+ #include <stdio.h>
+ #if defined(__cplusplus)
+ extern "C"
+ #endif
+ void OpenDebugPrintfSideFile();
+ extern FILE* sDebugPrintfSideFile;
+ #define DebugPrintfRtn fprintf
+ #define DebugPrintfFile ((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr)
+ #define DebugPrintfLineEnding "\n"
+ #define DebugPrintfFileComma DebugPrintfFile,
+ #else
+ #include <stdio.h>
+ #define DebugPrintfRtn fprintf
+ #define DebugPrintfFile stderr
+ #define DebugPrintfLineEnding "\n"
+ #define DebugPrintfFileComma DebugPrintfFile,
+ #endif
+ #endif
+
+ #define DebugPrintf(inFormat, ...) DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__)
+#else
+ #define DebugPrintfRtn
+ #define DebugPrintfFile
+ #define DebugPrintfLineEnding
+ #define DebugPrintfFileComma
+ #define DebugPrintf(inFormat, ...)
+#endif
+
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugger.cpp b/libs/appleutility/CoreAudio/PublicUtility/CADebugger.cpp
new file mode 100644
index 0000000000..7f0141d206
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugger.cpp
@@ -0,0 +1,103 @@
+/*
+ File: CADebugger.cpp
+ Abstract: CADebugger.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CADebugger.h"
+
+//=============================================================================
+// CADebugger
+//=============================================================================
+
+#if TARGET_API_MAC_OSX
+
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+bool CAIsDebuggerAttached(void)
+{
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+ size = sizeof(info);
+ info.kp_proc.p_flag = 0;
+
+ sysctl(mib, 4, &info, &size, NULL, 0);
+
+ return (info.kp_proc.p_flag & P_TRACED) == P_TRACED;
+}
+
+#endif
+
+void CADebuggerStop(void)
+{
+ #if CoreAudio_Debug
+ #if TARGET_API_MAC_OSX
+ if(CAIsDebuggerAttached())
+ {
+ #if defined(__i386__) || defined(__x86_64__)
+ asm("int3");
+ #else
+ __builtin_trap();
+ #endif
+ }
+ else
+ {
+ abort();
+ }
+ #else
+ __debugbreak();
+ #endif
+ #endif
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CADebugger.h b/libs/appleutility/CoreAudio/PublicUtility/CADebugger.h
new file mode 100644
index 0000000000..9391f011a2
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CADebugger.h
@@ -0,0 +1,69 @@
+/*
+ File: CADebugger.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CADebugger_h__)
+#define __CADebugger_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+//=============================================================================
+// CADebugger
+//=============================================================================
+
+#if TARGET_API_MAC_OSX
+ extern bool CAIsDebuggerAttached(void);
+#endif
+extern void CADebuggerStop(void);
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAException.h b/libs/appleutility/CoreAudio/PublicUtility/CAException.h
new file mode 100644
index 0000000000..7217001d78
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAException.h
@@ -0,0 +1,83 @@
+/*
+ File: CAException.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAException_h__)
+#define __CAException_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include "CoreAudioTypes.h"
+#endif
+
+//=============================================================================
+// CAException
+//=============================================================================
+
+class CAException
+{
+
+public:
+ CAException(OSStatus inError) : mError(inError) {}
+ CAException(const CAException& inException) : mError(inException.mError) {}
+ CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; }
+ ~CAException() {}
+
+ OSStatus GetError() const { return mError; }
+
+protected:
+ OSStatus mError;
+};
+
+#define CATry try{
+#define CACatch } catch(...) {}
+#define CASwallowException(inExpression) try { inExpression; } catch(...) {}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAExtAudioFile.h b/libs/appleutility/CoreAudio/PublicUtility/CAExtAudioFile.h
new file mode 100644
index 0000000000..f1aa56fb5e
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAExtAudioFile.h
@@ -0,0 +1,300 @@
+/*
+ File: CAExtAudioFile.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAExtAudioFile_h__
+#define __CAExtAudioFile_h__
+
+#include <TargetConditionals.h>
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioToolbox/ExtendedAudioFile.h>
+ #include <AudioToolbox/AudioConverter.h>
+#else
+ #include "ExtendedAudioFile.h"
+ #include "AudioConverter.h"
+#endif
+#include "CAXException.h"
+//#include "CAAutoDisposer.h"
+#include "CAStreamBasicDescription.h"
+#include "CAAudioChannelLayout.h"
+#include "CACFObject.h"
+
+// A C++ wrapper for ExtAudioFile
+// Error returns throw CAXExceptions.
+class CAExtAudioFile {
+public:
+ // instances are not automatically associated with open files.
+ CAExtAudioFile() :
+ mExtAudioFile(NULL) { }
+
+ virtual ~CAExtAudioFile()
+ {
+ Close();
+ }
+
+ bool IsValid() const { return mExtAudioFile != NULL; }
+
+ void Open(const char* filename)
+ {
+ Close();
+ CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)filename, strlen(filename), false);
+ XThrowIf(!url, -1, "couldn't convert path to CFURLRef");
+ OSStatus res = ExtAudioFileOpenURL(url, &mExtAudioFile);
+ if (res)
+ CFRelease(url);
+ Check(res, "ExtAudioFileOpenURL");
+ CFRelease (url);
+ }
+
+ // this group of methods maps directly to the API other than OSStatus results translating into exceptions.
+ // you must explicitly open, wrap or create a file.
+ void OpenURL(CFURLRef url)
+ {
+ Close();
+ Check(ExtAudioFileOpenURL(url, &mExtAudioFile), "ExtAudioFileOpenURL");
+ }
+
+ void WrapAudioFileID(AudioFileID inFileID, Boolean forWriting)
+ {
+ Close();
+ Check(ExtAudioFileWrapAudioFileID(inFileID, forWriting, &mExtAudioFile), "ExtAudioFileWrapAudioFileID");
+ }
+
+ void Create(const char *filePath, AudioFileTypeID filetype, const AudioStreamBasicDescription &streamDesc, const AudioChannelLayout *channelLayout, UInt32 flags)
+ {
+ CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)filePath, strlen(filePath), false);
+ XThrowIf(!url, -1, "couldn't convert path to CFURLRef");
+ Close();
+ OSStatus res = ExtAudioFileCreateWithURL(url, filetype, &streamDesc, channelLayout, flags, &mExtAudioFile);
+ if (res)
+ CFRelease(url);
+ Check(res, "ExtAudioFileCreateWithURL");
+ CFRelease(url);
+ }
+
+ void CreateWithURL(CFURLRef url, AudioFileTypeID filetype, const AudioStreamBasicDescription &streamDesc, const AudioChannelLayout *channelLayout, UInt32 flags)
+ {
+ Close();
+ Check(ExtAudioFileCreateWithURL(url, filetype, &streamDesc, channelLayout, flags, &mExtAudioFile), "ExtAudioFileCreateWithURL");
+ }
+
+ // you may explicitly close a file, or have it closed automatically by the destructor.
+ void Close()
+ {
+ if (mExtAudioFile != NULL) {
+ Check(ExtAudioFileDispose(mExtAudioFile), "ExtAudioFileClose");
+ mExtAudioFile = NULL;
+ }
+ }
+
+ void Read(UInt32 &ioNumberFrames, AudioBufferList *ioData)
+ {
+ Check(ExtAudioFileRead(mExtAudioFile, &ioNumberFrames, ioData), "ExtAudioFileRead");
+ }
+
+ OSStatus Write(UInt32 inNumberFrames, const AudioBufferList *ioData)
+ {
+ OSStatus err = ExtAudioFileWrite(mExtAudioFile, inNumberFrames, ioData);
+ switch (err) {
+ // noErr and certain special errors are returned without an exception
+ case noErr:
+ break;
+ #if TARGET_OS_IPHONE
+ case kExtAudioFileError_CodecUnavailableInputConsumed:
+ case kExtAudioFileError_CodecUnavailableInputNotConsumed:
+ break;
+ #endif
+ default:
+ // throw an exception
+ Check(err, "ExtAudioFileWrite");
+ break;
+ }
+ return err;
+ }
+
+ void WriteAsync(UInt32 inNumberFrames, const AudioBufferList *ioData)
+ {
+ Check(ExtAudioFileWriteAsync(mExtAudioFile, inNumberFrames, ioData), "ExtAudioFileWriteAsync");
+ }
+
+ void Seek(SInt64 inFrameOffset)
+ {
+ Check(ExtAudioFileSeek(mExtAudioFile, inFrameOffset), "ExtAudioFileSeek");
+ }
+
+ SInt64 Tell() const
+ {
+ SInt64 pos;
+ Check(ExtAudioFileTell(mExtAudioFile, &pos), "ExtAudioFileTell");
+ return pos;
+ }
+
+ UInt32 GetPropertyInfo(ExtAudioFilePropertyID propid, Boolean *outWritable) const
+ {
+ UInt32 size;
+ CheckProperty(ExtAudioFileGetPropertyInfo(mExtAudioFile, propid, &size, outWritable), "ExtAudioFileGetPropertyInfo", propid);
+ return size;
+ }
+
+ void GetProperty(ExtAudioFilePropertyID propid, UInt32 &ioSize, void *outData) const
+ {
+ CheckProperty(ExtAudioFileGetProperty(mExtAudioFile, propid, &ioSize, outData), "ExtAudioFileGetProperty", propid);
+ }
+
+ void SetProperty(ExtAudioFilePropertyID propid, UInt32 size, const void *inData)
+ {
+ CheckProperty(ExtAudioFileSetProperty(mExtAudioFile, propid, size, inData), "ExtAudioFileSetProperty", propid);
+ }
+
+ const CAAudioChannelLayout &GetFileChannelLayout()
+ {
+ return FetchChannelLayout(mFileChannelLayout, kExtAudioFileProperty_FileChannelLayout);
+ }
+
+ void SetFileChannelLayout(const CAAudioChannelLayout &layout) {
+ SetProperty(kExtAudioFileProperty_FileChannelLayout, layout.Size(), &layout.Layout());
+ }
+
+ const CAStreamBasicDescription &GetFileDataFormat()
+ {
+ UInt32 size = sizeof(mFileDataFormat);
+ GetProperty(kExtAudioFileProperty_FileDataFormat, size, &mFileDataFormat);
+ return mFileDataFormat;
+ }
+
+ const CAStreamBasicDescription &GetClientDataFormat() {
+ UInt32 size = sizeof(mClientDataFormat);
+ GetProperty(kExtAudioFileProperty_ClientDataFormat, size, &mClientDataFormat);
+ return mClientDataFormat;
+ }
+
+
+ void SetClientFormat(const CAStreamBasicDescription &dataFormat, const CAAudioChannelLayout *layout=NULL, UInt32 codecManuf=0) {
+ if (codecManuf != 0)
+ SetProperty('cman' /*kExtAudioFileProperty_CodecManufacturer*/, sizeof(codecManuf), &codecManuf);
+ SetProperty(kExtAudioFileProperty_ClientDataFormat, sizeof(dataFormat), &dataFormat);
+ if (layout)
+ SetClientChannelLayout(*layout);
+ }
+
+ void SetClientChannelLayout(const CAAudioChannelLayout &layout) {
+ SetProperty(kExtAudioFileProperty_ClientChannelLayout, layout.Size(), &layout.Layout());
+ }
+
+ AudioConverterRef GetConverter() const {
+ UInt32 size = sizeof(AudioConverterRef);
+ AudioConverterRef converter = NULL;
+ GetProperty(kExtAudioFileProperty_AudioConverter, size, &converter);
+ return converter;
+ }
+
+ bool HasConverter() const { return GetConverter() != NULL; }
+
+ OSStatus SetConverterProperty(AudioConverterPropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, bool inCanFail=false)
+ {
+ OSStatus err = AudioConverterSetProperty(GetConverter(), inPropertyID, inPropertyDataSize, inPropertyData);
+ if (!inCanFail)
+ XThrowIfError(err, "Couldn't set audio converter property");
+ if (!err) {
+ // must tell the file that we have changed the converter; a NULL converter config is sufficient
+ CFPropertyListRef config = NULL;
+ SetProperty(kExtAudioFileProperty_ConverterConfig, sizeof(CFPropertyListRef), &config);
+ }
+ return err;
+ }
+
+ SInt64 GetNumberFrames() {
+ SInt64 length;
+ UInt32 size = sizeof(SInt64);
+ GetProperty(kExtAudioFileProperty_FileLengthFrames, size, &length);
+ return length;
+ }
+
+
+protected:
+ virtual void Check(OSStatus err, const char *func) const
+ {
+ if (err) {
+ char txt[128];
+ snprintf(txt, sizeof(txt), "%s failed", func);
+ throw CAXException(txt, err);
+ }
+ }
+
+ virtual void CheckProperty(OSStatus err, const char *func, UInt32 propid) const
+ {
+ if (err) {
+ char txt[128];
+ char propstr[] = CA4CCToCString(propid);
+ snprintf(txt, sizeof(txt), "%s ('%s') failed", func, propstr);
+ throw CAXException(txt, err);
+ }
+ }
+
+ const CAAudioChannelLayout & FetchChannelLayout(CAAudioChannelLayout &layoutObj, ExtAudioFilePropertyID propID) {
+ UInt32 size = GetPropertyInfo(propID, NULL);
+ CAAutoFree<AudioChannelLayout> layout;
+ layout.allocBytes(size);
+ GetProperty(propID, size, layout);
+ layoutObj = layout;
+ return layoutObj;
+ }
+
+private:
+ CAExtAudioFile(const CAExtAudioFile &) { } // prohibit
+ CAExtAudioFile & operator = (const CAExtAudioFile &) { return *this; } // prohibit
+
+private:
+ ExtAudioFileRef mExtAudioFile;
+
+ // for convenience to the client, it helps if we hold onto some storage for these
+ CAStreamBasicDescription mFileDataFormat;
+ CAAudioChannelLayout mFileChannelLayout;
+ CAStreamBasicDescription mClientDataFormat;
+};
+
+
+#endif // __CAExtAudioFile_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.cpp
new file mode 100644
index 0000000000..124cb21433
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.cpp
@@ -0,0 +1,188 @@
+/*
+ File: CAFilePathUtils.cpp
+ Abstract: CAFilePathUtils.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAFilePathUtils.h"
+#include <string.h>
+
+#if !CA_NO_CORE_SERVICES
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h> // FSRef
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreServices.h>
+ #include <CoreAudioTypes.h>
+#endif
+
+OSStatus PosixPathToParentFSRefAndName(const char *path, FSRef &outParentDir, CFStringRef &outFileName)
+{
+ // convert C string to CFString
+#if !TARGET_OS_WIN32
+ CFStringRef cfFullPath = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
+#else
+ CFStringRef cfFullPath = CFStringCreateWithCString(NULL, path, kCFStringEncodingWindowsLatin1);
+#endif
+ // convert CF string to URL
+ CFURLRef fullurl = CFURLCreateWithFileSystemPath(NULL, cfFullPath, TARGET_OS_WIN32 ? kCFURLWindowsPathStyle : kCFURLPOSIXPathStyle, false);
+ CFRelease(cfFullPath);
+ // get the directory portion of the URL
+ CFURLRef dirurl = CFURLCreateCopyDeletingLastPathComponent(NULL, fullurl);
+ // get the directory's FSRef
+ OSStatus err = CFURLGetFSRef(dirurl, &outParentDir) ? OSStatus(noErr) : OSStatus(kAudio_FileNotFoundError);
+ CFRelease(dirurl);
+
+ CFStringRef lastPathComponent = CFURLCopyLastPathComponent(fullurl);
+ CFRelease(fullurl);
+ CFMutableStringRef filename = CFStringCreateMutableCopy(NULL, 0, lastPathComponent);
+ CFRelease(lastPathComponent);
+ // convert colons (legal in POSIX paths, illegal in File Manager) to slashes
+ CFStringFindAndReplace(filename, CFSTR(":"), CFSTR("/"), CFRangeMake(0, CFStringGetLength(filename)), 0);
+
+ outFileName = filename;
+
+ return err;
+}
+#endif // !CA_NO_CORE_SERVICES
+
+
+#if TARGET_OS_WIN32
+
+char* dirname(const char* inPath)
+{
+ static char sAnswer[1024];
+
+ char* theAnswer = NULL;
+ SInt32 thePathLength = strlen(inPath);
+ if(thePathLength < 1023)
+ {
+ // make a working copy
+ strlcpy(sAnswer, inPath, sizeof(sAnswer));
+
+ // start at the end of the string
+ SInt32 theIndex = thePathLength - 1;
+
+ // walk back over the '\' characters
+ while((theIndex > 0) && (sAnswer[theIndex] == '\\'))
+ {
+ --theIndex;
+ }
+
+ // now keep walking back until we get to a '\'
+ while((theIndex > 0) && (sAnswer[theIndex] != '\\'))
+ {
+ --theIndex;
+ }
+
+ // where we are now is either the first character of the path or the '\' that marks the end of the directory name
+ if(theIndex > 0)
+ {
+ // we have a name so put a '\0' in place of the '\'
+ sAnswer[theIndex] = 0;
+ }
+ else
+ {
+ // no name, so the answer is "."
+ sAnswer[0] = '.';
+ sAnswer[1] = 0;
+ }
+
+ // set the return value
+ theAnswer = sAnswer;
+ }
+
+ return theAnswer;
+}
+
+char* basename(const char* inPath)
+{
+ static char sAnswer[1024];
+
+ char* theAnswer = NULL;
+ SInt32 thePathLength = strlen(inPath);
+ if(thePathLength < 1023)
+ {
+ // make a working copy
+ strlcpy(sAnswer, inPath, sizeof(sAnswer));
+
+ // start at the end of the string
+ SInt32 theLastIndex = thePathLength - 1;
+
+ // walk back over the '\' characters
+ while((theLastIndex > 0) && (sAnswer[theLastIndex] == '\\'))
+ {
+ --theLastIndex;
+ }
+
+ // check to see if we're at the beginning now
+ if(theLastIndex > 0)
+ {
+ // there's a name in there now, so start where we are and go back to the next '\'
+ UInt32 theFirstIndex = theLastIndex;
+ while((theFirstIndex > 0) && (sAnswer[theFirstIndex] != '\\'))
+ {
+ --theFirstIndex;
+ }
+
+ // we now have a string, so put a '\0' after the last character
+ sAnswer[theLastIndex + 1] = 0;
+
+ // and set the return value
+ theAnswer = &sAnswer[theFirstIndex];
+ }
+ else
+ {
+ // the path was entirely '\' characters, so the return value is "\"
+ sAnswer[0] = '\\';
+ sAnswer[1] = 0;
+
+ // set the return value
+ theAnswer = sAnswer;
+ }
+ }
+
+ return theAnswer;
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.h b/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.h
new file mode 100644
index 0000000000..41f1ee00af
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAFilePathUtils.h
@@ -0,0 +1,70 @@
+/*
+ File: CAFilePathUtils.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAFilePathUtils_h__
+#define __CAFilePathUtils_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+ #include <CoreAudio/CoreAudio.h>
+#else
+ #include <TargetConditionals.h>
+ #include <CoreFoundation.h>
+ #include <CoreAudio.h>
+#endif
+
+struct FSRef;
+
+OSStatus PosixPathToParentFSRefAndName(const char *path, FSRef &outParentDir, CFStringRef &outFileName);
+
+#if !TARGET_OS_WIN32
+ #include <libgen.h>
+#else
+ char* dirname(const char* inPath);
+ char* basename(const char* inPath);
+#endif
+
+#endif // __CAFilePathUtils_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAGuard.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAGuard.cpp
new file mode 100644
index 0000000000..a1c83be9dd
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAGuard.cpp
@@ -0,0 +1,343 @@
+/*
+ File: CAGuard.cpp
+ Abstract: CAGuard.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAGuard.h"
+
+#if TARGET_OS_MAC
+ #include <errno.h>
+#endif
+
+// PublicUtility Inludes
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAHostTimeBase.h"
+
+//==================================================================================================
+// Logging
+//==================================================================================================
+
+#if CoreAudio_Debug
+// #define Log_Ownership 1
+// #define Log_WaitOwnership 1
+// #define Log_TimedWaits 1
+// #define Log_Latency 1
+// #define Log_Errors 1
+#endif
+
+//#warning Need a try-based Locker too
+//==================================================================================================
+// CAGuard
+//==================================================================================================
+
+CAGuard::CAGuard(const char* inName)
+:
+ CAMutex(inName)
+#if Log_Average_Latency
+ ,mAverageLatencyAccumulator(0.0),
+ mAverageLatencyCount(0)
+#endif
+{
+#if TARGET_OS_MAC
+ OSStatus theError = pthread_cond_init(&mCondVar, NULL);
+ ThrowIf(theError != 0, CAException(theError), "CAGuard::CAGuard: Could not init the cond var");
+#elif TARGET_OS_WIN32
+ mEvent = CreateEvent(NULL, true, false, NULL);
+ ThrowIfNULL(mEvent, CAException(GetLastError()), "CAGuard::CAGuard: Could not create the event");
+#endif
+}
+
+CAGuard::~CAGuard()
+{
+#if TARGET_OS_MAC
+ pthread_cond_destroy(&mCondVar);
+#elif TARGET_OS_WIN32
+ if(mEvent != NULL)
+ {
+ CloseHandle(mEvent);
+ }
+#endif
+}
+
+void CAGuard::Wait()
+{
+#if TARGET_OS_MAC
+ ThrowIf(!pthread_equal(pthread_self(), mOwner), CAException(1), "CAGuard::Wait: A thread has to have locked a guard before it can wait");
+
+ mOwner = 0;
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Wait: thread %p is waiting on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ OSStatus theError = pthread_cond_wait(&mCondVar, &mMutex);
+ ThrowIf(theError != 0, CAException(theError), "CAGuard::Wait: Could not wait for a signal");
+ mOwner = pthread_self();
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Wait: thread %p waited on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+#elif TARGET_OS_WIN32
+ ThrowIf(GetCurrentThreadId() != mOwner, CAException(1), "CAGuard::Wait: A thread has to have locked a guard before it can wait");
+
+ mOwner = 0;
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Wait: thread %lu is waiting on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ ReleaseMutex(mMutex);
+ HANDLE theHandles[] = { mMutex, mEvent };
+ OSStatus theError = WaitForMultipleObjects(2, theHandles, true, INFINITE);
+ ThrowIfError(theError, CAException(GetLastError()), "CAGuard::Wait: Could not wait for the signal");
+ mOwner = GetCurrentThreadId();
+ ResetEvent(mEvent);
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Wait: thread %lu waited on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+#endif
+}
+
+bool CAGuard::WaitFor(UInt64 inNanos)
+{
+ bool theAnswer = false;
+
+#if TARGET_OS_MAC
+ ThrowIf(!pthread_equal(pthread_self(), mOwner), CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");
+
+ #if Log_TimedWaits
+ DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
+ #endif
+
+ struct timespec theTimeSpec;
+ static const UInt64 kNanosPerSecond = 1000000000ULL;
+ if(inNanos >= kNanosPerSecond)
+ {
+ theTimeSpec.tv_sec = static_cast<long>(inNanos / kNanosPerSecond);
+ theTimeSpec.tv_nsec = static_cast<long>(inNanos % kNanosPerSecond);
+ }
+ else
+ {
+ theTimeSpec.tv_sec = 0;
+ theTimeSpec.tv_nsec = static_cast<long>(inNanos);
+ }
+
+ #if Log_TimedWaits || Log_Latency || Log_Average_Latency
+ UInt64 theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+ #endif
+
+ mOwner = 0;
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p is waiting on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ OSStatus theError = pthread_cond_timedwait_relative_np(&mCondVar, &mMutex, &theTimeSpec);
+ ThrowIf((theError != 0) && (theError != ETIMEDOUT), CAException(theError), "CAGuard::WaitFor: Wait got an error");
+ mOwner = pthread_self();
+
+ #if Log_TimedWaits || Log_Latency || Log_Average_Latency
+ UInt64 theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+ #endif
+
+ #if Log_TimedWaits
+ DebugMessageN1("CAGuard::WaitFor: waited %.0f", (Float64)(theEndNanos - theStartNanos));
+ #endif
+
+ #if Log_Latency
+ DebugMessageN1("CAGuard::WaitFor: latency %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
+ #endif
+
+ #if Log_Average_Latency
+ ++mAverageLatencyCount;
+ mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
+ if(mAverageLatencyCount >= 50)
+ {
+ DebugMessageN2("CAGuard::WaitFor: average latency %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
+ mAverageLatencyCount = 0;
+ mAverageLatencyAccumulator = 0.0;
+ }
+ #endif
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::WaitFor: thread %p waited on %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ theAnswer = theError == ETIMEDOUT;
+#elif TARGET_OS_WIN32
+ ThrowIf(GetCurrentThreadId() != mOwner, CAException(1), "CAGuard::WaitFor: A thread has to have locked a guard be for it can wait");
+
+ #if Log_TimedWaits
+ DebugMessageN1("CAGuard::WaitFor: waiting %.0f", (Float64)inNanos);
+ #endif
+
+ // the time out is specified in milliseconds(!)
+ UInt32 theWaitTime = static_cast<UInt32>(inNanos / 1000000ULL);
+
+ #if Log_TimedWaits || Log_Latency || Log_Average_Latency
+ UInt64 theStartNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+ #endif
+
+ mOwner = 0;
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu is waiting on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ ReleaseMutex(mMutex);
+ HANDLE theHandles[] = { mMutex, mEvent };
+ OSStatus theError = WaitForMultipleObjects(2, theHandles, true, theWaitTime);
+ ThrowIf((theError != WAIT_OBJECT_0) && (theError != WAIT_TIMEOUT), CAException(GetLastError()), "CAGuard::WaitFor: Wait got an error");
+ mOwner = GetCurrentThreadId();
+ ResetEvent(mEvent);
+ // This mutex should be locked again when time out happens.rdar://12270555
+ if(theError == WAIT_TIMEOUT) {
+ DWORD dwError = WaitForSingleObject(mMutex, INFINITE);
+ ThrowIf((dwError != WAIT_OBJECT_0), CAException(GetLastError()), "CAGuard::WaitFor: failed to acquire the mutex back when timeout happened\n");
+ }
+ #if Log_TimedWaits || Log_Latency || Log_Average_Latency
+ UInt64 theEndNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+ #endif
+
+ #if Log_TimedWaits
+ DebugMessageN1("CAGuard::WaitFor: waited %.0f", (Float64)(theEndNanos - theStartNanos));
+ #endif
+
+ #if Log_Latency
+ DebugMessageN1("CAGuard::WaitFor: latency %.0f", (Float64)((theEndNanos - theStartNanos) - inNanos));
+ #endif
+
+ #if Log_Average_Latency
+ ++mAverageLatencyCount;
+ mAverageLatencyAccumulator += (theEndNanos - theStartNanos) - inNanos;
+ if(mAverageLatencyCount >= 50)
+ {
+ DebugMessageN2("CAGuard::WaitFor: average latency %.3f ns over %ld waits", mAverageLatencyAccumulator / mAverageLatencyCount, mAverageLatencyCount);
+ mAverageLatencyCount = 0;
+ mAverageLatencyAccumulator = 0.0;
+ }
+ #endif
+
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::WaitFor: thread %lu waited on %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ theAnswer = theError == WAIT_TIMEOUT;
+#endif
+
+ return theAnswer;
+}
+
+bool CAGuard::WaitUntil(UInt64 inNanos)
+{
+ bool theAnswer = false;
+ UInt64 theCurrentNanos = CAHostTimeBase::GetCurrentTimeInNanos();
+
+#if Log_TimedWaits
+ DebugMessageN2("CAGuard::WaitUntil: now: %.0f, requested: %.0f", (double)theCurrentNanos, (double)inNanos);
+#endif
+
+ if(inNanos > theCurrentNanos)
+ {
+#if Log_Errors
+ if((inNanos - theCurrentNanos) > 1000000000ULL)
+ {
+ DebugMessage("CAGuard::WaitUntil: about to wait for more than a second");
+ }
+#endif
+ theAnswer = WaitFor(inNanos - theCurrentNanos);
+ }
+ else
+ {
+#if Log_Errors
+ DebugMessageN2("CAGuard::WaitUntil: Time has expired before waiting, now: %.0f, requested: %.0f", (double)theCurrentNanos, (double)inNanos);
+#endif
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
+
+void CAGuard::Notify()
+{
+#if TARGET_OS_MAC
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::Notify: thread %p is notifying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ OSStatus theError = pthread_cond_signal(&mCondVar);
+ ThrowIf(theError != 0, CAException(theError), "CAGuard::Notify: failed");
+#elif TARGET_OS_WIN32
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::Notify: thread %lu is notifying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ SetEvent(mEvent);
+#endif
+}
+
+void CAGuard::NotifyAll()
+{
+#if TARGET_OS_MAC
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAGuard::NotifyAll: thread %p is notifying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ OSStatus theError = pthread_cond_broadcast(&mCondVar);
+ ThrowIf(theError != 0, CAException(theError), "CAGuard::NotifyAll: failed");
+#elif TARGET_OS_WIN32
+ #if Log_WaitOwnership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAGuard::NotifyAll: thread %lu is notifying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ SetEvent(mEvent);
+#endif
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAGuard.h b/libs/appleutility/CoreAudio/PublicUtility/CAGuard.h
new file mode 100644
index 0000000000..ffcb59da8d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAGuard.h
@@ -0,0 +1,133 @@
+/*
+ File: CAGuard.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAGuard_h__)
+#define __CAGuard_h__
+
+//==================================================================================================
+// Includes
+//=============================================================================
+
+// Super Class Includes
+#include "CAMutex.h"
+
+#if CoreAudio_Debug
+// #define Log_Average_Latency 1
+#endif
+
+//==================================================================================================
+// CAGuard
+//
+// This is your typical mutex with signalling implemented via pthreads.
+// Lock() will return true if and only if the guard is locked on that call.
+// A thread that already has the guard will receive 'false' if it locks it
+// again. Use of the stack-based CAGuard::Locker class is highly recommended
+// to properly manage the recursive nesting. The Wait calls with timeouts
+// will return true if and only if the timeout period expired. They will
+// return false if they receive notification any other way.
+//==================================================================================================
+
+class CAGuard : public CAMutex
+{
+
+// Construction/Destruction
+public:
+ CAGuard(const char* inName);
+ virtual ~CAGuard();
+
+// Actions
+public:
+ virtual void Wait();
+ virtual bool WaitFor(UInt64 inNanos);
+ virtual bool WaitUntil(UInt64 inNanos);
+
+ virtual void Notify();
+ virtual void NotifyAll();
+
+// Implementation
+protected:
+#if TARGET_OS_MAC
+ pthread_cond_t mCondVar;
+#else
+ HANDLE mEvent;
+#endif
+#if Log_Average_Latency
+ Float64 mAverageLatencyAccumulator;
+ UInt32 mAverageLatencyCount;
+#endif
+
+// Helper class to manage taking and releasing recursively
+public:
+ class Locker
+ {
+
+ // Construction/Destruction
+ public:
+ Locker(CAGuard& inGuard) : mGuard(inGuard), mNeedsRelease(false) { mNeedsRelease = mGuard.Lock(); }
+ ~Locker() { if(mNeedsRelease) { mGuard.Unlock(); } }
+
+ private:
+ Locker(const Locker&);
+ Locker& operator=(const Locker&);
+
+ // Actions
+ public:
+ void Wait() { mGuard.Wait(); }
+ bool WaitFor(UInt64 inNanos) { return mGuard.WaitFor(inNanos); }
+ bool WaitUntil(UInt64 inNanos) { return mGuard.WaitUntil(inNanos); }
+
+ void Notify() { mGuard.Notify(); }
+ void NotifyAll() { mGuard.NotifyAll(); }
+
+ // Implementation
+ private:
+ CAGuard& mGuard;
+ bool mNeedsRelease;
+ };
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.cpp
new file mode 100644
index 0000000000..9bce34626a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.cpp
@@ -0,0 +1,1156 @@
+/*
+ File: CAHALAudioDevice.cpp
+ Abstract: CAHALAudioDevice.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAHALAudioDevice.h"
+
+// PublicUtility Includes
+#include "CAAutoDisposer.h"
+#include "CAHALAudioStream.h"
+#include "CAHALAudioSystemObject.h"
+#include "CAPropertyAddress.h"
+
+//==================================================================================================
+// CAHALAudioDevice
+//==================================================================================================
+
+CAHALAudioDevice::CAHALAudioDevice(AudioObjectID inAudioDevice)
+:
+ CAHALAudioObject(inAudioDevice)
+{
+}
+
+CAHALAudioDevice::CAHALAudioDevice(CFStringRef inUID)
+:
+ CAHALAudioObject(CAHALAudioSystemObject().GetAudioDeviceForUID(inUID))
+{
+}
+
+CAHALAudioDevice::~CAHALAudioDevice()
+{
+}
+
+CFStringRef CAHALAudioDevice::CopyDeviceUID() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDeviceUID);
+ return GetPropertyData_CFString(theAddress, 0, NULL);
+}
+
+bool CAHALAudioDevice::HasModelUID() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyModelUID);
+ return HasProperty(theAddress);
+}
+
+CFStringRef CAHALAudioDevice::CopyModelUID() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyModelUID);
+ return GetPropertyData_CFString(theAddress, 0, NULL);
+}
+
+CFStringRef CAHALAudioDevice::CopyConfigurationApplicationBundleID() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyConfigurationApplication);
+ return GetPropertyData_CFString(theAddress, 0, NULL);
+}
+
+CFURLRef CAHALAudioDevice::CopyIconLocation() const
+{
+ CFURLRef theAnswer = NULL;
+ CAPropertyAddress theAddress(kAudioDevicePropertyIcon);
+ UInt32 theSize = sizeof(CFURLRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+UInt32 CAHALAudioDevice::GetTransportType() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyTransportType);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+bool CAHALAudioDevice::CanBeDefaultDevice(bool inIsInput, bool inIsSystem) const
+{
+ CAPropertyAddress theAddress(inIsSystem ? kAudioDevicePropertyDeviceCanBeDefaultSystemDevice : kAudioDevicePropertyDeviceCanBeDefaultDevice, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
+}
+
+bool CAHALAudioDevice::HasDevicePlugInStatus() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlugIn);
+ return HasProperty(theAddress);
+}
+
+OSStatus CAHALAudioDevice::GetDevicePlugInStatus() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlugIn);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+bool CAHALAudioDevice::IsAlive() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsAlive);
+ return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
+}
+
+bool CAHALAudioDevice::IsHidden() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyIsHidden);
+ return GetPropertyData_UInt32(theAddress, 0, NULL) != 0;
+}
+
+pid_t CAHALAudioDevice::GetHogModeOwner() const
+{
+ pid_t theAnswer = -1;
+ CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = sizeof(pid_t);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+ return theAnswer;
+}
+
+bool CAHALAudioDevice::IsHogModeSettable() const
+{
+ bool theAnswer = false;
+ CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
+ if(HasProperty(theAddress))
+ {
+ theAnswer = IsPropertySettable(theAddress);
+ }
+ return theAnswer;
+}
+
+bool CAHALAudioDevice::TakeHogMode()
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
+ pid_t thePID = getpid();
+ if(HasProperty(theAddress))
+ {
+ SetPropertyData(theAddress, 0, NULL, sizeof(pid_t), &thePID);
+ }
+ return thePID == getpid();
+}
+
+void CAHALAudioDevice::ReleaseHogMode()
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyHogMode);
+ if(HasProperty(theAddress))
+ {
+ pid_t thePID = -1;
+ SetPropertyData(theAddress, 0, NULL, sizeof(pid_t), &thePID);
+ }
+}
+
+bool CAHALAudioDevice::HasPreferredStereoChannels(bool inIsInput) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ return HasProperty(theAddress);
+}
+
+void CAHALAudioDevice::GetPreferredStereoChannels(bool inIsInput, UInt32& outLeft, UInt32& outRight) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theStereoPair[2] = { 0, 0 };
+ UInt32 theSize = 2 * sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, theStereoPair);
+ outLeft = theStereoPair[0];
+ outRight = theStereoPair[1];
+}
+
+void CAHALAudioDevice::SetPreferredStereoChannels(bool inIsInput, UInt32 inLeft, UInt32 inRight)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelsForStereo, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theStereoPair[2] = { inLeft, inRight };
+ SetPropertyData(theAddress, 0, NULL, 2 * sizeof(UInt32), theStereoPair);
+}
+
+bool CAHALAudioDevice::HasPreferredChannelLayout(bool inIsInput) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ return HasProperty(theAddress);
+}
+
+void CAHALAudioDevice::GetPreferredChannelLayout(bool inIsInput, AudioChannelLayout& outChannelLayout) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theSize = (SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription)) + GetTotalNumberChannels(inIsInput) * SizeOf32(AudioChannelDescription);
+ GetPropertyData(theAddress, 0, NULL, theSize, &outChannelLayout);
+}
+
+void CAHALAudioDevice::SetPreferredStereoChannels(bool inIsInput, AudioChannelLayout& inChannelLayout)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPreferredChannelLayout, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theSize = (SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription)) + GetTotalNumberChannels(inIsInput) * SizeOf32(AudioChannelDescription);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inChannelLayout);
+}
+
+UInt32 CAHALAudioDevice::GetNumberRelatedAudioDevices() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyRelatedDevices);
+ UInt32 theAnswer = 0;
+ if(HasProperty(theAddress))
+ {
+ theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer /= SizeOf32(AudioObjectID);
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetRelatedAudioDevices(UInt32& ioNumberRelatedDevices, AudioObjectID* outRelatedDevices) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyRelatedDevices);
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = ioNumberRelatedDevices * SizeOf32(AudioObjectID);
+ GetPropertyData(theAddress, 0, NULL, theSize, outRelatedDevices);
+ ioNumberRelatedDevices = theSize / SizeOf32(AudioObjectID);
+ }
+ else
+ {
+ UInt32 theSize = ioNumberRelatedDevices * SizeOf32(AudioObjectID);
+ memset(outRelatedDevices, 0, theSize);
+ ioNumberRelatedDevices = 0;
+ }
+}
+
+AudioObjectID CAHALAudioDevice::GetRelatedAudioDeviceByIndex(UInt32 inIndex) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ UInt32 theNumberRelatedDevices = GetNumberRelatedAudioDevices();
+ if((theNumberRelatedDevices > 0) && (inIndex < theNumberRelatedDevices))
+ {
+ CAAutoArrayDelete<AudioObjectID> theRelatedDeviceList(theNumberRelatedDevices);
+ GetRelatedAudioDevices(theNumberRelatedDevices, theRelatedDeviceList);
+ if((theNumberRelatedDevices > 0) && (inIndex < theNumberRelatedDevices))
+ {
+ theAnswer = theRelatedDeviceList[inIndex];
+ }
+ }
+ return theAnswer;
+}
+
+UInt32 CAHALAudioDevice::GetNumberStreams(bool inIsInput) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStreams, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer /= SizeOf32(AudioObjectID);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetStreams(bool inIsInput, UInt32& ioNumberStreams, AudioObjectID* outStreamList) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStreams, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theSize = ioNumberStreams * SizeOf32(AudioObjectID);
+ GetPropertyData(theAddress, 0, NULL, theSize, outStreamList);
+ ioNumberStreams = theSize / SizeOf32(AudioObjectID);
+}
+
+AudioObjectID CAHALAudioDevice::GetStreamByIndex(bool inIsInput, UInt32 inIndex) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ UInt32 theNumberStreams = GetNumberStreams(inIsInput);
+ if((theNumberStreams > 0) && (inIndex < theNumberStreams))
+ {
+ CAAutoArrayDelete<AudioObjectID> theStreamList(theNumberStreams);
+ GetStreams(inIsInput, theNumberStreams, theStreamList);
+ if((theNumberStreams > 0) && (inIndex < theNumberStreams))
+ {
+ theAnswer = theStreamList[inIndex];
+ }
+ }
+ return theAnswer;
+}
+
+UInt32 CAHALAudioDevice::GetTotalNumberChannels(bool inIsInput) const
+{
+ UInt32 theAnswer = 0;
+ CAPropertyAddress theAddress(kAudioDevicePropertyStreamConfiguration, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
+ CAAutoFree<AudioBufferList> theBufferList(theSize);
+ GetPropertyData(theAddress, 0, NULL, theSize, theBufferList);
+ for(UInt32 theIndex = 0; theIndex < theBufferList->mNumberBuffers; ++theIndex)
+ {
+ theAnswer += theBufferList->mBuffers[theIndex].mNumberChannels;
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetCurrentVirtualFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const
+{
+ ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inIsInput));
+ for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex)
+ {
+ CAHALAudioStream theStream(GetStreamByIndex(inIsInput, theIndex));
+ theStream.GetCurrentVirtualFormat(outFormats[theIndex]);
+ }
+}
+
+void CAHALAudioDevice::GetCurrentPhysicalFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const
+{
+ ioNumberStreams = std::min(ioNumberStreams, GetNumberStreams(inIsInput));
+ for(UInt32 theIndex = 0; theIndex < ioNumberStreams; ++theIndex)
+ {
+ CAHALAudioStream theStream(GetStreamByIndex(inIsInput, theIndex));
+ theStream.GetCurrentPhysicalFormat(outFormats[theIndex]);
+ }
+}
+
+bool CAHALAudioDevice::IsRunning() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsRunning);
+ UInt32 theAnswer = GetPropertyData_UInt32(theAddress, 0, NULL);
+ return theAnswer != 0;
+}
+
+bool CAHALAudioDevice::IsRunningSomewhere() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDeviceIsRunningSomewhere);
+ UInt32 theAnswer = 0;
+ if(HasProperty(theAddress))
+ {
+ theAnswer = GetPropertyData_UInt32(theAddress, 0, NULL);
+ }
+ return theAnswer != 0;
+}
+
+UInt32 CAHALAudioDevice::GetLatency(bool inIsInput) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyLatency, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+UInt32 CAHALAudioDevice::GetSafetyOffset(bool inIsInput) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySafetyOffset, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+bool CAHALAudioDevice::HasClockDomain() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockDomain);
+ return HasProperty(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetClockDomain() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockDomain);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+Float64 CAHALAudioDevice::GetActualSampleRate() const
+{
+ Float64 theAnswer = 0;
+ CAPropertyAddress theAddress(kAudioDevicePropertyActualSampleRate);
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = sizeof(Float64);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+ else
+ {
+ theAnswer = GetNominalSampleRate();
+ }
+ return theAnswer;
+}
+
+Float64 CAHALAudioDevice::GetNominalSampleRate() const
+{
+ Float64 theAnswer = 0;
+ CAPropertyAddress theAddress(kAudioDevicePropertyNominalSampleRate);
+ UInt32 theSize = sizeof(Float64);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::SetNominalSampleRate(Float64 inSampleRate)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyNominalSampleRate);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float64), &inSampleRate);
+}
+
+UInt32 CAHALAudioDevice::GetNumberAvailableNominalSampleRateRanges() const
+{
+ UInt32 theAnswer = 0;
+ CAPropertyAddress theAddress(kAudioDevicePropertyAvailableNominalSampleRates);
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer = theSize / SizeOf32(AudioValueRange);
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetAvailableNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyAvailableNominalSampleRates);
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = ioNumberRanges * SizeOf32(AudioValueRange);
+ GetPropertyData(theAddress, 0, NULL, theSize, outRanges);
+ ioNumberRanges = theSize / SizeOf32(AudioValueRange);
+ }
+ else
+ {
+ ioNumberRanges = 0;
+ }
+}
+
+void CAHALAudioDevice::GetAvailableNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const
+{
+ UInt32 theNumberRanges = GetNumberAvailableNominalSampleRateRanges();
+ ThrowIf(inIndex >= theNumberRanges, CAException(kAudioHardwareIllegalOperationError), "CAHALAudioDevice::GetAvailableNominalSampleRateRangeByIndex: index out of range");
+ CAAutoArrayDelete<AudioValueRange> theRanges(theNumberRanges);
+ GetAvailableNominalSampleRateRanges(theNumberRanges, theRanges);
+ outMinimum = theRanges[inIndex].mMinimum;
+ outMaximum = theRanges[inIndex].mMaximum;
+}
+
+bool CAHALAudioDevice::IsValidNominalSampleRate(Float64 inSampleRate) const
+{
+ bool theAnswer = false;
+ UInt32 theNumberRanges = GetNumberAvailableNominalSampleRateRanges();
+ CAAutoArrayDelete<AudioValueRange> theRanges(theNumberRanges);
+ GetAvailableNominalSampleRateRanges(theNumberRanges, theRanges);
+ for(UInt32 theIndex = 0; !theAnswer && (theIndex < theNumberRanges); ++theIndex)
+ {
+ theAnswer = (inSampleRate >= theRanges[theIndex].mMinimum) && (inSampleRate <= theRanges[theIndex].mMinimum);
+ }
+ return theAnswer;
+}
+
+bool CAHALAudioDevice::IsIOBufferSizeSettable() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
+ return IsPropertySettable(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetIOBufferSize() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+void CAHALAudioDevice::SetIOBufferSize(UInt32 inBufferSize)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSize);
+ SetPropertyData(theAddress, 0, NULL, sizeof(UInt32), &inBufferSize);
+}
+
+bool CAHALAudioDevice::UsesVariableIOBufferSizes() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyUsesVariableBufferFrameSizes);
+ return HasProperty(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetMaximumVariableIOBufferSize() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyUsesVariableBufferFrameSizes);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+bool CAHALAudioDevice::HasIOBufferSizeRange() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSizeRange);
+ return HasProperty(theAddress);
+}
+
+void CAHALAudioDevice::GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const
+{
+ AudioValueRange theAnswer = { 0, 0 };
+ CAPropertyAddress theAddress(kAudioDevicePropertyBufferFrameSizeRange);
+ UInt32 theSize = sizeof(AudioValueRange);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ outMinimum = static_cast<UInt32>(theAnswer.mMinimum);
+ outMaximum = static_cast<UInt32>(theAnswer.mMaximum);
+}
+
+AudioDeviceIOProcID CAHALAudioDevice::CreateIOProcID(AudioDeviceIOProc inIOProc, void* inClientData)
+{
+ AudioDeviceIOProcID theAnswer = NULL;
+ OSStatus theError = AudioDeviceCreateIOProcID(mObjectID, inIOProc, inClientData, &theAnswer);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::CreateIOProcID: got an error creating the IOProc ID");
+ return theAnswer;
+}
+
+void CAHALAudioDevice::DestroyIOProcID(AudioDeviceIOProcID inIOProcID)
+{
+ OSStatus theError = AudioDeviceDestroyIOProcID(mObjectID, inIOProcID);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::DestroyIOProcID: got an error destroying the IOProc ID");
+}
+
+void CAHALAudioDevice::StartIOProc(AudioDeviceIOProcID inIOProcID)
+{
+ OSStatus theError = AudioDeviceStart(mObjectID, inIOProcID);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StartIOProc: got an error starting an IOProc");
+}
+
+void CAHALAudioDevice::StartIOProcAtTime(AudioDeviceIOProcID inIOProcID, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware)
+{
+ UInt32 theFlags = 0;
+ if(inIsInput)
+ {
+ theFlags |= kAudioDeviceStartTimeIsInputFlag;
+ }
+ if(inIgnoreHardware)
+ {
+ theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag;
+ }
+
+ OSStatus theError = AudioDeviceStartAtTime(mObjectID, inIOProcID, &ioStartTime, theFlags);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StartIOProcAtTime: got an error starting an IOProc");
+}
+
+void CAHALAudioDevice::StopIOProc(AudioDeviceIOProcID inIOProcID)
+{
+ OSStatus theError = AudioDeviceStop(mObjectID, inIOProcID);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StopIOProc: got an error stopping an IOProc");
+}
+
+void CAHALAudioDevice::GetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, bool* outStreamUsage) const
+{
+ // make an AudioHardwareIOProcStreamUsage the right size
+ UInt32 theNumberStreams = GetNumberStreams(inIsInput);
+ UInt32 theSize = SizeOf32(void*) + SizeOf32(UInt32) + (theNumberStreams * SizeOf32(UInt32));
+ CAAutoFree<AudioHardwareIOProcStreamUsage> theStreamUsage(theSize);
+
+ // set it up
+ theStreamUsage->mIOProc = reinterpret_cast<void*>(inIOProcID);
+ theStreamUsage->mNumberStreams = theNumberStreams;
+
+ // get the property
+ CAPropertyAddress theAddress(kAudioDevicePropertyIOProcStreamUsage, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ GetPropertyData(theAddress, 0, NULL, theSize, theStreamUsage);
+
+ // fill out the return value
+ for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex)
+ {
+ outStreamUsage[theIndex] = (theStreamUsage->mStreamIsOn[theIndex] != 0);
+ }
+}
+
+void CAHALAudioDevice::SetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, const bool* inStreamUsage)
+{
+ // make an AudioHardwareIOProcStreamUsage the right size
+ UInt32 theNumberStreams = GetNumberStreams(inIsInput);
+ UInt32 theSize = SizeOf32(void*) + SizeOf32(UInt32) + (theNumberStreams * SizeOf32(UInt32));
+ CAAutoFree<AudioHardwareIOProcStreamUsage> theStreamUsage(theSize);
+
+ // set it up
+ theStreamUsage->mIOProc = reinterpret_cast<void*>(inIOProcID);
+ theStreamUsage->mNumberStreams = theNumberStreams;
+ for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex)
+ {
+ theStreamUsage->mStreamIsOn[theIndex] = (inStreamUsage[theIndex] ? 1 : 0);
+ }
+
+ // set the property
+ CAPropertyAddress theAddress(kAudioDevicePropertyIOProcStreamUsage, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
+ SetPropertyData(theAddress, 0, NULL, theSize, theStreamUsage);
+}
+
+Float32 CAHALAudioDevice::GetIOCycleUsage() const
+{
+ Float32 theAnswer = 0;
+ CAPropertyAddress theAddress(kAudioDevicePropertyIOCycleUsage);
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::SetIOCycleUsage(Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyIOCycleUsage);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
+}
+
+void CAHALAudioDevice::GetCurrentTime(AudioTimeStamp& outTime)
+{
+ OSStatus theError = AudioDeviceGetCurrentTime(mObjectID, &outTime);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::GetCurrentTime: got an error getting the current time");
+}
+
+void CAHALAudioDevice::TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime)
+{
+ OSStatus theError = AudioDeviceTranslateTime(mObjectID, &inTime, &outTime);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::TranslateTime: got an error translating time");
+}
+
+void CAHALAudioDevice::GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware)
+{
+ UInt32 theFlags = 0;
+ if(inIsInput)
+ {
+ theFlags |= kAudioDeviceStartTimeIsInputFlag;
+ }
+ if(inIgnoreHardware)
+ {
+ theFlags |= kAudioDeviceStartTimeDontConsultDeviceFlag;
+ }
+
+ OSStatus theError = AudioDeviceGetNearestStartTime(mObjectID, &ioTime, theFlags);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::GetNearestStartTime: got an error getting the start time");
+}
+
+bool CAHALAudioDevice::HasVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::VolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+Float32 CAHALAudioDevice::GetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
+ Float32 theValue = 0.0f;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+Float32 CAHALAudioDevice::GetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibels, inScope, inChannel);
+ Float32 theValue = 0.0f;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+void CAHALAudioDevice::SetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalar, inScope, inChannel);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
+}
+
+void CAHALAudioDevice::SetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibels, inScope, inChannel);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
+}
+
+Float32 CAHALAudioDevice::GetVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeDecibelsToScalar, inScope, inChannel);
+ Float32 theValue = inValue;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+Float32 CAHALAudioDevice::GetVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyVolumeScalarToDecibels, inScope, inChannel);
+ Float32 theValue = inValue;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+bool CAHALAudioDevice::HasSubVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::SubVolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+Float32 CAHALAudioDevice::GetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
+ Float32 theValue = 0.0f;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+Float32 CAHALAudioDevice::GetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibels, inScope, inChannel);
+ Float32 theValue = 0.0f;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+void CAHALAudioDevice::SetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalar, inScope, inChannel);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
+}
+
+void CAHALAudioDevice::SetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibels, inScope, inChannel);
+ SetPropertyData(theAddress, 0, NULL, sizeof(Float32), &inValue);
+}
+
+Float32 CAHALAudioDevice::GetSubVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeDecibelsToScalar, inScope, inChannel);
+ Float32 theValue = inValue;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+Float32 CAHALAudioDevice::GetSubVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubVolumeScalarToDecibels, inScope, inChannel);
+ Float32 theValue = inValue;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+bool CAHALAudioDevice::HasMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::MuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+bool CAHALAudioDevice::GetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
+ UInt32 theValue = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue != 0;
+}
+
+void CAHALAudioDevice::SetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyMute, inScope, inChannel);
+ UInt32 theValue = (inValue ? 1 : 0);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+}
+
+bool CAHALAudioDevice::HasSoloControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::SoloControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+bool CAHALAudioDevice::GetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
+ UInt32 theValue = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue != 0;
+}
+
+void CAHALAudioDevice::SetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySolo, inScope, inChannel);
+ UInt32 theValue = (inValue ? 1 : 0);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+}
+
+bool CAHALAudioDevice::HasStereoPanControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::StereoPanControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+Float32 CAHALAudioDevice::GetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
+ Float32 theValue = 0.0f;
+ UInt32 theSize = sizeof(Float32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue;
+}
+
+void CAHALAudioDevice::SetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStereoPan, inScope, inChannel);
+ UInt32 theSize = sizeof(Float32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inValue);
+}
+
+void CAHALAudioDevice::GetStereoPanControlChannels(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& outLeftChannel, UInt32& outRightChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyStereoPanChannels, inScope, inChannel);
+ UInt32 theValue[2] = { 0, 0 };
+ UInt32 theSize = 2 * sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, theValue);
+ outLeftChannel = theValue[0];
+ outRightChannel = theValue[1];
+}
+
+bool CAHALAudioDevice::HasJackControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyJackIsConnected, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::GetJackControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyJackIsConnected, inScope, inChannel);
+ UInt32 theValue = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue != 0;
+}
+
+bool CAHALAudioDevice::HasSubMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::SubMuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+bool CAHALAudioDevice::GetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
+ UInt32 theValue = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue != 0;
+}
+
+void CAHALAudioDevice::SetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertySubMute, inScope, inChannel);
+ UInt32 theValue = (inValue ? 1 : 0);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+}
+
+bool CAHALAudioDevice::HasiSubOwnerControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::iSubOwnerControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+bool CAHALAudioDevice::GetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
+ UInt32 theValue = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theValue != 0;
+}
+
+void CAHALAudioDevice::SetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDriverShouldOwniSub, inScope, inChannel);
+ UInt32 theValue = (inValue ? 1 : 0);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+}
+
+bool CAHALAudioDevice::HasDataSourceControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::DataSourceControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetCurrentDataSourceID(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
+ UInt32 theAnswer = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::SetCurrentDataSourceByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSource, inScope, inChannel);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inID);
+}
+
+UInt32 CAHALAudioDevice::GetNumberAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSources, inScope, inChannel);
+ UInt32 theAnswer = 0;
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer = theSize / SizeOf32(UInt32);
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberSources, UInt32* outSources) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSources, inScope, inChannel);
+ UInt32 theNumberSources = std::min(GetNumberAvailableDataSources(inScope, inChannel), ioNumberSources);
+ UInt32 theSize = theNumberSources * SizeOf32(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, outSources);
+ ioNumberSources = theSize / SizeOf32(UInt32);
+}
+
+UInt32 CAHALAudioDevice::GetAvailableDataSourceByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const
+{
+ AudioStreamID theAnswer = 0;
+ UInt32 theNumberSources = GetNumberAvailableDataSources(inScope, inChannel);
+ if((theNumberSources > 0) && (inIndex < theNumberSources))
+ {
+ CAAutoArrayDelete<UInt32> theSourceList(theNumberSources);
+ GetAvailableDataSources(inScope, inChannel, theNumberSources, theSourceList);
+ theAnswer = theSourceList[inIndex];
+ }
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioDevice::CopyDataSourceNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyDataSourceNameForIDCFString, inScope, inChannel);
+ CFStringRef theAnswer = NULL;
+ AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
+ return theAnswer;
+}
+
+bool CAHALAudioDevice::HasDataDestinationControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::DataDestinationControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
+ return IsPropertySettable(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetCurrentDataDestinationID(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
+ UInt32 theAnswer = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::SetCurrentDataDestinationByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestination, inScope, inChannel);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inID);
+}
+
+UInt32 CAHALAudioDevice::GetNumberAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinations, inScope, inChannel);
+ UInt32 theAnswer = 0;
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer = theSize / SizeOf32(UInt32);
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberDestinations, UInt32* outDestinations) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinations, inScope, inChannel);
+ UInt32 theNumberDestinations = std::min(GetNumberAvailableDataDestinations(inScope, inChannel), ioNumberDestinations);
+ UInt32 theSize = theNumberDestinations * SizeOf32(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, outDestinations);
+ ioNumberDestinations = theSize / SizeOf32(UInt32);
+}
+
+UInt32 CAHALAudioDevice::GetAvailableDataDestinationByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const
+{
+ AudioStreamID theAnswer = 0;
+ UInt32 theNumberDestinations = GetNumberAvailableDataDestinations(inScope, inChannel);
+ if((theNumberDestinations > 0) && (inIndex < theNumberDestinations))
+ {
+ CAAutoArrayDelete<UInt32> theDestinationList(theNumberDestinations);
+ GetAvailableDataDestinations(inScope, inChannel, theNumberDestinations, theDestinationList);
+ theAnswer = theDestinationList[inIndex];
+ }
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioDevice::CopyDataDestinationNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyPlayThruDestinationNameForIDCFString, inScope, inChannel);
+ CFStringRef theAnswer = NULL;
+ AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
+ return theAnswer;
+}
+
+bool CAHALAudioDevice::HasClockSourceControl() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
+ return HasProperty(theAddress);
+}
+
+bool CAHALAudioDevice::ClockSourceControlIsSettable() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
+ return IsPropertySettable(theAddress);
+}
+
+UInt32 CAHALAudioDevice::GetCurrentClockSourceID() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
+ UInt32 theAnswer = 0;
+ UInt32 theSize = sizeof(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioDevice::SetCurrentClockSourceByID(UInt32 inID)
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSource);
+ UInt32 theSize = sizeof(UInt32);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inID);
+}
+
+UInt32 CAHALAudioDevice::GetNumberAvailableClockSources() const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSources);
+ UInt32 theAnswer = 0;
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer = theSize / SizeOf32(UInt32);
+ }
+ return theAnswer;
+}
+
+void CAHALAudioDevice::GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSources);
+ UInt32 theNumberSources = std::min(GetNumberAvailableClockSources(), ioNumberSources);
+ UInt32 theSize = theNumberSources * SizeOf32(UInt32);
+ GetPropertyData(theAddress, 0, NULL, theSize, outSources);
+ ioNumberSources = theSize / SizeOf32(UInt32);
+}
+
+UInt32 CAHALAudioDevice::GetAvailableClockSourceByIndex(UInt32 inIndex) const
+{
+ AudioStreamID theAnswer = 0;
+ UInt32 theNumberSources = GetNumberAvailableClockSources();
+ if((theNumberSources > 0) && (inIndex < theNumberSources))
+ {
+ CAAutoArrayDelete<UInt32> theSourceList(theNumberSources);
+ GetAvailableClockSources(theNumberSources, theSourceList);
+ theAnswer = theSourceList[inIndex];
+ }
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioDevice::CopyClockSourceNameForID(UInt32 inID) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSourceNameForIDCFString);
+ CFStringRef theAnswer = NULL;
+ AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(CFStringRef) };
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
+ return theAnswer;
+}
+
+UInt32 CAHALAudioDevice::GetClockSourceKindForID(UInt32 inID) const
+{
+ CAPropertyAddress theAddress(kAudioDevicePropertyClockSourceKindForID);
+ UInt32 theAnswer = 0;
+ AudioValueTranslation theTranslation = { &inID, sizeof(UInt32), &theAnswer, sizeof(UInt32) };
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theTranslation);
+ return theAnswer;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.h b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.h
new file mode 100644
index 0000000000..8cfb466886
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioDevice.h
@@ -0,0 +1,238 @@
+/*
+ File: CAHALAudioDevice.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAHALAudioDevice_h__)
+#define __CAHALAudioDevice_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Super Class Includes
+#include "CAHALAudioObject.h"
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+
+//==================================================================================================
+// CAHALAudioDevice
+//==================================================================================================
+
+class CAHALAudioDevice
+:
+ public CAHALAudioObject
+{
+
+// Construction/Destruction
+public:
+ CAHALAudioDevice(AudioObjectID inAudioDevice);
+ CAHALAudioDevice(CFStringRef inUID);
+ virtual ~CAHALAudioDevice();
+
+// General Stuff
+public:
+ CFStringRef CopyDeviceUID() const;
+ bool HasModelUID() const;
+ CFStringRef CopyModelUID() const;
+ CFStringRef CopyConfigurationApplicationBundleID() const;
+ CFURLRef CopyIconLocation() const;
+ UInt32 GetTransportType() const;
+ bool CanBeDefaultDevice(bool inIsInput, bool inIsSystem) const;
+ bool HasDevicePlugInStatus() const;
+ OSStatus GetDevicePlugInStatus() const;
+ bool IsAlive() const;
+ bool IsHidden() const;
+ pid_t GetHogModeOwner() const;
+ bool IsHogModeSettable() const;
+ bool TakeHogMode();
+ void ReleaseHogMode();
+ bool HasPreferredStereoChannels(bool inIsInput) const;
+ void GetPreferredStereoChannels(bool inIsInput, UInt32& outLeft, UInt32& outRight) const;
+ void SetPreferredStereoChannels(bool inIsInput, UInt32 inLeft, UInt32 inRight);
+ bool HasPreferredChannelLayout(bool inIsInput) const;
+ void GetPreferredChannelLayout(bool inIsInput, AudioChannelLayout& outChannelLayout) const;
+ void SetPreferredStereoChannels(bool inIsInput, AudioChannelLayout& inChannelLayout);
+ UInt32 GetNumberRelatedAudioDevices() const;
+ void GetRelatedAudioDevices(UInt32& ioNumberRelatedDevices, AudioObjectID* outRelatedDevices) const;
+ AudioObjectID GetRelatedAudioDeviceByIndex(UInt32 inIndex) const;
+
+// Stream Stuff
+public:
+ UInt32 GetNumberStreams(bool inIsInput) const;
+ void GetStreams(bool inIsInput, UInt32& ioNumberStreams, AudioObjectID* outStreamList) const;
+ AudioObjectID GetStreamByIndex(bool inIsInput, UInt32 inIndex) const;
+ UInt32 GetTotalNumberChannels(bool inIsInput) const;
+ void GetCurrentVirtualFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const;
+ void GetCurrentPhysicalFormats(bool inIsInput, UInt32& ioNumberStreams, AudioStreamBasicDescription* outFormats) const;
+
+// IO Stuff
+public:
+ bool IsRunning() const;
+ bool IsRunningSomewhere() const;
+ UInt32 GetLatency(bool inIsInput) const;
+ UInt32 GetSafetyOffset(bool inIsInput) const;
+ bool HasClockDomain() const;
+ UInt32 GetClockDomain() const;
+ Float64 GetActualSampleRate() const;
+ Float64 GetNominalSampleRate() const;
+ void SetNominalSampleRate(Float64 inSampleRate);
+ UInt32 GetNumberAvailableNominalSampleRateRanges() const;
+ void GetAvailableNominalSampleRateRanges(UInt32& ioNumberRanges, AudioValueRange* outRanges) const;
+ void GetAvailableNominalSampleRateRangeByIndex(UInt32 inIndex, Float64& outMinimum, Float64& outMaximum) const;
+ bool IsValidNominalSampleRate(Float64 inSampleRate) const;
+ bool IsIOBufferSizeSettable() const;
+ UInt32 GetIOBufferSize() const;
+ void SetIOBufferSize(UInt32 inBufferSize);
+ bool UsesVariableIOBufferSizes() const;
+ UInt32 GetMaximumVariableIOBufferSize() const;
+ bool HasIOBufferSizeRange() const;
+ void GetIOBufferSizeRange(UInt32& outMinimum, UInt32& outMaximum) const;
+ AudioDeviceIOProcID CreateIOProcID(AudioDeviceIOProc inIOProc, void* inClientData);
+ AudioDeviceIOProcID CreateIOProcIDWithBlock(dispatch_queue_t inDispatchQueue, AudioDeviceIOBlock inIOBlock);
+ void DestroyIOProcID(AudioDeviceIOProcID inIOProcID);
+ void StartIOProc(AudioDeviceIOProcID inIOProcID);
+ void StartIOProcAtTime(AudioDeviceIOProcID inIOProcID, AudioTimeStamp& ioStartTime, bool inIsInput, bool inIgnoreHardware);
+ void StopIOProc(AudioDeviceIOProcID inIOProcID);
+ void GetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, bool* outStreamUsage) const;
+ void SetIOProcStreamUsage(AudioDeviceIOProcID inIOProcID, bool inIsInput, const bool* inStreamUsage);
+ Float32 GetIOCycleUsage() const;
+ void SetIOCycleUsage(Float32 inValue);
+
+// Time Operations
+public:
+ void GetCurrentTime(AudioTimeStamp& outTime);
+ void TranslateTime(const AudioTimeStamp& inTime, AudioTimeStamp& outTime);
+ void GetNearestStartTime(AudioTimeStamp& ioTime, bool inIsInput, bool inIgnoreHardware);
+
+// Controls
+public:
+ bool HasVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool VolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ Float32 GetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ Float32 GetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue);
+ void SetVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue);
+ Float32 GetVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const;
+ Float32 GetVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const;
+
+ bool HasSubVolumeControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool SubVolumeControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ Float32 GetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ Float32 GetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetSubVolumeControlScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue);
+ void SetSubVolumeControlDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue);
+ Float32 GetSubVolumeControlScalarForDecibelValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const;
+ Float32 GetSubVolumeControlDecibelForScalarValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue) const;
+
+ bool HasMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool MuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool GetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue);
+
+ bool HasSoloControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool SoloControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool GetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetSoloControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue);
+
+ bool HasStereoPanControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool StereoPanControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ Float32 GetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetStereoPanControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, Float32 inValue);
+ void GetStereoPanControlChannels(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& outLeftChannel, UInt32& outRightChannel) const;
+
+ bool HasJackControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool GetJackControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+
+ bool HasSubMuteControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool SubMuteControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool GetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetSubMuteControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue);
+
+ bool HasiSubOwnerControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool iSubOwnerControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool GetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetiSubOwnerControlValue(AudioObjectPropertyScope inScope, UInt32 inChannel, bool inValue);
+
+ bool HasDataSourceControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool DataSourceControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ UInt32 GetCurrentDataSourceID(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetCurrentDataSourceByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID);
+ UInt32 GetNumberAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void GetAvailableDataSources(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberSources, UInt32* outSources) const;
+ UInt32 GetAvailableDataSourceByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const;
+ CFStringRef CopyDataSourceNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const;
+
+ bool HasDataDestinationControl(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ bool DataDestinationControlIsSettable(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ UInt32 GetCurrentDataDestinationID(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void SetCurrentDataDestinationByID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID);
+ UInt32 GetNumberAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel) const;
+ void GetAvailableDataDestinations(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32& ioNumberDestinations, UInt32* outDestinations) const;
+ UInt32 GetAvailableDataDestinationByIndex(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inIndex) const;
+ CFStringRef CopyDataDestinationNameForID(AudioObjectPropertyScope inScope, UInt32 inChannel, UInt32 inID) const;
+
+ bool HasClockSourceControl() const;
+ bool ClockSourceControlIsSettable() const;
+ UInt32 GetCurrentClockSourceID() const;
+ void SetCurrentClockSourceByID(UInt32 inID);
+ UInt32 GetNumberAvailableClockSources() const;
+ void GetAvailableClockSources(UInt32& ioNumberSources, UInt32* outSources) const;
+ UInt32 GetAvailableClockSourceByIndex(UInt32 inIndex) const;
+ CFStringRef CopyClockSourceNameForID(UInt32 inID) const;
+ UInt32 GetClockSourceKindForID(UInt32 inID) const;
+
+};
+
+inline AudioDeviceIOProcID CAHALAudioDevice::CreateIOProcIDWithBlock(dispatch_queue_t inDispatchQueue, AudioDeviceIOBlock inIOBlock)
+{
+ AudioDeviceIOProcID theAnswer = NULL;
+ OSStatus theError = AudioDeviceCreateIOProcIDWithBlock(&theAnswer, mObjectID, inDispatchQueue, inIOBlock);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::CreateIOProcIDWithBlock: got an error creating the IOProc ID");
+ return theAnswer;
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.cpp
new file mode 100644
index 0000000000..c8f16b4fb3
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.cpp
@@ -0,0 +1,370 @@
+/*
+ File: CAHALAudioObject.cpp
+ Abstract: CAHALAudioObject.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAHALAudioObject.h"
+
+// PublicUtility Includes
+#include "CAAutoDisposer.h"
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAPropertyAddress.h"
+
+//==================================================================================================
+// CAHALAudioObject
+//==================================================================================================
+
+CAHALAudioObject::CAHALAudioObject(AudioObjectID inObjectID)
+:
+ mObjectID(inObjectID)
+{
+}
+
+CAHALAudioObject::~CAHALAudioObject()
+{
+}
+
+AudioObjectID CAHALAudioObject::GetObjectID() const
+{
+ return mObjectID;
+}
+
+void CAHALAudioObject::SetObjectID(AudioObjectID inObjectID)
+{
+ mObjectID = inObjectID;
+}
+
+AudioClassID CAHALAudioObject::GetClassID() const
+{
+ // set up the return value
+ AudioClassID theAnswer = 0;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyClass);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ UInt32 theSize = sizeof(AudioClassID);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+AudioObjectID CAHALAudioObject::GetOwnerObjectID() const
+{
+ // set up the return value
+ AudioObjectID theAnswer = 0;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyOwner);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(AudioObjectID);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyOwningPlugInBundleID() const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyCreator);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyName() const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyName);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyManufacturer() const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyManufacturer);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyElementName, inScope, inElement);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyCategoryNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyElementCategoryName, inScope, inElement);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+CFStringRef CAHALAudioObject::CopyNumberNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const
+{
+ // set up the return value
+ CFStringRef theAnswer = NULL;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyElementNumberName, inScope, inElement);
+
+ // make sure the property exists
+ if(HasProperty(theAddress))
+ {
+ // get the property data
+ UInt32 theSize = sizeof(CFStringRef);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ }
+
+ return theAnswer;
+}
+
+bool CAHALAudioObject::ObjectExists(AudioObjectID inObjectID)
+{
+ Boolean isSettable;
+ CAPropertyAddress theAddress(kAudioObjectPropertyClass);
+ return (inObjectID == 0) || (AudioObjectIsPropertySettable(inObjectID, &theAddress, &isSettable) != 0);
+}
+
+UInt32 CAHALAudioObject::GetNumberOwnedObjects(AudioClassID inClass) const
+{
+ // set up the return value
+ UInt32 theAnswer = 0;
+
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
+
+ // figure out the qualifier
+ UInt32 theQualifierSize = 0;
+ void* theQualifierData = NULL;
+ if(inClass != 0)
+ {
+ theQualifierSize = sizeof(AudioObjectID);
+ theQualifierData = &inClass;
+ }
+
+ // get the property data size
+ theAnswer = GetPropertyDataSize(theAddress, theQualifierSize, theQualifierData);
+
+ // calculate the number of object IDs
+ theAnswer /= SizeOf32(AudioObjectID);
+
+ return theAnswer;
+}
+
+void CAHALAudioObject::GetAllOwnedObjects(AudioClassID inClass, UInt32& ioNumberObjects, AudioObjectID* ioObjectIDs) const
+{
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
+
+ // figure out the qualifier
+ UInt32 theQualifierSize = 0;
+ void* theQualifierData = NULL;
+ if(inClass != 0)
+ {
+ theQualifierSize = sizeof(AudioObjectID);
+ theQualifierData = &inClass;
+ }
+
+ // get the property data
+ UInt32 theDataSize = ioNumberObjects * SizeOf32(AudioClassID);
+ GetPropertyData(theAddress, theQualifierSize, theQualifierData, theDataSize, ioObjectIDs);
+
+ // set the number of object IDs being returned
+ ioNumberObjects = theDataSize / SizeOf32(AudioObjectID);
+}
+
+AudioObjectID CAHALAudioObject::GetOwnedObjectByIndex(AudioClassID inClass, UInt32 inIndex)
+{
+ // set up the property address
+ CAPropertyAddress theAddress(kAudioObjectPropertyOwnedObjects);
+
+ // figure out the qualifier
+ UInt32 theQualifierSize = 0;
+ void* theQualifierData = NULL;
+ if(inClass != 0)
+ {
+ theQualifierSize = sizeof(AudioObjectID);
+ theQualifierData = &inClass;
+ }
+
+ // figure out how much space to allocate
+ UInt32 theDataSize = GetPropertyDataSize(theAddress, theQualifierSize, theQualifierData);
+ UInt32 theNumberObjectIDs = theDataSize / SizeOf32(AudioObjectID);
+
+ // set up the return value
+ AudioObjectID theAnswer = 0;
+
+ // maker sure the index is in range
+ if(inIndex < theNumberObjectIDs)
+ {
+ // allocate it
+ CAAutoArrayDelete<AudioObjectID> theObjectList(theDataSize / sizeof(AudioObjectID));
+
+ // get the property data
+ GetPropertyData(theAddress, theQualifierSize, theQualifierData, theDataSize, theObjectList);
+
+ // get the return value
+ theAnswer = theObjectList[inIndex];
+ }
+
+ return theAnswer;
+}
+
+bool CAHALAudioObject::HasProperty(const AudioObjectPropertyAddress& inAddress) const
+{
+ return AudioObjectHasProperty(mObjectID, &inAddress);
+}
+
+bool CAHALAudioObject::IsPropertySettable(const AudioObjectPropertyAddress& inAddress) const
+{
+ Boolean isSettable = false;
+ OSStatus theError = AudioObjectIsPropertySettable(mObjectID, &inAddress, &isSettable);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::IsPropertySettable: got an error getting info about a property");
+ return isSettable != 0;
+}
+
+UInt32 CAHALAudioObject::GetPropertyDataSize(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData) const
+{
+ UInt32 theDataSize = 0;
+ OSStatus theError = AudioObjectGetPropertyDataSize(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, &theDataSize);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::GetPropertyDataSize: got an error getting the property data size");
+ return theDataSize;
+}
+
+void CAHALAudioObject::GetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32& ioDataSize, void* outData) const
+{
+ OSStatus theError = AudioObjectGetPropertyData(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, &ioDataSize, outData);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::GetPropertyData: got an error getting the property data");
+}
+
+void CAHALAudioObject::SetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData)
+{
+ OSStatus theError = AudioObjectSetPropertyData(mObjectID, &inAddress, inQualifierDataSize, inQualifierData, inDataSize, inData);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::SetPropertyData: got an error setting the property data");
+}
+
+void CAHALAudioObject::AddPropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData)
+{
+ OSStatus theError = AudioObjectAddPropertyListener(mObjectID, &inAddress, inListenerProc, inClientData);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::AddPropertyListener: got an error adding a property listener");
+}
+
+void CAHALAudioObject::RemovePropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData)
+{
+ OSStatus theError = AudioObjectRemovePropertyListener(mObjectID, &inAddress, inListenerProc, inClientData);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::RemovePropertyListener: got an error removing a property listener");
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.h b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.h
new file mode 100644
index 0000000000..d99ab0d59a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioObject.h
@@ -0,0 +1,155 @@
+/*
+ File: CAHALAudioObject.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAHALAudioObject_h__)
+#define __CAHALAudioObject_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudio.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreAudio.h>
+ #include <CoreFoundation.h>
+#endif
+
+//==================================================================================================
+// CAHALAudioObject
+//==================================================================================================
+
+class CAHALAudioObject
+{
+
+// Construction/Destruction
+public:
+ CAHALAudioObject(AudioObjectID inObjectID);
+ virtual ~CAHALAudioObject();
+
+// Attributes
+public:
+ AudioObjectID GetObjectID() const;
+ void SetObjectID(AudioObjectID inObjectID);
+ AudioClassID GetClassID() const;
+ AudioObjectID GetOwnerObjectID() const;
+ CFStringRef CopyOwningPlugInBundleID() const;
+ CFStringRef CopyName() const;
+ CFStringRef CopyManufacturer() const;
+ CFStringRef CopyNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const;
+ CFStringRef CopyCategoryNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const;
+ CFStringRef CopyNumberNameForElement(AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) const;
+
+ static bool ObjectExists(AudioObjectID inObjectID);
+
+// Owned Objects
+public:
+ UInt32 GetNumberOwnedObjects(AudioClassID inClass) const;
+ void GetAllOwnedObjects(AudioClassID inClass, UInt32& ioNumberObjects, AudioObjectID* ioObjectIDs) const;
+ AudioObjectID GetOwnedObjectByIndex(AudioClassID inClass, UInt32 inIndex);
+
+// Property Operations
+public:
+ bool HasProperty(const AudioObjectPropertyAddress& inAddress) const;
+ bool IsPropertySettable(const AudioObjectPropertyAddress& inAddress) const;
+ UInt32 GetPropertyDataSize(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData) const;
+
+ void GetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32& ioDataSize, void* outData) const;
+ void SetPropertyData(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData);
+
+ UInt32 GetPropertyData_UInt32(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { UInt32 theAnswer = 0; UInt32 theDataSize = SizeOf32(UInt32); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &theAnswer); return theAnswer; }
+ void SetPropertyData_UInt32(const AudioObjectPropertyAddress& inAddress, UInt32 inValue, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(UInt32), &inValue); }
+
+ Float32 GetPropertyData_Float32(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { Float32 theAnswer = 0; UInt32 theDataSize = SizeOf32(Float32); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &theAnswer); return theAnswer; }
+ void SetPropertyData_Float32(const AudioObjectPropertyAddress& inAddress, Float32 inValue, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(Float32), &inValue); }
+
+ Float64 GetPropertyData_Float64(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { Float64 theAnswer = 0; UInt32 theDataSize = SizeOf32(Float64); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &theAnswer); return theAnswer; }
+ void SetPropertyData_Float64(const AudioObjectPropertyAddress& inAddress, Float64 inValue, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(Float64), &inValue); }
+
+ CFTypeRef GetPropertyData_CFType(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { CFTypeRef theAnswer = NULL; UInt32 theDataSize = SizeOf32(CFTypeRef); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &theAnswer); return theAnswer; }
+ void SetPropertyData_CFType(const AudioObjectPropertyAddress& inAddress, CFTypeRef inValue, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(CFTypeRef), &inValue); }
+
+ CFStringRef GetPropertyData_CFString(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { CFStringRef theAnswer = NULL; UInt32 theDataSize = SizeOf32(CFStringRef); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &theAnswer); return theAnswer; }
+ void SetPropertyData_CFString(const AudioObjectPropertyAddress& inAddress, CFStringRef inValue, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(CFStringRef), &inValue); }
+
+ template <class T> void GetPropertyData_Struct(const AudioObjectPropertyAddress& inAddress, T& outStruct, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { UInt32 theDataSize = SizeOf32(T); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, &outStruct); }
+ template <class T> void SetPropertyData_Struct(const AudioObjectPropertyAddress& inAddress, T& inStruct, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, SizeOf32(T), &inStruct); }
+
+ template <class T> UInt32 GetPropertyData_ArraySize(const AudioObjectPropertyAddress& inAddress, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { return GetPropertyDataSize(inAddress, inQualifierDataSize, inQualifierData) / SizeOf32(T); }
+ template <class T> void GetPropertyData_Array(const AudioObjectPropertyAddress& inAddress, UInt32& ioNumberItems, T* outArray, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) const { UInt32 theDataSize = ioNumberItems * SizeOf32(T); GetPropertyData(inAddress, inQualifierDataSize, inQualifierData, theDataSize, outArray); ioNumberItems = theDataSize / SizeOf32(T); }
+ template <class T> void SetPropertyData_Array(const AudioObjectPropertyAddress& inAddress, UInt32 inNumberItems, T* inArray, UInt32 inQualifierDataSize = 0, const void* inQualifierData = NULL) { SetPropertyData(inAddress, inQualifierDataSize, inQualifierData, inNumberItems * SizeOf32(T), inArray); }
+
+ void AddPropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData);
+ void RemovePropertyListener(const AudioObjectPropertyAddress& inAddress, AudioObjectPropertyListenerProc inListenerProc, void* inClientData);
+
+ void AddPropertyListenerBlock(const AudioObjectPropertyAddress& inAddress, dispatch_queue_t inDispatchQueue, AudioObjectPropertyListenerBlock inListenerBlock);
+ void RemovePropertyListenerBlock(const AudioObjectPropertyAddress& inAddress, dispatch_queue_t inDispatchQueue, AudioObjectPropertyListenerBlock inListenerBlock);
+
+// Implementation
+protected:
+ AudioObjectID mObjectID;
+
+};
+
+inline void CAHALAudioObject::AddPropertyListenerBlock(const AudioObjectPropertyAddress& inAddress, dispatch_queue_t inDispatchQueue, AudioObjectPropertyListenerBlock inListenerBlock)
+{
+ OSStatus theError = AudioObjectAddPropertyListenerBlock(mObjectID, &inAddress, inDispatchQueue, inListenerBlock);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::AddPropertyListenerBlock: got an error adding a property listener");
+}
+
+inline void CAHALAudioObject::RemovePropertyListenerBlock(const AudioObjectPropertyAddress& inAddress, dispatch_queue_t inDispatchQueue, AudioObjectPropertyListenerBlock inListenerBlock)
+{
+ OSStatus theError = AudioObjectRemovePropertyListenerBlock(mObjectID, &inAddress, inDispatchQueue, inListenerBlock);
+ ThrowIfError(theError, CAException(theError), "CAHALAudioObject::RemovePropertyListener: got an error removing a property listener");
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.cpp
new file mode 100644
index 0000000000..62b9b3c566
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.cpp
@@ -0,0 +1,182 @@
+/*
+ File: CAHALAudioStream.cpp
+ Abstract: CAHALAudioStream.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAHALAudioStream.h"
+
+// PublicUtility Includes
+#include "CAAutoDisposer.h"
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAPropertyAddress.h"
+
+//==================================================================================================
+// CAHALAudioStream
+//==================================================================================================
+
+CAHALAudioStream::CAHALAudioStream(AudioObjectID inAudioStream)
+:
+ CAHALAudioObject(inAudioStream)
+{
+}
+
+CAHALAudioStream::~CAHALAudioStream()
+{
+}
+
+UInt32 CAHALAudioStream::GetDirection() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyDirection);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+UInt32 CAHALAudioStream::GetTerminalType() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyTerminalType);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+UInt32 CAHALAudioStream::GetStartingChannel() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyStartingChannel);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+UInt32 CAHALAudioStream::GetLatency() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyLatency);
+ return GetPropertyData_UInt32(theAddress, 0, NULL);
+}
+
+void CAHALAudioStream::GetCurrentVirtualFormat(AudioStreamBasicDescription& outFormat) const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyVirtualFormat);
+ UInt32 theSize = sizeof(AudioStreamBasicDescription);
+ GetPropertyData(theAddress, 0, NULL, theSize, &outFormat);
+}
+
+void CAHALAudioStream::SetCurrentVirtualFormat(const AudioStreamBasicDescription& inFormat)
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyVirtualFormat);
+ SetPropertyData(theAddress, 0, NULL, sizeof(AudioStreamBasicDescription), &inFormat);
+}
+
+UInt32 CAHALAudioStream::GetNumberAvailableVirtualFormats() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyAvailableVirtualFormats);
+ UInt32 theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer /= SizeOf32(AudioStreamRangedDescription);
+ return theAnswer;
+}
+
+void CAHALAudioStream::GetAvailableVirtualFormats(UInt32& ioNumberFormats, AudioStreamRangedDescription* outFormats) const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyAvailableVirtualFormats);
+ UInt32 theSize = ioNumberFormats * SizeOf32(AudioStreamRangedDescription);
+ GetPropertyData(theAddress, 0, NULL, theSize, outFormats);
+ ioNumberFormats = theSize / SizeOf32(AudioStreamRangedDescription);
+}
+
+void CAHALAudioStream::GetAvailableVirtualFormatByIndex(UInt32 inIndex, AudioStreamRangedDescription& outFormat) const
+{
+ UInt32 theNumberFormats = GetNumberAvailableVirtualFormats();
+ if((theNumberFormats > 0) && (inIndex < theNumberFormats))
+ {
+ CAAutoArrayDelete<AudioStreamRangedDescription> theFormats(theNumberFormats);
+ GetAvailableVirtualFormats(theNumberFormats, theFormats);
+ if((theNumberFormats > 0) && (inIndex < theNumberFormats))
+ {
+ outFormat = theFormats[inIndex];
+ }
+ }
+}
+
+void CAHALAudioStream::GetCurrentPhysicalFormat(AudioStreamBasicDescription& outFormat) const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyPhysicalFormat);
+ UInt32 theSize = sizeof(AudioStreamBasicDescription);
+ GetPropertyData(theAddress, 0, NULL, theSize, &outFormat);
+}
+
+void CAHALAudioStream::SetCurrentPhysicalFormat(const AudioStreamBasicDescription& inFormat)
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyPhysicalFormat);
+ SetPropertyData(theAddress, 0, NULL, sizeof(AudioStreamBasicDescription), &inFormat);
+}
+
+UInt32 CAHALAudioStream::GetNumberAvailablePhysicalFormats() const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyAvailablePhysicalFormats);
+ UInt32 theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer /= SizeOf32(AudioStreamRangedDescription);
+ return theAnswer;
+}
+
+void CAHALAudioStream::GetAvailablePhysicalFormats(UInt32& ioNumberFormats, AudioStreamRangedDescription* outFormats) const
+{
+ CAPropertyAddress theAddress(kAudioStreamPropertyAvailablePhysicalFormats);
+ UInt32 theSize = ioNumberFormats * SizeOf32(AudioStreamRangedDescription);
+ GetPropertyData(theAddress, 0, NULL, theSize, outFormats);
+ ioNumberFormats = theSize / SizeOf32(AudioStreamRangedDescription);
+}
+
+void CAHALAudioStream::GetAvailablePhysicalFormatByIndex(UInt32 inIndex, AudioStreamRangedDescription& outFormat) const
+{
+ UInt32 theNumberFormats = GetNumberAvailablePhysicalFormats();
+ if((theNumberFormats > 0) && (inIndex < theNumberFormats))
+ {
+ CAAutoArrayDelete<AudioStreamRangedDescription> theFormats(theNumberFormats);
+ GetAvailablePhysicalFormats(theNumberFormats, theFormats);
+ if((theNumberFormats > 0) && (inIndex < theNumberFormats))
+ {
+ outFormat = theFormats[inIndex];
+ }
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.h b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.h
new file mode 100644
index 0000000000..0c6cb55a85
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioStream.h
@@ -0,0 +1,94 @@
+/*
+ File: CAHALAudioStream.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAHALAudioStream_h__)
+#define __CAHALAudioStream_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Super Class Includes
+#include "CAHALAudioObject.h"
+
+//==================================================================================================
+// CAHALAudioStream
+//==================================================================================================
+
+class CAHALAudioStream
+:
+ public CAHALAudioObject
+{
+
+// Construction/Destruction
+public:
+ CAHALAudioStream(AudioObjectID inAudioStream);
+ virtual ~CAHALAudioStream();
+
+// Attributes
+public:
+ UInt32 GetDirection() const;
+ UInt32 GetTerminalType() const;
+ UInt32 GetStartingChannel() const;
+ UInt32 GetLatency() const;
+
+// Format Info
+public:
+ void GetCurrentVirtualFormat(AudioStreamBasicDescription& outFormat) const;
+ void SetCurrentVirtualFormat(const AudioStreamBasicDescription& inFormat);
+ UInt32 GetNumberAvailableVirtualFormats() const;
+ void GetAvailableVirtualFormats(UInt32& ioNumberFormats, AudioStreamRangedDescription* outFormats) const;
+ void GetAvailableVirtualFormatByIndex(UInt32 inIndex, AudioStreamRangedDescription& outFormat) const;
+
+ void GetCurrentPhysicalFormat(AudioStreamBasicDescription& outFormat) const;
+ void SetCurrentPhysicalFormat(const AudioStreamBasicDescription& inFormat);
+ UInt32 GetNumberAvailablePhysicalFormats() const;
+ void GetAvailablePhysicalFormats(UInt32& ioNumberFormats, AudioStreamRangedDescription* outFormats) const;
+ void GetAvailablePhysicalFormatByIndex(UInt32 inIndex, AudioStreamRangedDescription& outFormat) const;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.cpp
new file mode 100644
index 0000000000..404dd98498
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.cpp
@@ -0,0 +1,181 @@
+/*
+ File: CAHALAudioSystemObject.cpp
+ Abstract: CAHALAudioSystemObject.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAHALAudioSystemObject.h"
+
+// PublicUtility Includes
+#include "CAAutoDisposer.h"
+#include "CACFString.h"
+#include "CAHALAudioDevice.h"
+#include "CAPropertyAddress.h"
+
+//==================================================================================================
+// CAHALAudioSystemObject
+//==================================================================================================
+
+CAHALAudioSystemObject::CAHALAudioSystemObject()
+:
+ CAHALAudioObject(kAudioObjectSystemObject)
+{
+}
+
+CAHALAudioSystemObject::~CAHALAudioSystemObject()
+{
+}
+
+UInt32 CAHALAudioSystemObject::GetNumberAudioDevices() const
+{
+ CAPropertyAddress theAddress(kAudioHardwarePropertyDevices);
+ UInt32 theAnswer = GetPropertyDataSize(theAddress, 0, NULL);
+ theAnswer /= SizeOf32(AudioObjectID);
+ return theAnswer;
+}
+
+void CAHALAudioSystemObject::GetAudioDevices(UInt32& ioNumberAudioDevices, AudioObjectID* outAudioDevices) const
+{
+ CAPropertyAddress theAddress(kAudioHardwarePropertyDevices);
+ UInt32 theSize = ioNumberAudioDevices * SizeOf32(AudioObjectID);
+ GetPropertyData(theAddress, 0, NULL, theSize, outAudioDevices);
+ ioNumberAudioDevices = theSize / SizeOf32(AudioObjectID);
+}
+
+AudioObjectID CAHALAudioSystemObject::GetAudioDeviceAtIndex(UInt32 inIndex) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ UInt32 theNumberDevices = GetNumberAudioDevices();
+ if((theNumberDevices > 0) && (inIndex < theNumberDevices))
+ {
+ CAAutoArrayDelete<AudioObjectID> theDeviceList(theNumberDevices);
+ GetAudioDevices(theNumberDevices, theDeviceList);
+ if((theNumberDevices > 0) && (inIndex < theNumberDevices))
+ {
+ theAnswer = theDeviceList[inIndex];
+ }
+ }
+ return theAnswer;
+}
+
+AudioObjectID CAHALAudioSystemObject::GetAudioDeviceForUID(CFStringRef inUID) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ AudioValueTranslation theValue = { &inUID, sizeof(CFStringRef), &theAnswer, sizeof(AudioObjectID) };
+ CAPropertyAddress theAddress(kAudioHardwarePropertyDeviceForUID);
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theAnswer;
+}
+
+void CAHALAudioSystemObject::LogBasicDeviceInfo()
+{
+ UInt32 theNumberDevices = GetNumberAudioDevices();
+ CAAutoArrayDelete<AudioObjectID> theDeviceList(theNumberDevices);
+ GetAudioDevices(theNumberDevices, theDeviceList);
+ DebugMessageN1("CAHALAudioSystemObject::LogBasicDeviceInfo: %d devices", (int)theNumberDevices);
+ for(UInt32 theDeviceIndex = 0; theDeviceIndex < theNumberDevices; ++theDeviceIndex)
+ {
+ char theCString[256];
+ UInt32 theCStringSize = sizeof(theCString);
+ DebugMessageN1("CAHALAudioSystemObject::LogBasicDeviceInfo: Device %d", (int)theDeviceIndex);
+
+ CAHALAudioDevice theDevice(theDeviceList[theDeviceIndex]);
+ DebugMessageN1("CAHALAudioSystemObject::LogBasicDeviceInfo: Object ID: %d", (int)theDeviceList[theDeviceIndex]);
+
+ CACFString theDeviceName(theDevice.CopyName());
+ theCStringSize = sizeof(theCString);
+ theDeviceName.GetCString(theCString, theCStringSize);
+ DebugMessageN1("CAHALAudioSystemObject::LogBasicDeviceInfo: Name: %s", theCString);
+
+ CACFString theDeviceUID(theDevice.CopyDeviceUID());
+ theCStringSize = sizeof(theCString);
+ theDeviceUID.GetCString(theCString, theCStringSize);
+ DebugMessageN1("CAHALAudioSystemObject::LogBasicDeviceInfo: UID: %s", theCString);
+ }
+}
+
+static inline AudioObjectPropertySelector CAHALAudioSystemObject_CalculateDefaultDeviceProperySelector(bool inIsInput, bool inIsSystem)
+{
+ AudioObjectPropertySelector theAnswer = kAudioHardwarePropertyDefaultOutputDevice;
+ if(inIsInput)
+ {
+ theAnswer = kAudioHardwarePropertyDefaultInputDevice;
+ }
+ else if(inIsSystem)
+ {
+ theAnswer = kAudioHardwarePropertyDefaultSystemOutputDevice;
+ }
+ return theAnswer;
+}
+
+AudioObjectID CAHALAudioSystemObject::GetDefaultAudioDevice(bool inIsInput, bool inIsSystem) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ CAPropertyAddress theAddress(CAHALAudioSystemObject_CalculateDefaultDeviceProperySelector(inIsInput, inIsSystem));
+ UInt32 theSize = sizeof(AudioObjectID);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theAnswer);
+ return theAnswer;
+}
+
+void CAHALAudioSystemObject::SetDefaultAudioDevice(bool inIsInput, bool inIsSystem, AudioObjectID inNewDefaultDevice)
+{
+ CAPropertyAddress theAddress(CAHALAudioSystemObject_CalculateDefaultDeviceProperySelector(inIsInput, inIsSystem));
+ UInt32 theSize = sizeof(AudioObjectID);
+ SetPropertyData(theAddress, 0, NULL, theSize, &inNewDefaultDevice);
+}
+
+AudioObjectID CAHALAudioSystemObject::GetAudioPlugInForBundleID(CFStringRef inUID) const
+{
+ AudioObjectID theAnswer = kAudioObjectUnknown;
+ AudioValueTranslation theValue = { &inUID, sizeof(CFStringRef), &theAnswer, sizeof(AudioObjectID) };
+ CAPropertyAddress theAddress(kAudioHardwarePropertyPlugInForBundleID);
+ UInt32 theSize = sizeof(AudioValueTranslation);
+ GetPropertyData(theAddress, 0, NULL, theSize, &theValue);
+ return theAnswer;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.h b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.h
new file mode 100644
index 0000000000..0ade7a5098
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHALAudioSystemObject.h
@@ -0,0 +1,90 @@
+/*
+ File: CAHALAudioSystemObject.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAHALAudioSystemObject_h__)
+#define __CAHALAudioSystemObject_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Super Class Includes
+#include "CAHALAudioObject.h"
+
+//==================================================================================================
+// CAHALAudioSystemObject
+//==================================================================================================
+
+class CAHALAudioSystemObject
+:
+ public CAHALAudioObject
+{
+
+// Construction/Destruction
+public:
+ CAHALAudioSystemObject();
+ virtual ~CAHALAudioSystemObject();
+
+// Audio Device List Management
+public:
+ UInt32 GetNumberAudioDevices() const;
+ void GetAudioDevices(UInt32& ioNumberAudioDevices, AudioObjectID* outAudioDevices) const;
+ AudioObjectID GetAudioDeviceAtIndex(UInt32 inIndex) const;
+ AudioObjectID GetAudioDeviceForUID(CFStringRef inUID) const;
+ void LogBasicDeviceInfo();
+
+// Default Device Management
+public:
+ AudioObjectID GetDefaultAudioDevice(bool inIsInput, bool inIsSystem) const;
+ void SetDefaultAudioDevice(bool inIsInput, bool inIsSystem, AudioObjectID inNewDefaultDevice);
+
+// PlugIns
+public:
+ AudioObjectID GetAudioPlugInForBundleID(CFStringRef inBundleID) const;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.cpp
new file mode 100644
index 0000000000..db78a4afee
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.cpp
@@ -0,0 +1,99 @@
+/*
+ File: CAHostTimeBase.cpp
+ Abstract: CAHostTimeBase.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CAHostTimeBase.h"
+
+Float64 CAHostTimeBase::sFrequency = 0;
+Float64 CAHostTimeBase::sInverseFrequency = 0;
+UInt32 CAHostTimeBase::sMinDelta = 0;
+UInt32 CAHostTimeBase::sToNanosNumerator = 0;
+UInt32 CAHostTimeBase::sToNanosDenominator = 0;
+pthread_once_t CAHostTimeBase::sIsInited = PTHREAD_ONCE_INIT;
+#if Track_Host_TimeBase
+UInt64 CAHostTimeBase::sLastTime = 0;
+#endif
+
+//=============================================================================
+// CAHostTimeBase
+//
+// This class provides platform independent access to the host's time base.
+//=============================================================================
+
+void CAHostTimeBase::Initialize()
+{
+ // get the info about Absolute time
+ #if TARGET_OS_MAC
+ struct mach_timebase_info theTimeBaseInfo;
+ mach_timebase_info(&theTimeBaseInfo);
+ sMinDelta = 1;
+ sToNanosNumerator = theTimeBaseInfo.numer;
+ sToNanosDenominator = theTimeBaseInfo.denom;
+
+ // the frequency of that clock is: (sToNanosDenominator / sToNanosNumerator) * 10^9
+ sFrequency = static_cast<Float64>(sToNanosDenominator) / static_cast<Float64>(sToNanosNumerator);
+ sFrequency *= 1000000000.0;
+ #elif TARGET_OS_WIN32
+ LARGE_INTEGER theFrequency;
+ QueryPerformanceFrequency(&theFrequency);
+ sMinDelta = 1;
+ sToNanosNumerator = 1000000000ULL;
+ sToNanosDenominator = *((UInt64*)&theFrequency);
+ sFrequency = static_cast<Float64>(*((UInt64*)&theFrequency));
+ #endif
+ sInverseFrequency = 1.0 / sFrequency;
+
+ #if Log_Host_Time_Base_Parameters
+ DebugPrintf("Host Time Base Parameters");
+ DebugPrintf(" Minimum Delta: %lu", (unsigned long)sMinDelta);
+ DebugPrintf(" Frequency: %f", sFrequency);
+ DebugPrintf(" To Nanos Numerator: %lu", (unsigned long)sToNanosNumerator);
+ DebugPrintf(" To Nanos Denominator: %lu", (unsigned long)sToNanosDenominator);
+ #endif
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.h b/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.h
new file mode 100644
index 0000000000..50e3507648
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAHostTimeBase.h
@@ -0,0 +1,234 @@
+/*
+ File: CAHostTimeBase.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAHostTimeBase_h__)
+#define __CAHostTimeBase_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+#if TARGET_OS_MAC
+ #include <mach/mach_time.h>
+ #include <pthread.h>
+#elif TARGET_OS_WIN32
+ #include <windows.h>
+ #include "WinPThreadDefs.h"
+#else
+ #error Unsupported operating system
+#endif
+
+#include "CADebugPrintf.h"
+
+//=============================================================================
+// CAHostTimeBase
+//
+// This class provides platform independent access to the host's time base.
+//=============================================================================
+
+#if CoreAudio_Debug
+// #define Log_Host_Time_Base_Parameters 1
+// #define Track_Host_TimeBase 1
+#endif
+
+class CAHostTimeBase
+{
+
+public:
+ static UInt64 ConvertToNanos(UInt64 inHostTime);
+ static UInt64 ConvertFromNanos(UInt64 inNanos);
+
+ static UInt64 GetTheCurrentTime();
+#if TARGET_OS_MAC
+ static UInt64 GetCurrentTime() { return GetTheCurrentTime(); }
+#endif
+ static UInt64 GetCurrentTimeInNanos();
+
+ static Float64 GetFrequency() { pthread_once(&sIsInited, Initialize); return sFrequency; }
+ static Float64 GetInverseFrequency() { pthread_once(&sIsInited, Initialize); return sInverseFrequency; }
+ static UInt32 GetMinimumDelta() { pthread_once(&sIsInited, Initialize); return sMinDelta; }
+
+ static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
+ static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
+
+ static UInt64 MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator);
+
+private:
+ static void Initialize();
+
+ static pthread_once_t sIsInited;
+
+ static Float64 sFrequency;
+ static Float64 sInverseFrequency;
+ static UInt32 sMinDelta;
+ static UInt32 sToNanosNumerator;
+ static UInt32 sToNanosDenominator;
+#if Track_Host_TimeBase
+ static UInt64 sLastTime;
+#endif
+};
+
+inline UInt64 CAHostTimeBase::GetTheCurrentTime()
+{
+ UInt64 theTime = 0;
+
+ #if TARGET_OS_MAC
+ theTime = mach_absolute_time();
+ #elif TARGET_OS_WIN32
+ LARGE_INTEGER theValue;
+ QueryPerformanceCounter(&theValue);
+ theTime = *((UInt64*)&theValue);
+ #endif
+
+ #if Track_Host_TimeBase
+ if(sLastTime != 0)
+ {
+ if(theTime <= sLastTime)
+ {
+ DebugPrintf("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime);
+ }
+ sLastTime = theTime;
+ }
+ else
+ {
+ sLastTime = theTime;
+ }
+ #endif
+
+ return theTime;
+}
+
+inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime)
+{
+ pthread_once(&sIsInited, Initialize);
+
+ UInt64 theAnswer = MultiplyByRatio(inHostTime, sToNanosNumerator, sToNanosDenominator);
+ #if CoreAudio_Debug
+ if(((sToNanosNumerator > sToNanosDenominator) && (theAnswer < inHostTime)) || ((sToNanosDenominator > sToNanosNumerator) && (theAnswer > inHostTime)))
+ {
+ DebugPrintf("CAHostTimeBase::ConvertToNanos: The conversion wrapped");
+ }
+ #endif
+
+ return theAnswer;
+}
+
+inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos)
+{
+ pthread_once(&sIsInited, Initialize);
+
+ UInt64 theAnswer = MultiplyByRatio(inNanos, sToNanosDenominator, sToNanosNumerator);
+ #if CoreAudio_Debug
+ if(((sToNanosDenominator > sToNanosNumerator) && (theAnswer < inNanos)) || ((sToNanosNumerator > sToNanosDenominator) && (theAnswer > inNanos)))
+ {
+ DebugPrintf("CAHostTimeBase::ConvertFromNanos: The conversion wrapped");
+ }
+ #endif
+
+ return theAnswer;
+}
+
+inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos()
+{
+ return ConvertToNanos(GetTheCurrentTime());
+}
+
+inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
+{
+ UInt64 theAnswer;
+
+ if(inStartTime <= inEndTime)
+ {
+ theAnswer = inEndTime - inStartTime;
+ }
+ else
+ {
+ theAnswer = inStartTime - inEndTime;
+ }
+
+ return ConvertToNanos(theAnswer);
+}
+
+inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
+{
+ SInt64 theAnswer;
+ SInt64 theSign = 1;
+
+ if(inStartTime <= inEndTime)
+ {
+ theAnswer = static_cast<SInt64>(inEndTime - inStartTime);
+ }
+ else
+ {
+ theAnswer = static_cast<SInt64>(inStartTime - inEndTime);
+ theSign = -1;
+ }
+
+ return theSign * static_cast<SInt64>(ConvertToNanos(static_cast<UInt64>(theAnswer)));
+}
+
+inline UInt64 CAHostTimeBase::MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator)
+{
+#if TARGET_OS_MAC && TARGET_RT_64_BIT
+ __uint128_t theAnswer = inMuliplicand;
+#else
+ long double theAnswer = inMuliplicand;
+#endif
+ if(inNumerator != inDenominator)
+ {
+ theAnswer *= inNumerator;
+ theAnswer /= inDenominator;
+ }
+ return static_cast<UInt64>(theAnswer);
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CALogMacros.h b/libs/appleutility/CoreAudio/PublicUtility/CALogMacros.h
new file mode 100644
index 0000000000..7fd4ac4c21
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CALogMacros.h
@@ -0,0 +1,140 @@
+/*
+ File: CALogMacros.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CALogMacros_h__)
+#define __CALogMacros_h__
+
+//=============================================================================
+// Log Macros
+//=============================================================================
+
+#if CoreAudio_Debug
+
+ #include "CADebugMacros.h"
+ #include "CADebugPrintf.h"
+ #include <stdio.h>
+ #include <string.h>
+
+ #define PrintLine(msg) DebugPrintfRtn(DebugPrintfFileComma "%s\n", (msg))
+
+ #define PrintBool(msg, b) DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (b) ? "true" : "false")
+ #define PrintIndexedBool(msg, i, b) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %s\n", (msg), (long)(i), (b) ? "true" : "false")
+
+ #define PrintToggle(msg, b) DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (b) ? "on" : "off")
+ #define PrintIndexedToggle(msg, i, b) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %s\n", (msg), (long)(i), (b) ? "on" : "off")
+
+ #define PrintInt(msg, n) DebugPrintfRtn(DebugPrintfFileComma "%s%ld\n", (msg), (long)(n))
+ #define PrintIndexedInt(msg, i, n) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %ld\n", (msg), (long)(i), (long)(n))
+
+ #define PrintHex(msg, n) DebugPrintfRtn(DebugPrintfFileComma "%s0x%lX\n", (msg), (unsigned long)(n))
+ #define PrintIndexedHex(msg, i, n) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: 0x%lX\n", (msg), (long)(i), (unsigned long)(n))
+
+ #define PrintFloat(msg, f) DebugPrintfRtn(DebugPrintfFileComma "%s%.6f\n", (msg), (f))
+ #define PrintIndexedFloat(msg, i, f) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %.6f\n", (msg), (long)(i), (f))
+ #define PrintFloatIndexedFloat(msg, i, f) DebugPrintfRtn(DebugPrintfFileComma " %s %.6f: %.6f\n", (msg), (i), (f))
+
+ #define PrintString(msg, s) DebugPrintfRtn(DebugPrintfFileComma "%s%s\n", (msg), (s))
+ #define PrintIndexedString(msg, i, s) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %s\n", (msg), (long)(i), (s))
+
+ #define PrintPointer(msg, p) DebugPrintfRtn(DebugPrintfFileComma "%s%p\n", (msg), (p))
+ #define PrintIndexedPointer(msg, i, p) DebugPrintfRtn(DebugPrintfFileComma " %s %ld: %p\n", (msg), (long)(i), (p))
+
+ #define Print4CharCode(msg, c) { \
+ UInt32 __4CC_number = (c); \
+ char __4CC_string[5] = CA4CCToCString(__4CC_number); \
+ DebugPrintfRtn(DebugPrintfFileComma "%s'%s'\n", (msg), __4CC_string); \
+ }
+ #define PrintIndexed4CharCode(msg, i, c) { \
+ UInt32 __4CC_number = (c); \
+ char __4CC_string[5] = CA4CCToCString(__4CC_number); \
+ DebugPrintfRtn(DebugPrintfFileComma " %s %ld: '%s'\n", (msg), (long)(i), __4CC_string); \
+ }
+
+ #define ErrorLine(s) DebugPrintfRtn(DebugPrintfFileComma "%s\n", (s))
+ #define OSErrorLine(s, e) { \
+ OSStatus __err_number = (e); \
+ char __err_string[5] = CA4CCToCString(__err_number); \
+ DebugPrintfRtn(DebugPrintfFileComma "%s, OSStatus code: %s\n", (s), __err_string); \
+ }
+
+ #define MessageIfOSError(e, s) if((e) != 0) { OSErrorLine(s, e); }
+ #define MessageIfNULL(p, s) if((p) == 0) { ErrorLine(s); }
+
+#else
+
+ #define PrintLine(msg)
+
+ #define PrintBool(msg, b) (b)
+ #define PrintIndexedBool(msg, i, b) (b)
+
+ #define PrintInt(msg, n) (n)
+ #define PrintIndexedInt(msg, i, n) (n)
+
+ #define PrintHex(msg, n) (n)
+ #define PrintIndexedHex(msg, i, n) (n)
+
+ #define PrintFloat(msg, f) (f)
+ #define PrintIndexedFloat(msg, i, f) (f)
+ #define PrintFloatIndexedFloat(msg, i, f) (f)
+
+ #define PrintString(msg, s) (s)
+ #define PrintIndexedString(msg, i, s) (s)
+
+ #define PrintPointer(msg, p) (p)
+ #define PrintIndexedPointer(msg, i, p) (p)
+
+ #define Print4CharCode(msg, c) (c)
+ #define PrintIndexed4CharCode(msg, i, c) (c)
+
+ #define ErrorLine(s) (s)
+ #define OSErrorLine(s, e) (e)
+
+ #define MessageIfOSError(e, s) (e)
+ #define MessageIfNULL(p, s) (p)
+
+#endif // CoreAudio_Debug
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAMath.h b/libs/appleutility/CoreAudio/PublicUtility/CAMath.h
new file mode 100644
index 0000000000..eb81f26e95
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAMath.h
@@ -0,0 +1,68 @@
+/*
+ File: CAMath.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAMath_h__
+#define __CAMath_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+inline bool fiszero(Float64 f) { return (f == 0.); }
+inline bool fiszero(Float32 f) { return (f == 0.f); }
+
+inline bool fnonzero(Float64 f) { return !fiszero(f); }
+inline bool fnonzero(Float32 f) { return !fiszero(f); }
+
+inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
+inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
+
+inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
+inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
+
+#endif // __CAMath_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAMixMap.h b/libs/appleutility/CoreAudio/PublicUtility/CAMixMap.h
new file mode 100644
index 0000000000..62e95d4aa5
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAMixMap.h
@@ -0,0 +1,157 @@
+/*
+ File: CAMixMap.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAMixMap_h__
+#define __CAMixMap_h__
+
+ // manages the setting of mix map volumes
+
+class CAMixMap {
+public:
+ CAMixMap ()
+ : mIns(0), mOuts (0), mMixMap(NULL)
+ {}
+
+ CAMixMap (const CAMixMap &mm)
+ : mIns(0), mOuts (0), mMixMap(NULL)
+ { *this = mm; }
+
+ CAMixMap (UInt32 numIns, UInt32 numOuts)
+ : mIns(numIns), mOuts (numOuts), mMixMap(NULL)
+ {
+ mMixMap = new Float32[numIns * numOuts];
+ memset (mMixMap, 0, ByteSize());
+ }
+
+ ~CAMixMap () { delete [] mMixMap; }
+
+ CAMixMap& operator=(const CAMixMap& mm)
+ {
+ if (mMixMap) { delete [] mMixMap; mMixMap = NULL; }
+ mIns = mm.mIns; mOuts = mm.mOuts;
+ if (NumIns() && NumOuts()) {
+ mMixMap = new Float32 [ NumIns() * NumOuts() ];
+ memcpy (mMixMap, mm.mMixMap, ByteSize());
+ }
+ return *this;
+ }
+
+ UInt32 NumIns () const { return mIns; }
+ UInt32 NumOuts () const { return mOuts; }
+
+ void SetCrossPoint (UInt32 inputChan, UInt32 outputChan, Float32 val)
+ {
+ if (inputChan < NumIns() && outputChan < NumOuts())
+ mMixMap[inputChan * NumOuts() + outputChan] = val;
+ }
+ Float32 GetCrossPoint (UInt32 inputChan, UInt32 outputChan) const
+ {
+ return (inputChan < NumIns() && outputChan < NumOuts())
+ ? mMixMap[inputChan * NumOuts() + outputChan]
+ : 0;
+ }
+
+ void SetDiagonal (Float32 val)
+ {
+ for (UInt32 i = 0; i < NumIns() && i < NumOuts(); ++i) {
+ mMixMap[i * NumOuts() + i] = val;
+ }
+ }
+
+ void Clear () { memset (mMixMap, 0, ByteSize()); }
+
+
+ Float32* MM() { return mMixMap; }
+ const Float32* MM() const { return mMixMap; }
+ UInt32 ByteSize () const { return NumIns() * NumOuts() * sizeof(Float32); }
+
+ UInt32 CountActiveInputs(UInt32 inOutputChannel)
+ {
+ UInt32 sum = 0;
+ for (UInt32 i = 0, k = inOutputChannel; i < mIns; ++i, k+=mOuts) {
+ if (mMixMap[k] != 0.f) sum++;
+ }
+ return sum;
+ }
+
+ void Normalize()
+ {
+ // ensure that no output channel will sum over unity.
+ Float32* mixmap = mMixMap;
+ Float32 maxsum = 0.f;
+ for (UInt32 j = 0; j < mOuts; ++j) {
+ Float32 sum = 0.f;
+ for (UInt32 i = 0, k = j; i < mIns; ++i, k+=mOuts) {
+ sum += mixmap[k];
+ }
+ if (sum > maxsum) maxsum = sum;
+ }
+
+ if (maxsum == 0.f) return;
+ Float32 scale = 1.f / maxsum;
+ for (UInt32 i = 0; i < mIns * mOuts; ++i) {
+ mixmap[i] *= scale;
+ }
+ }
+
+ void Print ()
+ {
+ printf ("Num Ins: %d, Num Outs: %d\n", (int)mIns, (int)mOuts);
+ for (unsigned int ins = 0; ins < mIns; ++ins) {
+ printf ("\t%d: ", ins);
+ for (unsigned int outs = 0; outs < mOuts; ++outs)
+ printf ("(%.3f) ", mMixMap[ins * NumOuts() + outs]);
+ printf("\n");
+ }
+ }
+
+private:
+ UInt32 mIns;
+ UInt32 mOuts;
+ Float32 *mMixMap;
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAMutex.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAMutex.cpp
new file mode 100644
index 0000000000..88cf9b0b02
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAMutex.cpp
@@ -0,0 +1,345 @@
+/*
+ File: CAMutex.cpp
+ Abstract: CAMutex.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAMutex.h"
+
+#if TARGET_OS_MAC
+ #include <errno.h>
+#endif
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+#include "CAHostTimeBase.h"
+
+//==================================================================================================
+// Logging
+//==================================================================================================
+
+#if CoreAudio_Debug
+// #define Log_Ownership 1
+// #define Log_Errors 1
+// #define Log_LongLatencies 1
+// #define LongLatencyThreshholdNS 1000000ULL // nanoseconds
+#endif
+
+//==================================================================================================
+// CAMutex
+//==================================================================================================
+
+CAMutex::CAMutex(const char* inName)
+:
+ mName(inName),
+ mOwner(0)
+{
+#if TARGET_OS_MAC
+ OSStatus theError = pthread_mutex_init(&mMutex, NULL);
+ ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex");
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+ #endif
+#elif TARGET_OS_WIN32
+ mMutex = CreateMutex(NULL, false, NULL);
+ ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex.");
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+ #endif
+#endif
+}
+
+CAMutex::~CAMutex()
+{
+#if TARGET_OS_MAC
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+ #endif
+ pthread_mutex_destroy(&mMutex);
+#elif TARGET_OS_WIN32
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
+ #endif
+ if(mMutex != NULL)
+ {
+ CloseHandle(mMutex);
+ }
+#endif
+}
+
+bool CAMutex::Lock()
+{
+ bool theAnswer = false;
+
+#if TARGET_OS_MAC
+ pthread_t theCurrentThread = pthread_self();
+ if(!pthread_equal(theCurrentThread, mOwner))
+ {
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+ #endif
+
+ #if Log_LongLatencies
+ UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
+ #endif
+
+ OSStatus theError = pthread_mutex_lock(&mMutex);
+ ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex");
+ mOwner = theCurrentThread;
+ theAnswer = true;
+
+ #if Log_LongLatencies
+ UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
+ if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
+ DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName);
+ #endif
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+ }
+#elif TARGET_OS_WIN32
+ if(mOwner != GetCurrentThreadId())
+ {
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
+ ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex");
+ mOwner = GetCurrentThreadId();
+ theAnswer = true;
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+ }
+#endif
+
+ return theAnswer;
+}
+
+void CAMutex::Unlock()
+{
+#if TARGET_OS_MAC
+ if(pthread_equal(pthread_self(), mOwner))
+ {
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+
+ mOwner = 0;
+ OSStatus theError = pthread_mutex_unlock(&mMutex);
+ ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex");
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
+ #endif
+ }
+ else
+ {
+ DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
+ }
+#elif TARGET_OS_WIN32
+ if(mOwner == GetCurrentThreadId())
+ {
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ mOwner = 0;
+ bool wasReleased = ReleaseMutex(mMutex);
+ ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex");
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+ }
+ else
+ {
+ DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
+ }
+#endif
+}
+
+bool CAMutex::Try(bool& outWasLocked)
+{
+ bool theAnswer = false;
+ outWasLocked = false;
+
+#if TARGET_OS_MAC
+ pthread_t theCurrentThread = pthread_self();
+ if(!pthread_equal(theCurrentThread, mOwner))
+ {
+ // this means the current thread doesn't already own the lock
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+ #endif
+
+ // go ahead and call trylock to see if we can lock it.
+ int theError = pthread_mutex_trylock(&mMutex);
+ if(theError == 0)
+ {
+ // return value of 0 means we successfully locked the lock
+ mOwner = theCurrentThread;
+ theAnswer = true;
+ outWasLocked = true;
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+ #endif
+ }
+ else if(theError == EBUSY)
+ {
+ // return value of EBUSY means that the lock was already locked by another thread
+ theAnswer = false;
+ outWasLocked = false;
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
+ #endif
+ }
+ else
+ {
+ // any other return value means something really bad happenned
+ ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
+ }
+ }
+ else
+ {
+ // this means the current thread already owns the lock
+ theAnswer = true;
+ outWasLocked = false;
+ }
+#elif TARGET_OS_WIN32
+ if(mOwner != GetCurrentThreadId())
+ {
+ // this means the current thread doesn't own the lock
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+
+ // try to acquire the mutex
+ OSStatus theError = WaitForSingleObject(mMutex, 0);
+ if(theError == WAIT_OBJECT_0)
+ {
+ // this means we successfully locked the lock
+ mOwner = GetCurrentThreadId();
+ theAnswer = true;
+ outWasLocked = true;
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+ }
+ else if(theError == WAIT_TIMEOUT)
+ {
+ // this means that the lock was already locked by another thread
+ theAnswer = false;
+ outWasLocked = false;
+
+ #if Log_Ownership
+ DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
+ #endif
+ }
+ else
+ {
+ // any other return value means something really bad happenned
+ ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
+ }
+ }
+ else
+ {
+ // this means the current thread already owns the lock
+ theAnswer = true;
+ outWasLocked = false;
+ }
+#endif
+
+ return theAnswer;
+}
+
+bool CAMutex::IsFree() const
+{
+ return mOwner == 0;
+}
+
+bool CAMutex::IsOwnedByCurrentThread() const
+{
+ bool theAnswer = true;
+
+#if TARGET_OS_MAC
+ theAnswer = pthread_equal(pthread_self(), mOwner);
+#elif TARGET_OS_WIN32
+ theAnswer = (mOwner == GetCurrentThreadId());
+#endif
+
+ return theAnswer;
+}
+
+
+CAMutex::Unlocker::Unlocker(CAMutex& inMutex)
+: mMutex(inMutex),
+ mNeedsLock(false)
+{
+ Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!");
+
+ mMutex.Unlock();
+ mNeedsLock = true;
+}
+
+CAMutex::Unlocker::~Unlocker()
+{
+ if(mNeedsLock)
+ {
+ mMutex.Lock();
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAMutex.h b/libs/appleutility/CoreAudio/PublicUtility/CAMutex.h
new file mode 100644
index 0000000000..093066b400
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAMutex.h
@@ -0,0 +1,163 @@
+/*
+ File: CAMutex.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAMutex_h__
+#define __CAMutex_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+#if TARGET_OS_MAC
+ #include <pthread.h>
+#elif TARGET_OS_WIN32
+ #include <windows.h>
+#else
+ #error Unsupported operating system
+#endif
+
+//==================================================================================================
+// A recursive mutex.
+//==================================================================================================
+
+class CAMutex
+{
+// Construction/Destruction
+public:
+ CAMutex(const char* inName);
+ virtual ~CAMutex();
+
+// Actions
+public:
+ virtual bool Lock();
+ virtual void Unlock();
+ virtual bool Try(bool& outWasLocked); // returns true if lock is free, false if not
+
+ virtual bool IsFree() const;
+ virtual bool IsOwnedByCurrentThread() const;
+
+// Implementation
+protected:
+ const char* mName;
+#if TARGET_OS_MAC
+ pthread_t mOwner;
+ pthread_mutex_t mMutex;
+#elif TARGET_OS_WIN32
+ UInt32 mOwner;
+ HANDLE mMutex;
+#endif
+
+// Helper class to manage taking and releasing recursively
+public:
+ class Locker
+ {
+
+ // Construction/Destruction
+ public:
+ Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
+ Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); }
+ // in this case the mutex can be null
+ ~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } }
+
+
+ private:
+ Locker(const Locker&);
+ Locker& operator=(const Locker&);
+
+ // Implementation
+ private:
+ CAMutex* mMutex;
+ bool mNeedsRelease;
+
+ };
+
+// Unlocker
+ class Unlocker
+ {
+ public:
+ Unlocker(CAMutex& inMutex);
+ ~Unlocker();
+
+ private:
+ CAMutex& mMutex;
+ bool mNeedsLock;
+
+ // Hidden definitions of copy ctor, assignment operator
+ Unlocker(const Unlocker& copy); // Not implemented
+ Unlocker& operator=(const Unlocker& copy); // Not implemented
+ };
+
+// you can use this with Try - if you take the lock in try, pass in the outWasLocked var
+ class Tryer {
+
+ // Construction/Destruction
+ public:
+ Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); }
+ ~Tryer () { if (mNeedsRelease) mMutex.Unlock(); }
+
+ bool HasLock () const { return mHasLock; }
+
+ private:
+ Tryer(const Tryer&);
+ Tryer& operator=(const Tryer&);
+
+ // Implementation
+ private:
+ CAMutex & mMutex;
+ bool mNeedsRelease;
+ bool mHasLock;
+ };
+};
+
+
+#endif // __CAMutex_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAPThread.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAPThread.cpp
new file mode 100644
index 0000000000..3da1058de7
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAPThread.cpp
@@ -0,0 +1,450 @@
+/*
+ File: CAPThread.cpp
+ Abstract: CAPThread.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CAPThread.h"
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+#include "CAException.h"
+
+// System Includes
+#if TARGET_OS_MAC
+ #include <mach/mach.h>
+#endif
+
+// Standard Library Includes
+#include <stdio.h>
+
+//==================================================================================================
+// CAPThread
+//==================================================================================================
+
+// returns the thread's priority as it was last set by the API
+#define CAPTHREAD_SET_PRIORITY 0
+// returns the thread's priority as it was last scheduled by the Kernel
+#define CAPTHREAD_SCHEDULED_PRIORITY 1
+
+//#define Log_SetPriority 1
+
+CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority, bool inFixedPriority, bool inAutoDelete, const char* inThreadName)
+:
+#if TARGET_OS_MAC
+ mPThread(0),
+ mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)),
+#elif TARGET_OS_WIN32
+ mThreadHandle(NULL),
+ mThreadID(0),
+#endif
+ mThreadRoutine(inThreadRoutine),
+ mThreadParameter(inParameter),
+ mPriority(inPriority),
+ mPeriod(0),
+ mComputation(0),
+ mConstraint(0),
+ mIsPreemptible(true),
+ mTimeConstraintSet(false),
+ mFixedPriority(inFixedPriority),
+ mAutoDelete(inAutoDelete)
+{
+ if(inThreadName != NULL)
+ {
+ strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
+ }
+ else
+ {
+ memset(mThreadName, 0, kMaxThreadNameLength);
+ }
+}
+
+CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible, bool inAutoDelete, const char* inThreadName)
+:
+#if TARGET_OS_MAC
+ mPThread(0),
+ mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)),
+#elif TARGET_OS_WIN32
+ mThreadHandle(NULL),
+ mThreadID(0),
+#endif
+ mThreadRoutine(inThreadRoutine),
+ mThreadParameter(inParameter),
+ mPriority(kDefaultThreadPriority),
+ mPeriod(inPeriod),
+ mComputation(inComputation),
+ mConstraint(inConstraint),
+ mIsPreemptible(inIsPreemptible),
+ mTimeConstraintSet(true),
+ mFixedPriority(false),
+ mAutoDelete(inAutoDelete)
+{
+ if(inThreadName != NULL)
+ {
+ strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
+ }
+ else
+ {
+ memset(mThreadName, 0, kMaxThreadNameLength);
+ }
+}
+
+CAPThread::~CAPThread()
+{
+}
+
+UInt32 CAPThread::GetScheduledPriority()
+{
+#if TARGET_OS_MAC
+ return CAPThread::getScheduledPriority( mPThread, CAPTHREAD_SCHEDULED_PRIORITY );
+#elif TARGET_OS_WIN32
+ UInt32 theAnswer = 0;
+ if(mThreadHandle != NULL)
+ {
+ theAnswer = GetThreadPriority(mThreadHandle);
+ }
+ return theAnswer;
+#endif
+}
+
+UInt32 CAPThread::GetScheduledPriority(NativeThread thread)
+{
+#if TARGET_OS_MAC
+ return getScheduledPriority( thread, CAPTHREAD_SCHEDULED_PRIORITY );
+#elif TARGET_OS_WIN32
+ return 0; // ???
+#endif
+}
+
+void CAPThread::SetPriority(UInt32 inPriority, bool inFixedPriority)
+{
+ mPriority = inPriority;
+ mTimeConstraintSet = false;
+ mFixedPriority = inFixedPriority;
+#if TARGET_OS_MAC
+ if(mPThread != 0)
+ {
+ SetPriority(mPThread, mPriority, mFixedPriority);
+ }
+#elif TARGET_OS_WIN32
+ if(mThreadID != NULL)
+ {
+ SetPriority(mThreadID, mPriority, mFixedPriority);
+ }
+#endif
+}
+
+void CAPThread::SetPriority(NativeThread inThread, UInt32 inPriority, bool inFixedPriority)
+{
+#if TARGET_OS_MAC
+ if(inThread != 0)
+ {
+ kern_return_t theError = 0;
+
+ // set whether or not this is a fixed priority thread
+ if (inFixedPriority)
+ {
+ thread_extended_policy_data_t theFixedPolicy = { false };
+ theError = thread_policy_set(pthread_mach_thread_np(inThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
+ AssertNoKernelError(theError, "CAPThread::SetPriority: failed to set the fixed-priority policy");
+ }
+
+ // set the thread's absolute priority which is relative to the priority on which thread_policy_set() is called
+ UInt32 theCurrentThreadPriority = getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY);
+ thread_precedence_policy_data_t thePrecedencePolicy = { static_cast<integer_t>(inPriority - theCurrentThreadPriority) };
+ theError = thread_policy_set(pthread_mach_thread_np(inThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
+ AssertNoKernelError(theError, "CAPThread::SetPriority: failed to set the precedence policy");
+
+ #if Log_SetPriority
+ DebugMessageN4("CAPThread::SetPriority: requsted: %lu spawning: %lu current: %lu assigned: %d", mPriority, mSpawningThreadPriority, theCurrentThreadPriority, thePrecedencePolicy.importance);
+ #endif
+ }
+#elif TARGET_OS_WIN32
+ if(inThread != NULL)
+ {
+ HANDLE hThread = OpenThread(NULL, FALSE, inThread);
+ if(hThread != NULL) {
+ SetThreadPriority(hThread, inPriority);
+ CloseHandle(hThread);
+ }
+ }
+#endif
+}
+
+void CAPThread::SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible)
+{
+ mPeriod = inPeriod;
+ mComputation = inComputation;
+ mConstraint = inConstraint;
+ mIsPreemptible = inIsPreemptible;
+ mTimeConstraintSet = true;
+#if TARGET_OS_MAC
+ if(mPThread != 0)
+ {
+ thread_time_constraint_policy_data_t thePolicy;
+ thePolicy.period = mPeriod;
+ thePolicy.computation = mComputation;
+ thePolicy.constraint = mConstraint;
+ thePolicy.preemptible = mIsPreemptible;
+ AssertNoError(thread_policy_set(pthread_mach_thread_np(mPThread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&thePolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT), "CAPThread::SetTimeConstraints: thread_policy_set failed");
+ }
+#elif TARGET_OS_WIN32
+ if(mThreadHandle != NULL)
+ {
+ SetThreadPriority(mThreadHandle, THREAD_PRIORITY_TIME_CRITICAL);
+ }
+#endif
+}
+
+void CAPThread::Start()
+{
+#if TARGET_OS_MAC
+ Assert(mPThread == 0, "CAPThread::Start: can't start because the thread is already running");
+ if(mPThread == 0)
+ {
+ OSStatus theResult;
+ pthread_attr_t theThreadAttributes;
+
+ theResult = pthread_attr_init(&theThreadAttributes);
+ ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: Thread attributes could not be created.");
+
+ theResult = pthread_attr_setdetachstate(&theThreadAttributes, PTHREAD_CREATE_DETACHED);
+ ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: A thread could not be created in the detached state.");
+
+ theResult = pthread_create(&mPThread, &theThreadAttributes, (ThreadRoutine)CAPThread::Entry, this);
+ ThrowIf(theResult != 0 || !mPThread, CAException(theResult), "CAPThread::Start: Could not create a thread.");
+
+ pthread_attr_destroy(&theThreadAttributes);
+
+ }
+#elif TARGET_OS_WIN32
+ Assert(mThreadID == 0, "CAPThread::Start: can't start because the thread is already running");
+ if(mThreadID == 0)
+ {
+ // clean up the existing thread handle
+ if(mThreadHandle != NULL)
+ {
+ CloseHandle(mThreadHandle);
+ mThreadHandle = NULL;
+ }
+
+ // create a new thread
+ mThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Entry, this, 0, &mThreadID);
+ ThrowIf(mThreadHandle == NULL, CAException(GetLastError()), "CAPThread::Start: Could not create a thread.");
+ }
+#endif
+}
+
+#if TARGET_OS_MAC
+
+void* CAPThread::Entry(CAPThread* inCAPThread)
+{
+ void* theAnswer = NULL;
+
+#if TARGET_OS_MAC
+ inCAPThread->mPThread = pthread_self();
+#elif TARGET_OS_WIN32
+ // do we need to do something here?
+#endif
+
+#if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+ if(inCAPThread->mThreadName[0] != 0)
+ {
+ pthread_setname_np(inCAPThread->mThreadName);
+ }
+#endif
+
+ try
+ {
+ if(inCAPThread->mTimeConstraintSet)
+ {
+ inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible);
+ }
+ else
+ {
+ inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority);
+ }
+
+ if(inCAPThread->mThreadRoutine != NULL)
+ {
+ theAnswer = inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter);
+ }
+ }
+ catch (...)
+ {
+ // what should be done here?
+ }
+ inCAPThread->mPThread = 0;
+ if (inCAPThread->mAutoDelete)
+ delete inCAPThread;
+ return theAnswer;
+}
+
+UInt32 CAPThread::getScheduledPriority(pthread_t inThread, int inPriorityKind)
+{
+ thread_basic_info_data_t threadInfo;
+ policy_info_data_t thePolicyInfo;
+ unsigned int count;
+
+ if (inThread == NULL)
+ return 0;
+
+ // get basic info
+ count = THREAD_BASIC_INFO_COUNT;
+ thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count);
+
+ switch (threadInfo.policy) {
+ case POLICY_TIMESHARE:
+ count = POLICY_TIMESHARE_INFO_COUNT;
+ thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count);
+ if (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) {
+ return static_cast<UInt32>(thePolicyInfo.ts.cur_priority);
+ }
+ return static_cast<UInt32>(thePolicyInfo.ts.base_priority);
+ break;
+
+ case POLICY_FIFO:
+ count = POLICY_FIFO_INFO_COUNT;
+ thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count);
+ if ( (thePolicyInfo.fifo.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) {
+ return static_cast<UInt32>(thePolicyInfo.fifo.depress_priority);
+ }
+ return static_cast<UInt32>(thePolicyInfo.fifo.base_priority);
+ break;
+
+ case POLICY_RR:
+ count = POLICY_RR_INFO_COUNT;
+ thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count);
+ if ( (thePolicyInfo.rr.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) {
+ return static_cast<UInt32>(thePolicyInfo.rr.depress_priority);
+ }
+ return static_cast<UInt32>(thePolicyInfo.rr.base_priority);
+ break;
+ }
+
+ return 0;
+}
+
+#elif TARGET_OS_WIN32
+
+UInt32 WINAPI CAPThread::Entry(CAPThread* inCAPThread)
+{
+ UInt32 theAnswer = 0;
+
+ try
+ {
+ if(inCAPThread->mTimeConstraintSet)
+ {
+ inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible);
+ }
+ else
+ {
+ inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority);
+ }
+
+ if(inCAPThread->mThreadRoutine != NULL)
+ {
+ theAnswer = reinterpret_cast<UInt32>(inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter));
+ }
+ inCAPThread->mThreadID = 0;
+ }
+ catch (...)
+ {
+ // what should be done here?
+ }
+ CloseHandle(inCAPThread->mThreadHandle);
+ inCAPThread->mThreadHandle = NULL;
+ if (inCAPThread->mAutoDelete)
+ delete inCAPThread;
+ return theAnswer;
+}
+
+extern "C"
+Boolean CompareAndSwap(UInt32 inOldValue, UInt32 inNewValue, UInt32* inOldValuePtr)
+{
+ return InterlockedCompareExchange((volatile LONG*)inOldValuePtr, inNewValue, inOldValue) == inOldValue;
+}
+
+#endif
+
+void CAPThread::SetName(const char* inThreadName)
+{
+ if(inThreadName != NULL)
+ {
+ strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
+ }
+ else
+ {
+ memset(mThreadName, 0, kMaxThreadNameLength);
+ }
+}
+
+#if CoreAudio_Debug
+void CAPThread::DebugPriority(const char *label)
+{
+#if !TARGET_OS_WIN32
+ if (mTimeConstraintSet)
+ printf("CAPThread::%s %p: pri=<time constraint>, spawning pri=%d, scheduled pri=%d\n", label, this,
+ (int)mSpawningThreadPriority, (mPThread != NULL) ? (int)GetScheduledPriority() : -1);
+ else
+ printf("CAPThread::%s %p: pri=%d%s, spawning pri=%d, scheduled pri=%d\n", label, this, (int)mPriority, mFixedPriority ? " fixed" : "",
+ (int)mSpawningThreadPriority, (mPThread != NULL) ? (int)GetScheduledPriority() : -1);
+#else
+ if (mTimeConstraintSet)
+ {
+ printf("CAPThread::%s %p: pri=<time constraint>, spawning pri=%d, scheduled pri=%d\n", label, this,
+ (int)mPriority, (mThreadHandle != NULL) ? (int)GetScheduledPriority() : -1);
+ }
+ else
+ {
+ printf("CAPThread::%s %p: pri=%d%s, spawning pri=%d, scheduled pri=%d\n", label, this, (int)mPriority, mFixedPriority ? " fixed" : "",
+ (int)mPriority, (mThreadHandle != NULL) ? (int)GetScheduledPriority() : -1);
+ }
+#endif
+}
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAPThread.h b/libs/appleutility/CoreAudio/PublicUtility/CAPThread.h
new file mode 100644
index 0000000000..41451252f8
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAPThread.h
@@ -0,0 +1,191 @@
+/*
+ File: CAPThread.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAPThread_h__)
+#define __CAPThread_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CFBase.h>
+#else
+ #include <CFBase.h>
+#endif
+
+#if TARGET_OS_MAC
+ #include <pthread.h>
+ #include <unistd.h>
+#elif TARGET_OS_WIN32
+ #include <windows.h>
+#else
+ #error Unsupported operating system
+#endif
+
+//==================================================================================================
+// CAPThread
+//
+// This class wraps a pthread and a Win32 thread.
+// caution: long-running fixed priority threads can make the system unresponsive
+//==================================================================================================
+
+class CAPThread
+{
+
+// Types
+public:
+ typedef void* (*ThreadRoutine)(void* inParameter);
+
+// Constants
+public:
+ enum
+ {
+#if TARGET_OS_MAC
+ kMinThreadPriority = 1,
+ kMaxThreadPriority = 63,
+ kDefaultThreadPriority = 31,
+ kMaxThreadNameLength = 64
+#elif TARGET_OS_WIN32
+ kMinThreadPriority = 1,
+ kMaxThreadPriority = 31,
+ kDefaultThreadPriority = THREAD_PRIORITY_NORMAL,
+ kMaxThreadNameLength = 256
+#endif
+ };
+
+// Construction/Destruction
+public:
+ CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority = kDefaultThreadPriority, bool inFixedPriority=false, bool inAutoDelete=false, const char* inThreadName = NULL);
+ CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible, bool inAutoDelete=false, const char* inThreadName = NULL);
+ virtual ~CAPThread();
+
+// Properties
+public:
+#if TARGET_OS_MAC
+ typedef pthread_t NativeThread;
+
+ NativeThread GetNativeThread() { return mPThread; }
+ static NativeThread GetCurrentThread() { return pthread_self(); }
+ static bool IsNativeThreadsEqual(NativeThread a, NativeThread b) { return (a==b); }
+
+ bool operator==(NativeThread b) { return pthread_equal(mPThread,b); }
+
+ pthread_t GetPThread() const { return mPThread; }
+ bool IsCurrentThread() const { return (0 != mPThread) && (pthread_self() == mPThread); }
+ bool IsRunning() const { return 0 != mPThread; }
+ static UInt32 getScheduledPriority(pthread_t inThread, int inPriorityKind);
+#elif TARGET_OS_WIN32
+ typedef unsigned long NativeThread;
+
+ NativeThread GetNativeThread() { return mThreadID; }
+ static NativeThread GetCurrentThread() { return GetCurrentThreadId(); }
+ static bool IsNativeThreadsEqual(NativeThread a, NativeThread b) { return (a==b); }
+
+ bool operator ==(NativeThread b) { return (mThreadID==b); }
+
+ HANDLE GetThreadHandle() const { return mThreadHandle; }
+ UInt32 GetThreadID() const { return mThreadID; }
+ bool IsCurrentThread() const { return (0 != mThreadID) && (GetCurrentThreadId() == mThreadID); }
+ bool IsRunning() const { return 0 != mThreadID; }
+#endif
+
+ bool IsTimeShareThread() const { return !mTimeConstraintSet; }
+ bool IsTimeConstraintThread() const { return mTimeConstraintSet; }
+
+ UInt32 GetPriority() const { return mPriority; }
+ UInt32 GetScheduledPriority();
+ static UInt32 GetScheduledPriority(NativeThread thread);
+ void SetPriority(UInt32 inPriority, bool inFixedPriority=false);
+ static void SetPriority(NativeThread inThread, UInt32 inPriority, bool inFixedPriority = false);
+
+ void GetTimeConstraints(UInt32& outPeriod, UInt32& outComputation, UInt32& outConstraint, bool& outIsPreemptible) const { outPeriod = mPeriod; outComputation = mComputation; outConstraint = mConstraint; outIsPreemptible = mIsPreemptible; }
+ void SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible);
+ void ClearTimeConstraints() { SetPriority(mPriority); }
+
+ bool WillAutoDelete() const { return mAutoDelete; }
+ void SetAutoDelete(bool b) { mAutoDelete = b; }
+
+ void SetName(const char* inThreadName);
+
+#if CoreAudio_Debug
+ void DebugPriority(const char *label);
+#endif
+
+// Actions
+public:
+ virtual void Start();
+
+// Implementation
+protected:
+#if TARGET_OS_MAC
+ static void* Entry(CAPThread* inCAPThread);
+#elif TARGET_OS_WIN32
+ static UInt32 WINAPI Entry(CAPThread* inCAPThread);
+#endif
+
+#if TARGET_OS_MAC
+ pthread_t mPThread;
+ UInt32 mSpawningThreadPriority;
+#elif TARGET_OS_WIN32
+ HANDLE mThreadHandle;
+ unsigned long mThreadID;
+#endif
+ ThreadRoutine mThreadRoutine;
+ void* mThreadParameter;
+ char mThreadName[kMaxThreadNameLength];
+ UInt32 mPriority;
+ UInt32 mPeriod;
+ UInt32 mComputation;
+ UInt32 mConstraint;
+ bool mIsPreemptible;
+ bool mTimeConstraintSet;
+ bool mFixedPriority;
+ bool mAutoDelete; // delete self when thread terminates
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAPersistence.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAPersistence.cpp
new file mode 100644
index 0000000000..d3fe008eeb
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAPersistence.cpp
@@ -0,0 +1,468 @@
+/*
+ File: CAPersistence.cpp
+ Abstract: CAPersistence.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CACFArray.h"
+#include "CACFDictionary.h"
+
+#include "CAAudioUnit.h"
+#include "CACFString.h"
+#include "CAAudioChannelLayout.h"
+#include "CAAUParameter.h"
+#include "CAAUMIDIMap.h"
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+#pragma mark __CAStreamBasicDescription
+
+static const CFStringRef kSampleRate = CFSTR("sample rate");
+static const CFStringRef kFormat = CFSTR("format");
+static const CFStringRef kFormatFlags = CFSTR("format flags");
+static const CFStringRef kPacketBytes = CFSTR("packet bytes");
+static const CFStringRef kFramePackets = CFSTR("frame packets");
+static const CFStringRef kFrameBytes = CFSTR("frame bytes");
+static const CFStringRef kFrameChannels = CFSTR("frame channels");
+static const CFStringRef kChannelBits = CFSTR("channel bits");
+
+ // This will return a value that should be used as the key for this struct
+ // and a CFData object that contains the current state of this object
+OSStatus CAStreamBasicDescription::Save (CFPropertyListRef *outData) const
+{
+ CACFDictionary dict(false);
+
+ if (!dict.AddFloat64 (kSampleRate, mSampleRate)) goto error;
+ if (!dict.AddUInt32 (kFormat, mFormatID)) goto error;
+ if (!dict.AddUInt32 (kFormatFlags, mFormatFlags)) goto error;
+ if (!dict.AddUInt32 (kPacketBytes, mBytesPerPacket)) goto error;
+ if (!dict.AddUInt32 (kFramePackets, mFramesPerPacket)) goto error;
+ if (!dict.AddUInt32 (kFrameBytes, mBytesPerFrame)) goto error;
+ if (!dict.AddUInt32 (kFrameChannels, mChannelsPerFrame)) goto error;
+ if (!dict.AddUInt32 (kChannelBits, mBitsPerChannel)) goto error;
+
+ *outData = dict.GetDict();
+
+ return noErr;
+
+error:
+ dict.ShouldRelease (true);
+ return paramErr;
+}
+
+
+ // Given a CFData object generated by the save command, this will re-establish
+ // the CAStreamBasicDescription
+OSStatus CAStreamBasicDescription::Restore (CFPropertyListRef& inData)
+{
+ if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
+ CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
+
+ if (!dict.GetFloat64 (kSampleRate, mSampleRate)) return paramErr;
+ if (!dict.GetUInt32 (kFormat, mFormatID)) return paramErr;
+ if (!dict.GetUInt32 (kFormatFlags, mFormatFlags)) return paramErr;
+ if (!dict.GetUInt32 (kPacketBytes, mBytesPerPacket)) return paramErr;
+ if (!dict.GetUInt32 (kFramePackets, mFramesPerPacket)) return paramErr;
+ if (!dict.GetUInt32 (kFrameBytes, mBytesPerFrame)) return paramErr;
+ if (!dict.GetUInt32 (kFrameChannels, mChannelsPerFrame)) return paramErr;
+ if (!dict.GetUInt32 (kChannelBits, mBitsPerChannel)) return paramErr;
+
+ return noErr;
+}
+
+#pragma mark __CAComponentDescription
+
+static const CFStringRef kType = CFSTR("type");
+static const CFStringRef kSubType = CFSTR("subtype");
+static const CFStringRef kManu = CFSTR("manufacturer");
+
+OSStatus CAComponentDescription::Save (CFPropertyListRef *outData) const
+{
+ CACFDictionary dict(false);
+ if (!dict.AddUInt32 (kType, componentType)) goto error;
+ if (!dict.AddUInt32 (kSubType, componentSubType)) goto error;
+ if (!dict.AddUInt32 (kManu, componentManufacturer)) goto error;
+
+ *outData = dict.GetDict();
+
+ return 0;
+error:
+ dict.ShouldRelease (true);
+ return paramErr;
+}
+
+OSStatus CAComponentDescription::Restore (CFPropertyListRef &inData)
+{
+ if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
+ CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
+
+ if (!dict.GetUInt32 (kType, componentType)) return paramErr;
+ if (!dict.GetUInt32 (kSubType, componentSubType)) return paramErr;
+ if (!dict.GetUInt32 (kManu, componentManufacturer)) return paramErr;
+
+ componentFlags = 0;
+ componentFlagsMask = 0;
+
+ return 0;
+}
+
+#pragma mark __CAComponent
+
+OSStatus CAComponent::Save (CFPropertyListRef *outData) const
+{
+ OSStatus result = mDesc.Save (outData);
+ if (result) return result;
+
+ //add the name string of the component for a human readable name...
+ // this name string is *not* restored when restoring the component
+ CFStringRef name = GetCompName ();
+ if (name && *outData)
+ CFDictionarySetValue ((CFMutableDictionaryRef)(*outData), CFSTR("name"), name);
+
+ return noErr;
+}
+
+OSStatus CAComponent::Restore (CFPropertyListRef &inData)
+{
+ if (mDesc.Restore (inData)) return paramErr;
+
+ Clear();
+
+ mComp = AudioComponentFindNext (NULL, &mDesc);
+ // this will restore the current flags...
+ if (mComp)
+ AudioComponentGetDescription (Comp(), &mDesc);
+
+ return noErr;
+}
+
+
+#pragma mark __CAAudioChannelLayout
+
+static const CFStringRef kACLTagKey = CFSTR("acl tag");
+static const CFStringRef kACLBitmapKey = CFSTR("chan bitmap");
+static const CFStringRef kACLLabelKey = CFSTR("label");
+static const CFStringRef kACLFlagsKey = CFSTR("flags");
+static const CFStringRef kACLCoords0Key = CFSTR("coords 0");
+static const CFStringRef kACLCoords1Key = CFSTR("coords 1");
+static const CFStringRef kACLCoords2Key = CFSTR("coords 2");
+static const CFStringRef kACLDescsKey = CFSTR("descriptions");
+
+OSStatus CAAudioChannelLayout::Save (CFPropertyListRef *outData) const
+{
+ const AudioChannelLayout& layout = Layout();
+
+ CACFDictionary dict (false);
+ if (!dict.AddUInt32 (kACLTagKey, layout.mChannelLayoutTag))
+ goto badadd;
+ if (layout.mChannelBitmap && !dict.AddUInt32 (kACLBitmapKey, layout.mChannelBitmap))
+ goto badadd;
+
+ if (layout.mNumberChannelDescriptions)
+ {
+ CFMutableArrayRef descs = CFArrayCreateMutable (NULL, layout.mNumberChannelDescriptions, &kCFTypeArrayCallBacks);
+
+ const AudioChannelDescription *desc = layout.mChannelDescriptions;
+ for (unsigned int i = 0; i < layout.mNumberChannelDescriptions; ++i, ++desc)
+ {
+ CACFDictionary descDict (true);
+ if (!descDict.AddUInt32 (kACLLabelKey, desc->mChannelLabel))
+ { CFRelease (descs); goto badadd; }
+ if (!descDict.AddUInt32 (kACLFlagsKey, desc->mChannelFlags))
+ { CFRelease (descs); goto badadd; }
+ if (!descDict.AddFloat32 (kACLCoords0Key, desc->mCoordinates[0]))
+ { CFRelease (descs); goto badadd; }
+ if (!descDict.AddFloat32 (kACLCoords1Key, desc->mCoordinates[1]))
+ { CFRelease (descs); goto badadd; }
+ if (!descDict.AddFloat32 (kACLCoords2Key, desc->mCoordinates[2]))
+ { CFRelease (descs); goto badadd; }
+
+ CFArrayAppendValue (descs, descDict.AsPropertyList());
+ }
+ dict.AddArray (kACLDescsKey, descs);
+
+ CFRelease (descs);
+ }
+
+ *outData = dict.GetDict();
+
+ return noErr;
+
+badadd:
+ dict.ShouldRelease(true);
+ return paramErr;
+}
+
+OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData)
+{
+ if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
+ CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
+
+ RefCountedLayout *temp = NULL;
+ AudioChannelLayout* layout;
+
+ CFArrayRef descs = NULL;
+ UInt32 numDescs = 0;
+
+ if (dict.GetArray (kACLDescsKey, descs)) {
+ numDescs = static_cast<OSStatus>(CFArrayGetCount (descs));
+ }
+
+ temp = RefCountedLayout::CreateWithNumberChannelDescriptions(numDescs);
+ layout = temp->GetLayout();
+
+ if (!dict.GetUInt32 (kACLTagKey, layout->mChannelLayoutTag))
+ goto badget;
+ if (dict.HasKey (kACLBitmapKey)) {
+ if (!dict.GetUInt32 (kACLBitmapKey, layout->mChannelBitmap))
+ goto badget;
+ } else
+ layout->mChannelBitmap = 0;
+
+ layout->mNumberChannelDescriptions = numDescs;
+
+ if (numDescs)
+ {
+ AudioChannelDescription *desc = layout->mChannelDescriptions;
+ for (unsigned int i = 0; i < numDescs; ++i, ++desc)
+ {
+ CFDictionaryRef descDict = (CFDictionaryRef)CFArrayGetValueAtIndex (descs, i);
+ CACFDictionary theDesc (descDict, false);
+
+ if (!theDesc.GetUInt32 (kACLLabelKey, desc->mChannelLabel))
+ goto badget;
+ if (!theDesc.GetUInt32 (kACLFlagsKey, desc->mChannelFlags))
+ goto badget;
+ if (!theDesc.GetFloat32 (kACLCoords0Key, desc->mCoordinates[0]))
+ goto badget;
+ if (!theDesc.GetFloat32 (kACLCoords1Key, desc->mCoordinates[1]))
+ goto badget;
+ if (!theDesc.GetFloat32 (kACLCoords2Key, desc->mCoordinates[2]))
+ goto badget;
+ }
+ }
+ if (mLayout)
+ mLayout->release();
+
+ mLayout = temp;
+
+ return noErr;
+
+badget:
+ delete temp;
+ return paramErr;
+}
+
+#pragma mark __AudioUnitParameter
+
+static const CFStringRef kAUScopeStr = CFSTR("scope");
+static const CFStringRef kAUElementIDStr = CFSTR("element ID");
+static const CFStringRef kAUParameterIDStr = CFSTR("paramID");
+
+void CAAUParameter::Save (CFPropertyListRef &outData) const
+{
+ return CAAUParameter::Save (*this, outData);
+}
+
+// static functions to save/restore AudioUnitParameter
+void CAAUParameter::Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData)
+{
+ CACFDictionary dict(false);
+ dict.AddUInt32 (kAUScopeStr, inParam.mScope);
+ dict.AddUInt32 (kAUElementIDStr, inParam.mElement);
+ dict.AddUInt32 (kAUParameterIDStr, inParam.mParameterID);
+
+ outData = dict.AsPropertyList();
+}
+
+OSStatus CAAUParameter::Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam)
+{
+ if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
+ CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
+
+ if (!dict.GetUInt32 (kAUScopeStr, outParam.mScope)) return paramErr;
+ if (!dict.GetUInt32 (kAUElementIDStr, outParam.mElement)) return paramErr;
+ if (!dict.GetUInt32 (kAUParameterIDStr, outParam.mParameterID)) return paramErr;
+ return noErr;
+}
+
+
+#pragma mark __MIDIMap
+
+const CFStringRef kParamMIDIStr = CFSTR("param maps");
+
+const CFStringRef kMIDIFlagsStr = CFSTR("flags");
+const CFStringRef kMIDISubMinStr = CFSTR("sub min");
+const CFStringRef kMIDISubMaxStr = CFSTR("sub max");
+const CFStringRef kMIDIStatusStr = CFSTR("midi status byte");
+const CFStringRef kMIDIDataByteStr = CFSTR("midi data1 byte");
+const CFStringRef kAUStr = CFSTR("unit");
+
+static const CFStringRef kLocalElementIDStr = CFSTR("element ID");
+static const CFStringRef kLocalScopeStr = CFSTR("scope");
+static const CFStringRef kLocalParameterIDStr = CFSTR("paramID");
+
+void CAAUMIDIMap::Save(CFPropertyListRef &outData) const
+{
+ CACFDictionary paramDict(false);
+
+ paramDict.AddUInt32 (kLocalScopeStr, mScope);
+ paramDict.AddUInt32 (kLocalElementIDStr, mElement);
+ paramDict.AddUInt32 (kLocalParameterIDStr, mParameterID);
+ paramDict.AddUInt32 (kMIDIFlagsStr, mFlags);
+ paramDict.AddFloat32 (kMIDISubMinStr, mSubRangeMin);
+ paramDict.AddFloat32 (kMIDISubMaxStr, mSubRangeMax);
+
+ UInt32 data = mStatus;
+ paramDict.AddUInt32 (kMIDIStatusStr, data);
+
+ data = mData1;
+ paramDict.AddUInt32 (kMIDIDataByteStr, data);
+
+ outData = paramDict.GetCFDictionary();
+}
+
+void CAAUMIDIMap::Restore(CFDictionaryRef inData)
+{
+ CACFDictionary paramDict (inData, false);
+
+ if (!paramDict.GetUInt32 (kLocalScopeStr, mScope)) return;
+ if (!paramDict.GetUInt32 (kLocalElementIDStr, mElement)) return;
+ if (!paramDict.GetUInt32 (kLocalParameterIDStr, mParameterID)) return;
+ if (!paramDict.GetUInt32 (kMIDIFlagsStr, mFlags)) return;
+ if (!paramDict.GetFloat32 (kMIDISubMinStr, mSubRangeMin)) return;
+ if (!paramDict.GetFloat32 (kMIDISubMaxStr, mSubRangeMax)) return;
+ UInt32 data;
+ if (!paramDict.GetUInt32 (kMIDIStatusStr, data)) return;
+ mStatus = data;
+ if (!paramDict.GetUInt32 (kMIDIDataByteStr, data)) return;
+ mData1 = data;
+}
+
+void CAAUMIDIMap::SaveAsMapPList (AudioUnit inUnit, const AUParameterMIDIMapping* inMappings, UInt32 inNumMappings, CFPropertyListRef &outData, CFStringRef inName)
+{
+
+ CACFDictionary mappingDict (false);
+ CACFArray maps (true);
+
+ for (UInt32 i = 0; i< inNumMappings; ++i)
+ {
+ CFPropertyListRef data;
+ CAAUMIDIMap paramMap(inMappings[i]);
+ paramMap.Save (data);
+ if (data)
+ {
+ maps.AppendCFType (data);
+ CFRelease(data);
+ }
+ }
+
+ if (maps.GetNumberItems()) {
+ mappingDict.AddCFType (kParamMIDIStr, maps.GetCFArray());
+
+ // Add the AU info here - where this map came from
+ CAAudioUnit au (inUnit);
+ CFPropertyListRef data;
+ au.Comp().Save (&data);
+
+ mappingDict.AddCFType (kAUStr, data);
+ CFRelease(data);
+
+ if (!inName) inName = CFSTR("Untitled");
+ mappingDict.AddString (CFSTR("name"), inName);
+
+ mappingDict.AddUInt32 (CFSTR("version"), 1);
+
+ outData = mappingDict.AsPropertyList();
+ } else {
+ mappingDict.ShouldRelease(true);
+ outData = NULL;
+ }
+}
+
+UInt32 CAAUMIDIMap::NumberOfMaps (const CFDictionaryRef inData)
+{
+ CACFDictionary dict (inData, false);
+
+ if (dict.HasKey (kParamMIDIStr))
+ {
+ CFArrayRef cfArray;
+ dict.GetArray (kParamMIDIStr, cfArray);
+
+ CACFArray array (cfArray, false);
+
+ return array.GetNumberItems();
+ }
+ return 0;
+}
+
+void CAAUMIDIMap::RestoreFromMapPList (const CFDictionaryRef inData, AUParameterMIDIMapping* outMappings, UInt32 inNumMappings)
+{
+
+ CACFDictionary dict (inData, false);
+
+ if (dict.HasKey (kParamMIDIStr))
+ {
+ CFArrayRef cfArray;
+ dict.GetArray (kParamMIDIStr, cfArray);
+
+ CACFArray array (cfArray, false);
+
+ UInt32 count = array.GetNumberItems();
+ if (count > inNumMappings)
+ count = inNumMappings;
+
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ CFDictionaryRef paramsDictRef;
+ if (!array.GetDictionary(i, paramsDictRef))
+ return;
+
+ CAAUMIDIMap parameterMap;
+ parameterMap.Restore(paramsDictRef);
+ outMappings[i] = parameterMap;
+ }
+ }
+}
+
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAProcess.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAProcess.cpp
new file mode 100644
index 0000000000..23ad2c0282
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAProcess.cpp
@@ -0,0 +1,92 @@
+/*
+ File: CAProcess.cpp
+ Abstract: CAProcess.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CAProcess.h"
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+//=============================================================================
+// CAProcess
+//=============================================================================
+
+bool CAProcess::ProcessExists(pid_t inPID)
+{
+ // pids <= 0 are reserved for special purposes and -1 is
+ // used as a sentinel value by the HAL.
+ bool theAnswer = inPID > 0;
+
+ if(theAnswer)
+ {
+ // according to kill(2), the process exists if kill(pid, 0) returns 0
+ int wasKilled = kill(inPID, 0);
+ if(wasKilled != 0)
+ {
+ // The kill call failed for some reason, but there is only one error code that
+ // that indicates that the process doesn't exist.
+ theAnswer = errno != ESRCH;
+ }
+ }
+
+
+ return theAnswer;
+}
+
+pid_t CAProcess::GetPID()
+{
+ if(sPID == -1)
+ {
+ sPID = getpid();
+ }
+
+ return sPID;
+}
+
+pid_t CAProcess::sPID = -1;
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAProcess.h b/libs/appleutility/CoreAudio/PublicUtility/CAProcess.h
new file mode 100644
index 0000000000..e512d911be
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAProcess.h
@@ -0,0 +1,75 @@
+/*
+ File: CAProcess.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAProcess_h__)
+#define __CAProcess_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include <sys/types.h>
+
+//=============================================================================
+// CAProcess
+//
+// Wrapper for utilities for dealing with Unix Processes.
+//=============================================================================
+
+class CAProcess
+{
+
+// operations
+public:
+ static bool ProcessExists(pid_t inPID);
+ static pid_t GetPID();
+
+private:
+ static pid_t sPID;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAPropertyAddress.h b/libs/appleutility/CoreAudio/PublicUtility/CAPropertyAddress.h
new file mode 100644
index 0000000000..6df444b0b4
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAPropertyAddress.h
@@ -0,0 +1,312 @@
+/*
+ File: CAPropertyAddress.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAPropertyAddress_h__)
+#define __CAPropertyAddress_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// PublicUtility Includes
+#include "CADebugMacros.h"
+
+// System Includes
+#include <CoreAudio/AudioHardware.h>
+
+// Standard Library Includes
+#include <algorithm>
+#include <functional>
+#include <vector>
+
+//==================================================================================================
+// CAPropertyAddress
+//
+// CAPropertyAddress extends the AudioObjectPropertyAddress structure to C++ including constructors
+// and other utility operations. Note that there is no defined operator< or operator== because the
+// presence of wildcards for the fields make comparisons ambiguous without specifying whether or
+// not to take the wildcards into account. Consequently, if you want to use this struct in an STL
+// data structure, you'll need to specify the approriate function object explicitly in the template
+// declaration.
+//==================================================================================================
+
+struct CAPropertyAddress
+:
+ public AudioObjectPropertyAddress
+{
+
+// Construction/Destruction
+public:
+ CAPropertyAddress() : AudioObjectPropertyAddress() { mSelector = 0; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
+ CAPropertyAddress(AudioObjectPropertySelector inSelector) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
+ CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = kAudioObjectPropertyElementMaster; }
+ CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = inElement; }
+ CAPropertyAddress(const AudioObjectPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
+ CAPropertyAddress(const CAPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
+ CAPropertyAddress& operator=(const AudioObjectPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
+ CAPropertyAddress& operator=(const CAPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
+
+// Operations
+public:
+ static bool IsSameAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return (inAddress1.mScope == inAddress2.mScope) && (inAddress1.mSelector == inAddress2.mSelector) && (inAddress1.mElement == inAddress2.mElement); }
+ static bool IsLessThanAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { bool theAnswer = false; if(inAddress1.mScope != inAddress2.mScope) { theAnswer = inAddress1.mScope < inAddress2.mScope; } else if(inAddress1.mSelector != inAddress2.mSelector) { theAnswer = inAddress1.mSelector < inAddress2.mSelector; } else { theAnswer = inAddress1.mElement < inAddress2.mElement; } return theAnswer; }
+ static bool IsCongruentSelector(AudioObjectPropertySelector inSelector1, AudioObjectPropertySelector inSelector2) { return (inSelector1 == inSelector2) || (inSelector1 == kAudioObjectPropertySelectorWildcard) || (inSelector2 == kAudioObjectPropertySelectorWildcard); }
+ static bool IsCongruentScope(AudioObjectPropertyScope inScope1, AudioObjectPropertyScope inScope2) { return (inScope1 == inScope2) || (inScope1 == kAudioObjectPropertyScopeWildcard) || (inScope2 == kAudioObjectPropertyScopeWildcard); }
+ static bool IsCongruentElement(AudioObjectPropertyElement inElement1, AudioObjectPropertyElement inElement2) { return (inElement1 == inElement2) || (inElement1 == kAudioObjectPropertyElementWildcard) || (inElement2 == kAudioObjectPropertyElementWildcard); }
+ static bool IsCongruentAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return IsCongruentScope(inAddress1.mScope, inAddress2.mScope) && IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector) && IsCongruentElement(inAddress1.mElement, inAddress2.mElement); }
+ static bool IsCongruentLessThanAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { bool theAnswer = false; if(!IsCongruentScope(inAddress1.mScope, inAddress2.mScope)) { theAnswer = inAddress1.mScope < inAddress2.mScope; } else if(!IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector)) { theAnswer = inAddress1.mSelector < inAddress2.mSelector; } else if(!IsCongruentElement(inAddress1.mElement, inAddress2.mElement)) { theAnswer = inAddress1.mElement < inAddress2.mElement; } return theAnswer; }
+
+// STL Helpers
+public:
+ struct EqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
+ {
+ bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsSameAddress(inAddress1, inAddress2); }
+ };
+
+ struct LessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
+ {
+ bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsLessThanAddress(inAddress1, inAddress2); }
+ };
+
+ struct CongruentEqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
+ {
+ bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentAddress(inAddress1, inAddress2); }
+ };
+
+ struct CongruentLessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
+ {
+ bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentLessThanAddress(inAddress1, inAddress2); }
+ };
+
+};
+
+//==================================================================================================
+// CAPropertyAddressList
+//
+// An auto-resizing array of CAPropertyAddress structures.
+//==================================================================================================
+
+class CAPropertyAddressList
+{
+
+// Construction/Destruction
+public:
+ CAPropertyAddressList() : mAddressList(), mToken(NULL) {}
+ explicit CAPropertyAddressList(void* inToken) : mAddressList(), mToken(inToken) {}
+ explicit CAPropertyAddressList(uintptr_t inToken) : mAddressList(), mToken(reinterpret_cast<void*>(inToken)) {}
+ CAPropertyAddressList(const CAPropertyAddressList& inAddressList) : mAddressList(inAddressList.mAddressList), mToken(inAddressList.mToken) {}
+ CAPropertyAddressList& operator=(const CAPropertyAddressList& inAddressList) { mAddressList = inAddressList.mAddressList; mToken = inAddressList.mToken; return *this; }
+ ~CAPropertyAddressList() {}
+
+// Operations
+public:
+ void* GetToken() const { return mToken; }
+ void SetToken(void* inToken) { mToken = inToken; }
+
+ uintptr_t GetIntToken() const { return reinterpret_cast<uintptr_t>(mToken); }
+ void SetIntToken(uintptr_t inToken) { mToken = reinterpret_cast<void*>(inToken); }
+
+ AudioObjectID GetAudioObjectIDToken() const { return static_cast<AudioObjectID>(reinterpret_cast<uintptr_t>(mToken)); }
+
+ bool IsEmpty() const { return mAddressList.empty(); }
+ UInt32 GetNumberItems() const { return ToUInt32(mAddressList.size()); }
+ void GetItemByIndex(UInt32 inIndex, AudioObjectPropertyAddress& outAddress) const { if(inIndex < mAddressList.size()) { outAddress = mAddressList.at(inIndex); } }
+ const AudioObjectPropertyAddress* GetItems() const { return &(*mAddressList.begin()); }
+ AudioObjectPropertyAddress* GetItems() { return &(*mAddressList.begin()); }
+
+ bool HasItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::CongruentEqualTo(), inAddress)); return theIterator != mAddressList.end(); }
+ bool HasExactItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); return theIterator != mAddressList.end(); }
+
+ void AppendItem(const AudioObjectPropertyAddress& inAddress) { mAddressList.push_back(inAddress); }
+ void AppendUniqueItem(const AudioObjectPropertyAddress& inAddress) { if(!HasItem(inAddress)) { mAddressList.push_back(inAddress); } }
+ void AppendUniqueExactItem(const AudioObjectPropertyAddress& inAddress) { if(!HasExactItem(inAddress)) { mAddressList.push_back(inAddress); } }
+ void InsertItemAtIndex(UInt32 inIndex, const AudioObjectPropertyAddress& inAddress) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.insert(theIterator, inAddress); } else { mAddressList.push_back(inAddress); } }
+ void EraseExactItem(const AudioObjectPropertyAddress& inAddress) { AddressList::iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); if(theIterator != mAddressList.end()) { mAddressList.erase(theIterator); } }
+ void EraseItemAtIndex(UInt32 inIndex) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.erase(theIterator); } }
+ void EraseAllItems() { mAddressList.clear(); }
+
+// Implementation
+private:
+ typedef std::vector<CAPropertyAddress> AddressList;
+
+ AddressList mAddressList;
+ void* mToken;
+
+};
+
+//==================================================================================================
+// CAPropertyAddressListVector
+//
+// An auto-resizing array of CAPropertyAddressList objects.
+//==================================================================================================
+
+class CAPropertyAddressListVector
+{
+
+// Construction/Destruction
+public:
+ CAPropertyAddressListVector() : mAddressListVector() {}
+ CAPropertyAddressListVector(const CAPropertyAddressListVector& inAddressListVector) : mAddressListVector(inAddressListVector.mAddressListVector) {}
+ CAPropertyAddressListVector& operator=(const CAPropertyAddressListVector& inAddressListVector) { mAddressListVector = inAddressListVector.mAddressListVector; return *this; }
+ ~CAPropertyAddressListVector() {}
+
+// Operations
+public:
+ bool IsEmpty() const { return mAddressListVector.empty(); }
+ bool HasAnyNonEmptyItems() const;
+ bool HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const;
+ bool HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const;
+
+ UInt32 GetNumberItems() const { return ToUInt32(mAddressListVector.size()); }
+ const CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) const { return mAddressListVector.at(inIndex); }
+ CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) { return mAddressListVector.at(inIndex); }
+ const CAPropertyAddressList* GetItemByToken(void* inToken) const;
+ CAPropertyAddressList* GetItemByToken(void* inToken);
+ const CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken) const;
+ CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken);
+
+ void AppendItem(const CAPropertyAddressList& inAddressList) { mAddressListVector.push_back(inAddressList); }
+ void EraseAllItems() { mAddressListVector.clear(); }
+
+// Implementation
+private:
+ typedef std::vector<CAPropertyAddressList> AddressListVector;
+
+ AddressListVector mAddressListVector;
+
+};
+
+inline bool CAPropertyAddressListVector::HasAnyNonEmptyItems() const
+{
+ bool theAnswer = false;
+ for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ theAnswer = !theIterator->IsEmpty();
+ }
+ return theAnswer;
+}
+
+inline bool CAPropertyAddressListVector::HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const
+{
+ bool theAnswer = false;
+ for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ theAnswer = theIterator->HasItem(inAddress);
+ }
+ return theAnswer;
+}
+
+inline bool CAPropertyAddressListVector::HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const
+{
+ bool theAnswer = false;
+ for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ theAnswer = theIterator->HasExactItem(inAddress);
+ }
+ return theAnswer;
+}
+
+inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken) const
+{
+ const CAPropertyAddressList* theAnswer = NULL;
+ bool wasFound = false;
+ for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ if(theIterator->GetToken() == inToken)
+ {
+ wasFound = true;
+ theAnswer = &(*theIterator);
+ }
+ }
+ return theAnswer;
+}
+
+inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken)
+{
+ CAPropertyAddressList* theAnswer = NULL;
+ bool wasFound = false;
+ for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ if(theIterator->GetToken() == inToken)
+ {
+ wasFound = true;
+ theAnswer = &(*theIterator);
+ }
+ }
+ return theAnswer;
+}
+
+inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken) const
+{
+ const CAPropertyAddressList* theAnswer = NULL;
+ bool wasFound = false;
+ for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ if(theIterator->GetIntToken() == inToken)
+ {
+ wasFound = true;
+ theAnswer = &(*theIterator);
+ }
+ }
+ return theAnswer;
+}
+
+inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken)
+{
+ CAPropertyAddressList* theAnswer = NULL;
+ bool wasFound = false;
+ for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
+ {
+ if(theIterator->GetIntToken() == inToken)
+ {
+ wasFound = true;
+ theAnswer = &(*theIterator);
+ }
+ }
+ return theAnswer;
+}
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAReferenceCounted.h b/libs/appleutility/CoreAudio/PublicUtility/CAReferenceCounted.h
new file mode 100644
index 0000000000..f00fc61675
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAReferenceCounted.h
@@ -0,0 +1,97 @@
+/*
+ File: CAReferenceCounted.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAReferenceCounted_h__
+#define __CAReferenceCounted_h__
+
+#include "CAAtomic.h"
+
+// base class for reference-counted objects
+class CAReferenceCounted {
+public:
+ CAReferenceCounted() : mRefCount(1) {}
+
+ void retain() { CAAtomicIncrement32(&mRefCount); }
+
+ void release()
+ {
+ SInt32 rc = CAAtomicDecrement32(&mRefCount);
+ if (rc == 0) {
+ releaseObject();
+ }
+ }
+
+
+ class Retainer {
+ public:
+ Retainer(CAReferenceCounted *obj) : mObject(obj) { mObject->retain(); }
+ ~Retainer() { mObject->release(); }
+
+ private:
+ CAReferenceCounted * mObject;
+ };
+
+protected:
+ virtual ~CAReferenceCounted() { }
+
+ virtual void releaseObject ()
+ {
+ delete this;
+ }
+
+#if DEBUG
+public:
+#endif
+ SInt32 GetReferenceCount() const { return mRefCount; }
+private:
+ SInt32 mRefCount;
+
+ CAReferenceCounted(const CAReferenceCounted &a);
+ CAReferenceCounted &operator=(const CAReferenceCounted &a);
+};
+
+
+#endif // __CAReferenceCounted_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.cpp b/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.cpp
new file mode 100644
index 0000000000..c78acd2c2d
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.cpp
@@ -0,0 +1,319 @@
+/*
+ File: CARingBuffer.cpp
+ Abstract: CARingBuffer.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CARingBuffer.h"
+#include "CABitOperations.h"
+#include "CAAutoDisposer.h"
+#include "CAAtomic.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <libkern/OSAtomic.h>
+
+CARingBuffer::CARingBuffer() :
+ mBuffers(NULL), mNumberChannels(0), mCapacityFrames(0), mCapacityBytes(0)
+{
+
+}
+
+CARingBuffer::~CARingBuffer()
+{
+ Deallocate();
+}
+
+
+void CARingBuffer::Allocate(int nChannels, UInt32 bytesPerFrame, UInt32 capacityFrames)
+{
+ Deallocate();
+
+ capacityFrames = NextPowerOfTwo(capacityFrames);
+
+ mNumberChannels = nChannels;
+ mBytesPerFrame = bytesPerFrame;
+ mCapacityFrames = capacityFrames;
+ mCapacityFramesMask = capacityFrames - 1;
+ mCapacityBytes = bytesPerFrame * capacityFrames;
+
+ // put everything in one memory allocation, first the pointers, then the deinterleaved channels
+ UInt32 allocSize = (mCapacityBytes + sizeof(Byte *)) * nChannels;
+ Byte *p = (Byte *)CA_malloc(allocSize);
+ memset(p, 0, allocSize);
+ mBuffers = (Byte **)p;
+ p += nChannels * sizeof(Byte *);
+ for (int i = 0; i < nChannels; ++i) {
+ mBuffers[i] = p;
+ p += mCapacityBytes;
+ }
+
+ for (UInt32 i = 0; i<kGeneralRingTimeBoundsQueueSize; ++i)
+ {
+ mTimeBoundsQueue[i].mStartTime = 0;
+ mTimeBoundsQueue[i].mEndTime = 0;
+ mTimeBoundsQueue[i].mUpdateCounter = 0;
+ }
+ mTimeBoundsQueuePtr = 0;
+}
+
+void CARingBuffer::Deallocate()
+{
+ if (mBuffers) {
+ free(mBuffers);
+ mBuffers = NULL;
+ }
+ mNumberChannels = 0;
+ mCapacityBytes = 0;
+ mCapacityFrames = 0;
+}
+
+inline void ZeroRange(Byte **buffers, int nchannels, int offset, int nbytes)
+{
+ while (--nchannels >= 0) {
+ memset(*buffers + offset, 0, nbytes);
+ ++buffers;
+ }
+}
+
+inline void StoreABL(Byte **buffers, int destOffset, const AudioBufferList *abl, int srcOffset, int nbytes)
+{
+ int nchannels = abl->mNumberBuffers;
+ const AudioBuffer *src = abl->mBuffers;
+ while (--nchannels >= 0) {
+ if (srcOffset > (int)src->mDataByteSize) continue;
+ memcpy(*buffers + destOffset, (Byte *)src->mData + srcOffset, std::min(nbytes, (int)src->mDataByteSize - srcOffset));
+ ++buffers;
+ ++src;
+ }
+}
+
+inline void FetchABL(AudioBufferList *abl, int destOffset, Byte **buffers, int srcOffset, int nbytes)
+{
+ int nchannels = abl->mNumberBuffers;
+ AudioBuffer *dest = abl->mBuffers;
+ while (--nchannels >= 0) {
+ if (destOffset > (int)dest->mDataByteSize) continue;
+ memcpy((Byte *)dest->mData + destOffset, *buffers + srcOffset, std::min(nbytes, (int)dest->mDataByteSize - destOffset));
+ ++buffers;
+ ++dest;
+ }
+}
+
+inline void ZeroABL(AudioBufferList *abl, int destOffset, int nbytes)
+{
+ int nBuffers = abl->mNumberBuffers;
+ AudioBuffer *dest = abl->mBuffers;
+ while (--nBuffers >= 0) {
+ if (destOffset > (int)dest->mDataByteSize) continue;
+ memset((Byte *)dest->mData + destOffset, 0, std::min(nbytes, (int)dest->mDataByteSize - destOffset));
+ ++dest;
+ }
+}
+
+
+CARingBufferError CARingBuffer::Store(const AudioBufferList *abl, UInt32 framesToWrite, SampleTime startWrite)
+{
+ if (framesToWrite == 0)
+ return kCARingBufferError_OK;
+
+ if (framesToWrite > mCapacityFrames)
+ return kCARingBufferError_TooMuch; // too big!
+
+ SampleTime endWrite = startWrite + framesToWrite;
+
+ if (startWrite < EndTime()) {
+ // going backwards, throw everything out
+ SetTimeBounds(startWrite, startWrite);
+ } else if (endWrite - StartTime() <= mCapacityFrames) {
+ // the buffer has not yet wrapped and will not need to
+ } else {
+ // advance the start time past the region we are about to overwrite
+ SampleTime newStart = endWrite - mCapacityFrames; // one buffer of time behind where we're writing
+ SampleTime newEnd = std::max(newStart, EndTime());
+ SetTimeBounds(newStart, newEnd);
+ }
+
+ // write the new frames
+ Byte **buffers = mBuffers;
+ int nchannels = mNumberChannels;
+ int offset0, offset1, nbytes;
+ SampleTime curEnd = EndTime();
+
+ if (startWrite > curEnd) {
+ // we are skipping some samples, so zero the range we are skipping
+ offset0 = FrameOffset(curEnd);
+ offset1 = FrameOffset(startWrite);
+ if (offset0 < offset1)
+ ZeroRange(buffers, nchannels, offset0, offset1 - offset0);
+ else {
+ ZeroRange(buffers, nchannels, offset0, mCapacityBytes - offset0);
+ ZeroRange(buffers, nchannels, 0, offset1);
+ }
+ offset0 = offset1;
+ } else {
+ offset0 = FrameOffset(startWrite);
+ }
+
+ offset1 = FrameOffset(endWrite);
+ if (offset0 < offset1)
+ StoreABL(buffers, offset0, abl, 0, offset1 - offset0);
+ else {
+ nbytes = mCapacityBytes - offset0;
+ StoreABL(buffers, offset0, abl, 0, nbytes);
+ StoreABL(buffers, 0, abl, nbytes, offset1);
+ }
+
+ // now update the end time
+ SetTimeBounds(StartTime(), endWrite);
+
+ return kCARingBufferError_OK; // success
+}
+
+void CARingBuffer::SetTimeBounds(SampleTime startTime, SampleTime endTime)
+{
+ UInt32 nextPtr = mTimeBoundsQueuePtr + 1;
+ UInt32 index = nextPtr & kGeneralRingTimeBoundsQueueMask;
+
+ mTimeBoundsQueue[index].mStartTime = startTime;
+ mTimeBoundsQueue[index].mEndTime = endTime;
+ mTimeBoundsQueue[index].mUpdateCounter = nextPtr;
+ CAAtomicCompareAndSwap32Barrier(mTimeBoundsQueuePtr, mTimeBoundsQueuePtr + 1, (SInt32*)&mTimeBoundsQueuePtr);
+}
+
+CARingBufferError CARingBuffer::GetTimeBounds(SampleTime &startTime, SampleTime &endTime)
+{
+ for (int i=0; i<8; ++i) // fail after a few tries.
+ {
+ UInt32 curPtr = mTimeBoundsQueuePtr;
+ UInt32 index = curPtr & kGeneralRingTimeBoundsQueueMask;
+ CARingBuffer::TimeBounds* bounds = mTimeBoundsQueue + index;
+
+ startTime = bounds->mStartTime;
+ endTime = bounds->mEndTime;
+ UInt32 newPtr = bounds->mUpdateCounter;
+
+ if (newPtr == curPtr)
+ return kCARingBufferError_OK;
+ }
+ return kCARingBufferError_CPUOverload;
+}
+
+CARingBufferError CARingBuffer::ClipTimeBounds(SampleTime& startRead, SampleTime& endRead)
+{
+ SampleTime startTime, endTime;
+
+ CARingBufferError err = GetTimeBounds(startTime, endTime);
+ if (err) return err;
+
+ if (startRead > endTime || endRead < startTime) {
+ endRead = startRead;
+ return kCARingBufferError_OK;
+ }
+
+ startRead = std::max(startRead, startTime);
+ endRead = std::min(endRead, endTime);
+ endRead = std::max(endRead, startRead);
+
+ return kCARingBufferError_OK; // success
+}
+
+CARingBufferError CARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead)
+{
+ if (nFrames == 0)
+ return kCARingBufferError_OK;
+
+ startRead = std::max(0LL, startRead);
+
+ SampleTime endRead = startRead + nFrames;
+
+ SampleTime startRead0 = startRead;
+ SampleTime endRead0 = endRead;
+
+ CARingBufferError err = ClipTimeBounds(startRead, endRead);
+ if (err) return err;
+
+ if (startRead == endRead) {
+ ZeroABL(abl, 0, nFrames * mBytesPerFrame);
+ return kCARingBufferError_OK;
+ }
+
+ SInt32 byteSize = (SInt32)((endRead - startRead) * mBytesPerFrame);
+
+ SInt32 destStartByteOffset = std::max((SInt32)0, (SInt32)((startRead - startRead0) * mBytesPerFrame));
+
+ if (destStartByteOffset > 0) {
+ ZeroABL(abl, 0, std::min((SInt32)(nFrames * mBytesPerFrame), destStartByteOffset));
+ }
+
+ SInt32 destEndSize = std::max((SInt32)0, (SInt32)(endRead0 - endRead));
+ if (destEndSize > 0) {
+ ZeroABL(abl, destStartByteOffset + byteSize, destEndSize * mBytesPerFrame);
+ }
+
+ Byte **buffers = mBuffers;
+ int offset0 = FrameOffset(startRead);
+ int offset1 = FrameOffset(endRead);
+ int nbytes;
+
+ if (offset0 < offset1) {
+ nbytes = offset1 - offset0;
+ FetchABL(abl, destStartByteOffset, buffers, offset0, nbytes);
+ } else {
+ nbytes = mCapacityBytes - offset0;
+ FetchABL(abl, destStartByteOffset, buffers, offset0, nbytes);
+ FetchABL(abl, destStartByteOffset + nbytes, buffers, 0, offset1);
+ nbytes += offset1;
+ }
+
+ int nchannels = abl->mNumberBuffers;
+ AudioBuffer *dest = abl->mBuffers;
+ while (--nchannels >= 0)
+ {
+ dest->mDataByteSize = nbytes;
+ dest++;
+ }
+
+ return noErr;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.h b/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.h
new file mode 100644
index 0000000000..9569e9a2a8
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CARingBuffer.h
@@ -0,0 +1,126 @@
+/*
+ File: CARingBuffer.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+
+#ifndef CARingBuffer_Header
+#define CARingBuffer_Header
+
+enum {
+ kCARingBufferError_OK = 0,
+ kCARingBufferError_TooMuch = 3, // fetch start time is earlier than buffer start time and fetch end time is later than buffer end time
+ kCARingBufferError_CPUOverload = 4 // the reader is unable to get enough CPU cycles to capture a consistent snapshot of the time bounds
+};
+
+typedef SInt32 CARingBufferError;
+
+const UInt32 kGeneralRingTimeBoundsQueueSize = 32;
+const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1;
+
+class CARingBuffer {
+public:
+ typedef SInt64 SampleTime;
+
+ CARingBuffer();
+ ~CARingBuffer();
+
+ void Allocate(int nChannels, UInt32 bytesPerFrame, UInt32 capacityFrames);
+ // capacityFrames will be rounded up to a power of 2
+ void Deallocate();
+
+ CARingBufferError Store(const AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
+ // Copy nFrames of data into the ring buffer at the specified sample time.
+ // The sample time should normally increase sequentially, though gaps
+ // are filled with zeroes. A sufficiently large gap effectively empties
+ // the buffer before storing the new data.
+
+ // If frameNumber is less than the previous frame number, the behavior is undefined.
+
+ // Return false for failure (buffer not large enough).
+
+ CARingBufferError Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
+ // will alter mNumDataBytes of the buffers
+
+ CARingBufferError GetTimeBounds(SampleTime &startTime, SampleTime &endTime);
+
+protected:
+
+ int FrameOffset(SampleTime frameNumber) { return (frameNumber & mCapacityFramesMask) * mBytesPerFrame; }
+
+ CARingBufferError ClipTimeBounds(SampleTime& startRead, SampleTime& endRead);
+
+ // these should only be called from Store.
+ SampleTime StartTime() const { return mTimeBoundsQueue[mTimeBoundsQueuePtr & kGeneralRingTimeBoundsQueueMask].mStartTime; }
+ SampleTime EndTime() const { return mTimeBoundsQueue[mTimeBoundsQueuePtr & kGeneralRingTimeBoundsQueueMask].mEndTime; }
+ void SetTimeBounds(SampleTime startTime, SampleTime endTime);
+
+protected:
+ Byte ** mBuffers; // allocated in one chunk of memory
+ int mNumberChannels;
+ UInt32 mBytesPerFrame; // within one deinterleaved channel
+ UInt32 mCapacityFrames; // per channel, must be a power of 2
+ UInt32 mCapacityFramesMask;
+ UInt32 mCapacityBytes; // per channel
+
+ // range of valid sample time in the buffer
+ typedef struct {
+ volatile SampleTime mStartTime;
+ volatile SampleTime mEndTime;
+ volatile UInt32 mUpdateCounter;
+ } TimeBounds;
+
+ CARingBuffer::TimeBounds mTimeBoundsQueue[kGeneralRingTimeBoundsQueueSize];
+ UInt32 mTimeBoundsQueuePtr;
+};
+
+
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.cpp b/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.cpp
new file mode 100644
index 0000000000..69bdffcb72
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.cpp
@@ -0,0 +1,737 @@
+/*
+ File: CASettingsStorage.cpp
+ Abstract: CASettingsStorage.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CASettingsStorage.h"
+
+// PublicUtility Includes
+#include "CAAutoDisposer.h"
+#include "CACFArray.h"
+#include "CACFData.h"
+#include "CACFDictionary.h"
+#include "CACFDistributedNotification.h"
+#include "CACFNumber.h"
+
+// Stamdard Library Includes
+#include <string.h>
+#include <sys/fcntl.h>
+
+//==================================================================================================
+// CASettingsStorage
+//==================================================================================================
+
+CASettingsStorage::CASettingsStorage(const char* inSettingsFilePath, mode_t inSettingsFileAccessMode, CFPropertyListFormat inSettingsCacheFormat, bool inIsSingleProcessOnly, bool inIsReadOnly)
+:
+ mSettingsFilePath(NULL),
+ mSettingsFileAccessMode(inSettingsFileAccessMode),
+ mSettingsCache(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)),
+ mSettingsCacheFormat(inSettingsCacheFormat),
+ mSettingsCacheTime(),
+ mSettingsCacheForceRefresh(true),
+ mIsSingleProcessOnly(inIsSingleProcessOnly),
+ mIsReadOnly(inIsReadOnly)
+{
+ size_t theLength = strlen(inSettingsFilePath);
+ mSettingsFilePath = new char[theLength + 2];
+ strlcpy(mSettingsFilePath, inSettingsFilePath, theLength + 2);
+
+ mSettingsCacheTime.tv_sec = 0;
+ mSettingsCacheTime.tv_nsec = 0;
+
+ mSettingsCacheForceRefresh = true;
+}
+
+CASettingsStorage::~CASettingsStorage()
+{
+ delete[] mSettingsFilePath;
+
+ if(mSettingsCache != NULL)
+ {
+ CFRelease(mSettingsCache);
+ }
+}
+
+UInt32 CASettingsStorage::GetNumberKeys() const
+{
+ // make sure our cache is up to date
+ const_cast<CASettingsStorage*>(this)->RefreshSettings();
+
+ return ToUInt32(CFDictionaryGetCount(mSettingsCache));
+}
+
+void CASettingsStorage::GetKeys(UInt32 inNumberKeys, UInt32& outNumberKeys, CFStringRef* outKeys) const
+{
+ // make sure our cache is up to date
+ const_cast<CASettingsStorage*>(this)->RefreshSettings();
+
+ CFDictionaryGetKeysAndValues(mSettingsCache, reinterpret_cast<const void**>(outKeys), NULL);
+ outNumberKeys = inNumberKeys;
+}
+
+void CASettingsStorage::CopyBoolValue(CFStringRef inKey, bool& outValue, bool inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // bools can be made from either CFBooleans or CFNumbers
+ if(CFGetTypeID(theValue) == CFBooleanGetTypeID())
+ {
+ // get the return value from the CF object
+ outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
+ }
+ else if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the numeric value
+ SInt32 theNumericValue = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
+
+ // non-zero indicates true
+ outValue = theNumericValue != 0;
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopySInt32Value(CFStringRef inKey, SInt32& outValue, SInt32 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopyUInt32Value(CFStringRef inKey, UInt32& outValue, UInt32 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopySInt64Value(CFStringRef inKey, SInt64& outValue, SInt64 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopyUInt64Value(CFStringRef inKey, UInt64& outValue, UInt64 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopyFloat32Value(CFStringRef inKey, Float32& outValue, Float32 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopyFloat64Value(CFStringRef inKey, Float64& outValue, Float64 inDefaultValue) const
+{
+ // initialize the return value
+ outValue = inDefaultValue;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, NULL);
+
+ // for this type, NULL is an invalid value
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // get the return value from the CF object
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
+ }
+
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+ }
+}
+
+void CASettingsStorage::CopyNumberValue(CFStringRef inKey, CFNumberRef& outValue, CFNumberRef inDefaultValue) const
+{
+ // initialize the return value
+ outValue = NULL;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, inDefaultValue);
+
+ // for this type, NULL is a valid value, but requires less work
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFNumberGetTypeID())
+ {
+ // set the return value to the CF object we are returning
+ outValue = static_cast<CFNumberRef>(theValue);
+ }
+ else
+ {
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+
+ // set the return value to the default value
+ outValue = inDefaultValue;
+
+ // and retain it
+ CFRetain(outValue);
+ }
+ }
+}
+
+void CASettingsStorage::CopyStringValue(CFStringRef inKey, CFStringRef& outValue, CFStringRef inDefaultValue) const
+{
+ // initialize the return value
+ outValue = NULL;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, inDefaultValue);
+
+ // for this type, NULL is a valid value, but requires less work
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFStringGetTypeID())
+ {
+ // set the return value to the CF object we are returning
+ outValue = static_cast<CFStringRef>(theValue);
+ }
+ else
+ {
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+
+ // set the return value to the default value
+ outValue = inDefaultValue;
+
+ // and retain it
+ CFRetain(outValue);
+ }
+ }
+}
+
+void CASettingsStorage::CopyArrayValue(CFStringRef inKey, CFArrayRef& outValue, CFArrayRef inDefaultValue) const
+{
+ // initialize the return value
+ outValue = NULL;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, inDefaultValue);
+
+ // for this type, NULL is a valid value, but requires less work
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFArrayGetTypeID())
+ {
+ // set the return value to the CF object we are returning
+ outValue = static_cast<CFArrayRef>(theValue);
+ }
+ else
+ {
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+
+ // set the return value to the default value
+ outValue = inDefaultValue;
+
+ // and retain it
+ CFRetain(outValue);
+ }
+ }
+}
+
+void CASettingsStorage::CopyDictionaryValue(CFStringRef inKey, CFDictionaryRef& outValue, CFDictionaryRef inDefaultValue) const
+{
+ // initialize the return value
+ outValue = NULL;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, inDefaultValue);
+
+ // for this type, NULL is a valid value, but requires less work
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFDictionaryGetTypeID())
+ {
+ // set the return value to the CF object we are returning
+ outValue = static_cast<CFDictionaryRef>(theValue);
+ }
+ else
+ {
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+
+ // set the return value to the default value
+ outValue = inDefaultValue;
+
+ // and retain it
+ CFRetain(outValue);
+ }
+ }
+}
+
+void CASettingsStorage::CopyDataValue(CFStringRef inKey, CFDataRef& outValue, CFDataRef inDefaultValue) const
+{
+ // initialize the return value
+ outValue = NULL;
+
+ // get the raw value
+ CFTypeRef theValue = NULL;
+ CopyCFTypeValue(inKey, theValue, inDefaultValue);
+
+ // for this type, NULL is a valid value, but requires less work
+ if(theValue != NULL)
+ {
+ // make sure we are dealing with the right kind of CF object
+ if(CFGetTypeID(theValue) == CFDataGetTypeID())
+ {
+ // set the return value to the CF object we are returning
+ outValue = static_cast<CFDataRef>(theValue);
+ }
+ else
+ {
+ // release the value since we aren't returning it
+ CFRelease(theValue);
+
+ // set the return value to the default value
+ outValue = inDefaultValue;
+
+ // and retain it
+ CFRetain(outValue);
+ }
+ }
+}
+
+void CASettingsStorage::CopyCFTypeValue(CFStringRef inKey, CFTypeRef& outValue, CFTypeRef inDefaultValue) const
+{
+ // make sure our cache is up to date
+ const_cast<CASettingsStorage*>(this)->RefreshSettings();
+
+ // check to see if we have a value for the given key
+ if(!CFDictionaryGetValueIfPresent(mSettingsCache, inKey, &outValue))
+ {
+ // the key wasn't in the cache, so return the default value
+ outValue = inDefaultValue;
+ }
+
+ // make sure we retain the return value
+ if(outValue != NULL)
+ {
+ CFRetain(outValue);
+ }
+}
+
+void CASettingsStorage::SetSInt32Value(CFStringRef inKey, SInt32 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetUInt32Value(CFStringRef inKey, UInt32 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetSInt64Value(CFStringRef inKey, SInt64 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetUInt64Value(CFStringRef inKey, UInt64 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetFloat32Value(CFStringRef inKey, Float32 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetFloat64Value(CFStringRef inKey, Float64 inValue)
+{
+ CACFNumber theValue(inValue);
+ SetCFTypeValue(inKey, theValue.GetCFNumber());
+}
+
+void CASettingsStorage::SetNumberValue(CFStringRef inKey, CFNumberRef inValue)
+{
+ SetCFTypeValue(inKey, inValue);
+}
+
+void CASettingsStorage::SetStringValue(CFStringRef inKey, CFStringRef inValue)
+{
+ SetCFTypeValue(inKey, inValue);
+}
+
+void CASettingsStorage::SetArrayValue(CFStringRef inKey, CFArrayRef inValue)
+{
+ SetCFTypeValue(inKey, inValue);
+}
+
+void CASettingsStorage::SetDictionaryValue(CFStringRef inKey, CFDictionaryRef inValue)
+{
+ SetCFTypeValue(inKey, inValue);
+}
+
+void CASettingsStorage::SetDataValue(CFStringRef inKey, CFDataRef inValue)
+{
+ SetCFTypeValue(inKey, inValue);
+}
+
+void CASettingsStorage::SetCFTypeValue(CFStringRef inKey, CFTypeRef inValue)
+{
+ // make sure our cache is up to date
+ RefreshSettings();
+
+ // add the new key/value to the dictionary
+ CFDictionarySetValue(mSettingsCache, inKey, inValue);
+
+ // write the settings to the file
+ SaveSettings();
+}
+
+void CASettingsStorage::RemoveValue(CFStringRef inKey)
+{
+ // make sure our cache is up to date
+ RefreshSettings();
+
+ // remove the given key
+ CFDictionaryRemoveValue(mSettingsCache, inKey);
+
+ // write the settings to the file
+ SaveSettings();
+}
+
+void CASettingsStorage::RemoveAllValues()
+{
+ // make sure our cache is up to date
+ RefreshSettings();
+
+ // remove the given key
+ CFDictionaryRemoveAllValues(mSettingsCache);
+
+ // write the settings to the file
+ SaveSettings();
+}
+
+void CASettingsStorage::SendNotification(CFStringRef inName, CFDictionaryRef inData, bool inPostToAllSessions) const
+{
+ CACFDistributedNotification::PostNotification(inName, inData, inPostToAllSessions);
+}
+
+void CASettingsStorage::ForceRefresh()
+{
+ mSettingsCacheForceRefresh = true;
+}
+
+inline bool operator<(const struct timespec& inX, const struct timespec& inY)
+{
+ return ((inX.tv_sec < inY.tv_sec) || ((inX.tv_sec == inY.tv_sec) && (inX.tv_nsec < inY.tv_nsec)));
+}
+
+void CASettingsStorage::RefreshSettings()
+{
+ // if this storage is only supporting a single process, there is no need to hit the disk unless
+ // required to by it being the first time or if the refresh is specifically forced for some reason
+ if(!mIsSingleProcessOnly || (mSettingsCache == NULL) || ((mSettingsCacheTime.tv_sec == 0) && (mSettingsCacheTime.tv_nsec == 0)) || mSettingsCacheForceRefresh)
+ {
+ // first, we need to stat the file to check the mod date, this has the side effect of also
+ // telling us if the file exisits
+ struct stat theFileInfo;
+ int theStatError = stat(mSettingsFilePath, &theFileInfo);
+
+ // we use this boolean to make error recovery easier since we need a case for when there's no file anyway
+ bool theSettingsWereCached = false;
+ bool theSettingsNeedSaving = true;
+
+ if(theStatError == 0)
+ {
+ // stat says there is something there, only have to do work if we either don't have a cache or the cache is out of date
+ if((mSettingsCache == NULL) || (mSettingsCacheTime < theFileInfo.st_mtimespec) || mSettingsCacheForceRefresh)
+ {
+ // open the file
+ FILE* theFile = fopen(mSettingsFilePath, "r");
+ if(theFile != NULL)
+ {
+ // lock the file (this call blocks until the lock is taken)
+ int theError = flock(fileno(theFile), LOCK_EX);
+ if(theError == 0)
+ {
+ // get the length of the file
+ fseek(theFile, 0, SEEK_END);
+ size_t theFileLength = static_cast<size_t>(ftell(theFile));
+ fseek(theFile, 0, SEEK_SET);
+
+ if(theFileLength > 0)
+ {
+ // allocate a block of memory to hold the data in the file
+ CAAutoFree<Byte> theRawFileData(theFileLength);
+
+ // read all the data in
+ fread(static_cast<Byte*>(theRawFileData), theFileLength, 1, theFile);
+
+ // release the lock
+ flock(fileno(theFile), LOCK_UN);
+
+ // put it into a CFData object
+ CACFData theRawFileDataCFData(static_cast<Byte*>(theRawFileData), static_cast<UInt32>(theFileLength));
+
+ // get rid of the existing cache
+ if(mSettingsCache != NULL)
+ {
+ CFRelease(mSettingsCache);
+ mSettingsCache = NULL;
+ }
+
+ // parse the data as a property list
+ mSettingsCache = (CFMutableDictionaryRef)CFPropertyListCreateWithData(NULL, theRawFileDataCFData.GetCFData(), kCFPropertyListMutableContainersAndLeaves, NULL, NULL);
+
+ // check to be sure we parsed a plist out of the file
+ if(mSettingsCache != NULL)
+ {
+ // save the date of the cache
+ mSettingsCacheTime = theFileInfo.st_mtimespec;
+
+ // mark that we're done
+ theSettingsWereCached = true;
+ theSettingsNeedSaving = false;
+ }
+ }
+ }
+
+ // close the file
+ fclose(theFile);
+ mSettingsCacheForceRefresh = false;
+ }
+ }
+ else
+ {
+ // nothing to do since the file was older than the cached data
+ theSettingsNeedSaving = false;
+ theSettingsWereCached = true;
+ }
+ }
+
+ // if there was a failure, we need to clean up
+ if((theStatError != 0) || theSettingsNeedSaving || !theSettingsWereCached)
+ {
+ // we get here if either there isn't a file or something wacky happenned while parsing it
+ // so, make sure we have a valid cache dictionary
+ if(mSettingsCache == NULL)
+ {
+ mSettingsCache = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ }
+
+ mSettingsCacheTime.tv_sec = 0;
+ mSettingsCacheTime.tv_nsec = 0;
+
+ if((theStatError != 0) || theSettingsNeedSaving)
+ {
+ SaveSettings();
+ }
+ }
+ }
+}
+
+void CASettingsStorage::SaveSettings()
+{
+ if(!mIsReadOnly && (mSettingsCache != NULL))
+ {
+ // make a CFData that contains the new settings
+ CACFData theNewRawPrefsCFData(CFPropertyListCreateData(NULL, mSettingsCache, mSettingsCacheFormat, 0, NULL), true);
+
+ // open the file for writing
+ FILE* theFile = fopen(mSettingsFilePath, "w+");
+ if(theFile != NULL)
+ {
+ // lock the file (this call blocks until the lock is taken)
+ int theError = flock(fileno(theFile), LOCK_EX);
+ if(theError == 0)
+ {
+ // set the file access mode if necessary
+ if(mSettingsFileAccessMode != 0)
+ {
+ fchmod(fileno(theFile), mSettingsFileAccessMode);
+ }
+
+ // write the data
+ fwrite(theNewRawPrefsCFData.GetDataPtr(), theNewRawPrefsCFData.GetSize(), 1, theFile);
+
+ // flush the file to be sure it is all on disk
+ fflush(theFile);
+
+ // release the lock
+ flock(fileno(theFile), LOCK_UN);
+
+ // close the file
+ fclose(theFile);
+
+ // stat the file to get the mod date
+ struct stat theFileInfo;
+ stat(mSettingsFilePath, &theFileInfo);
+
+ // save the mod date
+ mSettingsCacheTime = theFileInfo.st_mtimespec;
+ }
+ else
+ {
+ // close the file
+ fclose(theFile);
+ }
+ }
+ }
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.h b/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.h
new file mode 100644
index 0000000000..d15f87dd16
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASettingsStorage.h
@@ -0,0 +1,128 @@
+/*
+ File: CASettingsStorage.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CASettingsStorage_h__)
+#define __CASettingsStorage_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// System Includes
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+// Stamdard Library Includes
+#include <stdio.h>
+#include <sys/stat.h>
+
+//==================================================================================================
+// CASettingsStorage
+//==================================================================================================
+
+class CASettingsStorage
+{
+
+// Construction/Destruction
+public:
+ CASettingsStorage(const char* inSettingsFilePath, mode_t inSettingsFileAccessMode = 0, CFPropertyListFormat inSettingsCacheFormat = kCFPropertyListXMLFormat_v1_0, bool inIsSingleProcessOnly = false, bool inIsReadOnly = false);
+ ~CASettingsStorage();
+
+// Operations
+public:
+ UInt32 GetNumberKeys() const;
+ void GetKeys(UInt32 inNumberKeys, UInt32& outNumberKeys, CFStringRef* outKeys) const;
+
+ void CopyBoolValue(const CFStringRef inKey, bool& outValue, bool inDefaultValue = false) const;
+ void CopySInt32Value(const CFStringRef inKey, SInt32& outValue, SInt32 inDefaultValue = 0) const;
+ void CopyUInt32Value(const CFStringRef inKey, UInt32& outValue, UInt32 inDefaultValue = 0) const;
+ void CopySInt64Value(const CFStringRef inKey, SInt64& outValue, SInt64 inDefaultValue = 0) const;
+ void CopyUInt64Value(const CFStringRef inKey, UInt64& outValue, UInt64 inDefaultValue = 0) const;
+ void CopyFloat32Value(const CFStringRef inKey, Float32& outValue, Float32 inDefaultValue = 0) const;
+ void CopyFloat64Value(const CFStringRef inKey, Float64& outValue, Float64 inDefaultValue = 0) const;
+ void CopyNumberValue(const CFStringRef inKey, CFNumberRef& outValue, CFNumberRef inDefaultValue = NULL) const;
+ void CopyStringValue(const CFStringRef inKey, CFStringRef& outValue, CFStringRef inDefaultValue = NULL) const;
+ void CopyArrayValue(const CFStringRef inKey, CFArrayRef& outValue, CFArrayRef inDefaultValue = NULL) const;
+ void CopyDictionaryValue(const CFStringRef inKey, CFDictionaryRef& outValue, CFDictionaryRef inDefaultValue = NULL) const;
+ void CopyDataValue(const CFStringRef inKey, CFDataRef& outValue, CFDataRef inDefaultValue = NULL) const;
+ void CopyCFTypeValue(const CFStringRef inKey, CFTypeRef& outValue, CFTypeRef inDefaultValue = NULL) const;
+
+ void SetSInt32Value(const CFStringRef inKey, SInt32 inValue);
+ void SetUInt32Value(const CFStringRef inKey, UInt32 inValue);
+ void SetSInt64Value(const CFStringRef inKey, SInt64 inValue);
+ void SetUInt64Value(const CFStringRef inKey, UInt64 inValue);
+ void SetFloat32Value(const CFStringRef inKey, Float32 inValue);
+ void SetFloat64Value(const CFStringRef inKey, Float64 inValue);
+ void SetNumberValue(const CFStringRef inKey, const CFNumberRef inValue);
+ void SetStringValue(const CFStringRef inKey, const CFStringRef inValue);
+ void SetArrayValue(const CFStringRef inKey, const CFArrayRef inValue);
+ void SetDictionaryValue(const CFStringRef inKey, const CFDictionaryRef inValue);
+ void SetDataValue(const CFStringRef inKey, const CFDataRef inValue);
+ void SetCFTypeValue(const CFStringRef inKey, const CFTypeRef inValue);
+
+ void RemoveValue(const CFStringRef inKey);
+ void RemoveAllValues();
+
+ void SendNotification(const CFStringRef inName, CFDictionaryRef inData = NULL, bool inPostToAllSessions = true) const;
+ void ForceRefresh();
+
+// Implementation
+private:
+ void RefreshSettings();
+ void SaveSettings();
+
+ char* mSettingsFilePath;
+ mode_t mSettingsFileAccessMode;
+ CFMutableDictionaryRef mSettingsCache;
+ CFPropertyListFormat mSettingsCacheFormat;
+ struct timespec mSettingsCacheTime;
+ bool mSettingsCacheForceRefresh;
+ bool mIsSingleProcessOnly;
+ bool mIsReadOnly;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.cpp b/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.cpp
new file mode 100644
index 0000000000..0e39ac7e52
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.cpp
@@ -0,0 +1,118 @@
+/*
+ File: CASharedLibrary.cpp
+ Abstract: CASharedLibrary.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CASharedLibrary.h"
+
+//#define CASharedLibrary_Use_DYLD 1
+#if CASharedLibrary_Use_DYLD
+ #include <mach-o/dyld.h>
+#else
+ #include <dlfcn.h>
+ #include <stddef.h>
+#endif
+
+//=============================================================================
+// CASharedLibrary
+//=============================================================================
+
+void* CASharedLibrary::LoadLibraryAndGetRoutineAddress(const char* inRoutineName, const char* /*inLibraryName*/, const char* inLibraryPath)
+{
+ void* theRoutine = 0;
+
+#if CASharedLibrary_Use_DYLD
+ const struct mach_header* theImage = NSAddImage(inLibraryPath, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+ if(theImage != 0)
+ {
+ NSSymbol theSymbol = NSLookupSymbolInImage(theImage, inRoutineName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND);
+ if(theSymbol != 0)
+ {
+ theRoutine = NSAddressOfSymbol(theSymbol);
+ }
+ }
+#else
+ void* theImage = dlopen(inLibraryPath, RTLD_LAZY);
+ if(theImage != NULL)
+ {
+ // we assume that all routine names passed here have a leading underscore which gets shaved
+ // off when passed to dlsym
+ theRoutine = dlsym(theImage, &(inRoutineName[1]));
+ }
+
+#endif
+
+ return theRoutine;
+}
+
+void* CASharedLibrary::GetRoutineAddressIfLibraryLoaded(const char* inRoutineName, const char* /*inLibraryName*/, const char* inLibraryPath)
+{
+ void* theRoutine = 0;
+
+#if CASharedLibrary_Use_DYLD
+ const struct mach_header* theImage = NSAddImage(inLibraryPath, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED);
+ if(theImage != 0)
+ {
+ NSSymbol theSymbol = NSLookupSymbolInImage(theImage, inRoutineName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND);
+ if(theSymbol != 0)
+ {
+ theRoutine = NSAddressOfSymbol(theSymbol);
+ }
+ }
+#else
+ void* theImage = dlopen(inLibraryPath, RTLD_LAZY | RTLD_NOLOAD);
+ if(theImage != NULL)
+ {
+ // we assume that all routine names passed here have a leading underscore which gets shaved
+ // off when passed to dlsym
+ theRoutine = dlsym(theImage, &(inRoutineName[1]));
+ }
+#endif
+
+ return theRoutine;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.h b/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.h
new file mode 100644
index 0000000000..d02e70e356
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASharedLibrary.h
@@ -0,0 +1,64 @@
+/*
+ File: CASharedLibrary.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CASharedLibrary_h__)
+#define __CASharedLibrary_h__
+
+//=============================================================================
+// CASharedLibrary
+//=============================================================================
+
+class CASharedLibrary
+{
+
+// Symbol Operations
+public:
+ static void* LoadLibraryAndGetRoutineAddress(const char* inRoutineName, const char* inLibraryName, const char* inLibraryPath);
+ static void* GetRoutineAddressIfLibraryLoaded(const char* inRoutineName, const char* inLibraryName, const char* inLibraryPath);
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.cpp b/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.cpp
new file mode 100644
index 0000000000..ffb2da8a83
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.cpp
@@ -0,0 +1,376 @@
+/*
+ File: CASpectralProcessor.cpp
+ Abstract: CASpectralProcessor.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+
+//#include "AudioFormulas.h"
+#include "CASpectralProcessor.h"
+#include "CABitOperations.h"
+
+
+#include <Accelerate/Accelerate.h>
+
+
+#define OFFSETOF(class, field)((size_t)&((class*)0)->field)
+
+CASpectralProcessor::CASpectralProcessor(UInt32 inFFTSize, UInt32 inHopSize, UInt32 inNumChannels, UInt32 inMaxFrames)
+ : mFFTSize(inFFTSize), mHopSize(inHopSize), mNumChannels(inNumChannels), mMaxFrames(inMaxFrames),
+ mLog2FFTSize(Log2Ceil(mFFTSize)),
+ mFFTMask(mFFTSize - 1),
+ mFFTByteSize(mFFTSize * sizeof(Float32)),
+ mIOBufSize(NextPowerOfTwo(mFFTSize + mMaxFrames)),
+ mIOMask(mIOBufSize - 1),
+ mInputSize(0),
+ mInputPos(0), mOutputPos(-mFFTSize & mIOMask),
+ mInFFTPos(0), mOutFFTPos(0),
+ mSpectralFunction(0), mUserData(0)
+{
+ mWindow.alloc(mFFTSize, false);
+ SineWindow(); // set default window.
+
+ mChannels.alloc(mNumChannels);
+ mSpectralBufferList.allocBytes(OFFSETOF(SpectralBufferList, mDSPSplitComplex[mNumChannels]), true);
+ mSpectralBufferList->mNumberSpectra = mNumChannels;
+ for (UInt32 i = 0; i < mNumChannels; ++i)
+ {
+ mChannels[i].mInputBuf.alloc(mIOBufSize, true);
+ mChannels[i].mOutputBuf.alloc(mIOBufSize, true);
+ mChannels[i].mFFTBuf.alloc(mFFTSize, true);
+ mChannels[i].mSplitFFTBuf.alloc(mFFTSize, true);
+ mSpectralBufferList->mDSPSplitComplex[i].realp = mChannels[i].mSplitFFTBuf();
+ mSpectralBufferList->mDSPSplitComplex[i].imagp = mChannels[i].mSplitFFTBuf() + (mFFTSize >> 1);
+ }
+
+ mFFTSetup = vDSP_create_fftsetup (mLog2FFTSize, FFT_RADIX2);
+
+}
+
+CASpectralProcessor::~CASpectralProcessor()
+{
+ mWindow.free();
+ mChannels.free();
+ mSpectralBufferList.free();
+ vDSP_destroy_fftsetup(mFFTSetup);
+}
+
+void CASpectralProcessor::Reset()
+{
+ mInputPos = 0;
+ mOutputPos = -mFFTSize & mIOMask;
+ mInFFTPos = 0;
+ mOutFFTPos = 0;
+
+ for (UInt32 i = 0; i < mNumChannels; ++i)
+ {
+ memset(mChannels[i].mInputBuf(), 0, mIOBufSize * sizeof(Float32));
+ memset(mChannels[i].mOutputBuf(), 0, mIOBufSize * sizeof(Float32));
+ memset(mChannels[i].mFFTBuf(), 0, mFFTSize * sizeof(Float32));
+ }
+}
+
+const double two_pi = 2. * M_PI;
+
+void CASpectralProcessor::HanningWindow()
+{
+ // this is also vector optimized
+
+ double w = two_pi / (double)(mFFTSize - 1);
+ for (UInt32 i = 0; i < mFFTSize; ++i)
+ {
+ mWindow[i] = (0.5 - 0.5 * cos(w * (double)i));
+ }
+}
+
+void CASpectralProcessor::SineWindow()
+{
+ double w = M_PI / (double)(mFFTSize - 1);
+ for (UInt32 i = 0; i < mFFTSize; ++i)
+ {
+ mWindow[i] = sin(w * (double)i);
+ }
+}
+
+void CASpectralProcessor::Process(UInt32 inNumFrames, AudioBufferList* inInput, AudioBufferList* outOutput)
+{
+ // copy from buffer list to input buffer
+ CopyInput(inNumFrames, inInput);
+
+ // if enough input to process, then process.
+ while (mInputSize >= mFFTSize)
+ {
+ CopyInputToFFT(); // copy from input buffer to fft buffer
+ DoWindowing();
+ DoFwdFFT();
+ ProcessSpectrum(mFFTSize, mSpectralBufferList());
+ DoInvFFT();
+ DoWindowing();
+ OverlapAddOutput();
+ }
+
+ // copy from output buffer to buffer list
+ CopyOutput(inNumFrames, outOutput);
+}
+
+void CASpectralProcessor::DoWindowing()
+{
+ Float32 *win = mWindow();
+ if (!win) return;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ Float32 *x = mChannels[i].mFFTBuf();
+ vDSP_vmul(x, 1, win, 1, x, 1, mFFTSize);
+ }
+ //printf("DoWindowing %g %g\n", mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+}
+
+
+
+void CASpectralProcessor::CopyInput(UInt32 inNumFrames, AudioBufferList* inInput)
+{
+ UInt32 numBytes = inNumFrames * sizeof(Float32);
+ UInt32 firstPart = mIOBufSize - mInputPos;
+
+
+ if (firstPart < inNumFrames) {
+ UInt32 firstPartBytes = firstPart * sizeof(Float32);
+ UInt32 secondPartBytes = numBytes - firstPartBytes;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(mChannels[i].mInputBuf + mInputPos, inInput->mBuffers[i].mData, firstPartBytes);
+ memcpy(mChannels[i].mInputBuf, (UInt8*)inInput->mBuffers[i].mData + firstPartBytes, secondPartBytes);
+ }
+ } else {
+ UInt32 numBytes = inNumFrames * sizeof(Float32);
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(mChannels[i].mInputBuf + mInputPos, inInput->mBuffers[i].mData, numBytes);
+ }
+ }
+ //printf("CopyInput %g %g\n", mChannels[0].mInputBuf[mInputPos], mChannels[0].mInputBuf[(mInputPos + 200) & mIOMask]);
+ //printf("CopyInput mInputPos %u mIOBufSize %u\n", (unsigned)mInputPos, (unsigned)mIOBufSize);
+ mInputSize += inNumFrames;
+ mInputPos = (mInputPos + inNumFrames) & mIOMask;
+}
+
+void CASpectralProcessor::CopyOutput(UInt32 inNumFrames, AudioBufferList* outOutput)
+{
+ //printf("->CopyOutput %g %g\n", mChannels[0].mOutputBuf[mOutputPos], mChannels[0].mOutputBuf[(mOutputPos + 200) & mIOMask]);
+ //printf("CopyOutput mOutputPos %u\n", (unsigned)mOutputPos);
+ UInt32 numBytes = inNumFrames * sizeof(Float32);
+ UInt32 firstPart = mIOBufSize - mOutputPos;
+ if (firstPart < inNumFrames) {
+ UInt32 firstPartBytes = firstPart * sizeof(Float32);
+ UInt32 secondPartBytes = numBytes - firstPartBytes;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(outOutput->mBuffers[i].mData, mChannels[i].mOutputBuf + mOutputPos, firstPartBytes);
+ memcpy((UInt8*)outOutput->mBuffers[i].mData + firstPartBytes, mChannels[i].mOutputBuf, secondPartBytes);
+ memset(mChannels[i].mOutputBuf + mOutputPos, 0, firstPartBytes);
+ memset(mChannels[i].mOutputBuf, 0, secondPartBytes);
+ }
+ } else {
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(outOutput->mBuffers[i].mData, mChannels[i].mOutputBuf + mOutputPos, numBytes);
+ memset(mChannels[i].mOutputBuf + mOutputPos, 0, numBytes);
+ }
+ }
+ //printf("<-CopyOutput %g %g\n", ((Float32*)outOutput->mBuffers[0].mData)[0], ((Float32*)outOutput->mBuffers[0].mData)[200]);
+ mOutputPos = (mOutputPos + inNumFrames) & mIOMask;
+}
+
+void CASpectralProcessor::PrintSpectralBufferList()
+{
+ UInt32 half = mFFTSize >> 1;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ DSPSplitComplex &freqData = mSpectralBufferList->mDSPSplitComplex[i];
+
+ for (UInt32 j=0; j<half; j++){
+ printf(" bin[%d]: %lf + %lfi\n", (int) j, freqData.realp[j], freqData.imagp[j]);
+ }
+ }
+}
+
+
+void CASpectralProcessor::CopyInputToFFT()
+{
+ //printf("CopyInputToFFT mInFFTPos %u\n", (unsigned)mInFFTPos);
+ UInt32 firstPart = mIOBufSize - mInFFTPos;
+ UInt32 firstPartBytes = firstPart * sizeof(Float32);
+ if (firstPartBytes < mFFTByteSize) {
+ UInt32 secondPartBytes = mFFTByteSize - firstPartBytes;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(mChannels[i].mFFTBuf(), mChannels[i].mInputBuf() + mInFFTPos, firstPartBytes);
+ memcpy((UInt8*)mChannels[i].mFFTBuf() + firstPartBytes, mChannels[i].mInputBuf(), secondPartBytes);
+ }
+ } else {
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ memcpy(mChannels[i].mFFTBuf(), mChannels[i].mInputBuf() + mInFFTPos, mFFTByteSize);
+ }
+ }
+ mInputSize -= mHopSize;
+ mInFFTPos = (mInFFTPos + mHopSize) & mIOMask;
+ //printf("CopyInputToFFT %g %g\n", mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+}
+
+void CASpectralProcessor::OverlapAddOutput()
+{
+ //printf("OverlapAddOutput mOutFFTPos %u\n", (unsigned)mOutFFTPos);
+ UInt32 firstPart = mIOBufSize - mOutFFTPos;
+ if (firstPart < mFFTSize) {
+ UInt32 secondPart = mFFTSize - firstPart;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ float* out1 = mChannels[i].mOutputBuf() + mOutFFTPos;
+ vDSP_vadd(out1, 1, mChannels[i].mFFTBuf(), 1, out1, 1, firstPart);
+ float* out2 = mChannels[i].mOutputBuf();
+ vDSP_vadd(out2, 1, mChannels[i].mFFTBuf() + firstPart, 1, out2, 1, secondPart);
+ }
+ } else {
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ float* out1 = mChannels[i].mOutputBuf() + mOutFFTPos;
+ vDSP_vadd(out1, 1, mChannels[i].mFFTBuf(), 1, out1, 1, mFFTSize);
+ }
+ }
+ //printf("OverlapAddOutput %g %g\n", mChannels[0].mOutputBuf[mOutFFTPos], mChannels[0].mOutputBuf[(mOutFFTPos + 200) & mIOMask]);
+ mOutFFTPos = (mOutFFTPos + mHopSize) & mIOMask;
+}
+
+
+void CASpectralProcessor::DoFwdFFT()
+{
+ //printf("->DoFwdFFT %g %g\n", mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+ UInt32 half = mFFTSize >> 1;
+ for (UInt32 i=0; i<mNumChannels; ++i)
+ {
+ vDSP_ctoz((DSPComplex*)mChannels[i].mFFTBuf(), 2, &mSpectralBufferList->mDSPSplitComplex[i], 1, half);
+ vDSP_fft_zrip(mFFTSetup, &mSpectralBufferList->mDSPSplitComplex[i], 1, mLog2FFTSize, FFT_FORWARD);
+ }
+ //printf("<-DoFwdFFT %g %g\n", direction, mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+}
+
+void CASpectralProcessor::DoInvFFT()
+{
+ //printf("->DoInvFFT %g %g\n", mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+ UInt32 half = mFFTSize >> 1;
+ for (UInt32 i=0; i<mNumChannels; ++i)
+ {
+ vDSP_fft_zrip(mFFTSetup, &mSpectralBufferList->mDSPSplitComplex[i], 1, mLog2FFTSize, FFT_INVERSE);
+ vDSP_ztoc(&mSpectralBufferList->mDSPSplitComplex[i], 1, (DSPComplex*)mChannels[i].mFFTBuf(), 2, half);
+ float scale = 0.5 / mFFTSize;
+ vDSP_vsmul(mChannels[i].mFFTBuf(), 1, &scale, mChannels[i].mFFTBuf(), 1, mFFTSize );
+ }
+ //printf("<-DoInvFFT %g %g\n", direction, mChannels[0].mFFTBuf()[0], mChannels[0].mFFTBuf()[200]);
+}
+
+void CASpectralProcessor::SetSpectralFunction(SpectralFunction inFunction, void* inUserData)
+{
+ mSpectralFunction = inFunction;
+ mUserData = inUserData;
+}
+
+void CASpectralProcessor::ProcessSpectrum(UInt32 inFFTSize, SpectralBufferList* inSpectra)
+{
+ if (mSpectralFunction)
+ (mSpectralFunction)(inSpectra, mUserData);
+}
+
+#pragma mark ___Utility___
+
+void CASpectralProcessor::GetMagnitude(AudioBufferList* list, Float32* min, Float32* max)
+{
+ UInt32 half = mFFTSize >> 1;
+ for (UInt32 i=0; i<mNumChannels; ++i) {
+ DSPSplitComplex &freqData = mSpectralBufferList->mDSPSplitComplex[i];
+
+ Float32* b = (Float32*) list->mBuffers[i].mData;
+
+ vDSP_zvabs(&freqData,1,b,1,half);
+
+ vDSP_maxmgv(b, 1, &max[i], half);
+ vDSP_minmgv(b, 1, &min[i], half);
+
+ }
+}
+
+
+void CASpectralProcessor::GetFrequencies(Float32* freqs, Float32 sampleRate)
+{
+ UInt32 half = mFFTSize >> 1;
+
+ for (UInt32 i=0; i< half; i++){
+ freqs[i] = ((Float32)(i))*sampleRate/((Float32)mFFTSize);
+ }
+}
+
+
+bool CASpectralProcessor::ProcessForwards(UInt32 inNumFrames, AudioBufferList* inInput)
+{
+ // copy from buffer list to input buffer
+ CopyInput(inNumFrames, inInput);
+
+ bool processed = false;
+ // if enough input to process, then process.
+ while (mInputSize >= mFFTSize)
+ {
+ CopyInputToFFT(); // copy from input buffer to fft buffer
+ DoWindowing();
+ DoFwdFFT();
+ ProcessSpectrum(mFFTSize, mSpectralBufferList()); // here you would copy the fft results out to a buffer indicated in mUserData, say for sonogram drawing
+ processed = true;
+ }
+
+ return processed;
+}
+
+bool CASpectralProcessor::ProcessBackwards(UInt32 inNumFrames, AudioBufferList* outOutput)
+{
+
+ ProcessSpectrum(mFFTSize, mSpectralBufferList());
+ DoInvFFT();
+ DoWindowing();
+ OverlapAddOutput();
+
+ // copy from output buffer to buffer list
+ CopyOutput(inNumFrames, outOutput);
+
+ return true;
+}
+
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.h b/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.h
new file mode 100644
index 0000000000..d7c285b6a9
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CASpectralProcessor.h
@@ -0,0 +1,146 @@
+/*
+ File: CASpectralProcessor.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef _SpectralProcesor_H_
+#define _SpectralProcesor_H_
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreFoundation/CoreFoundation.h>
+#else
+#include <CoreAudioTypes.h>
+#include <CoreFoundation.h>
+#endif
+
+#include <Accelerate/Accelerate.h>
+
+#include "CAAutoDisposer.h"
+
+struct SpectralBufferList
+{
+ UInt32 mNumberSpectra;
+ DSPSplitComplex mDSPSplitComplex[1];
+};
+
+class CASpectralProcessor
+{
+public:
+ CASpectralProcessor(UInt32 inFFTSize, UInt32 inHopSize, UInt32 inNumChannels, UInt32 inMaxFrames);
+ virtual ~CASpectralProcessor();
+
+ void Reset();
+
+ void Process(UInt32 inNumFrames, AudioBufferList* inInput, AudioBufferList* outOutput);
+
+ typedef void (*SpectralFunction)(SpectralBufferList* inSpectra, void* inUserData);
+
+ void SetSpectralFunction(SpectralFunction inFunction, void* inUserData);
+
+ UInt32 FFTSize() const { return mFFTSize; }
+ UInt32 MaxFrames() const { return mMaxFrames; }
+ UInt32 NumChannels() const { return mNumChannels; }
+ UInt32 HopSize() const { return mHopSize; }
+ Float32* Window() const { return mWindow; }
+
+
+ void HanningWindow(); // set up a hanning window
+ void SineWindow();
+
+ void GetFrequencies(Float32* freqs, Float32 sampleRate); // only for processed forward
+ void GetMagnitude(AudioBufferList* inCopy, Float32* min, Float32* max); // only for processed forward
+
+ virtual bool ProcessForwards(UInt32 inNumFrames, AudioBufferList* inInput);
+ bool ProcessBackwards(UInt32 inNumFrames, AudioBufferList* outOutput);
+
+
+ void PrintSpectralBufferList();
+
+protected:
+ void CopyInput(UInt32 inNumFrames, AudioBufferList* inInput);
+ void CopyInputToFFT();
+ void DoWindowing();
+ void DoFwdFFT();
+ void DoInvFFT();
+ void OverlapAddOutput();
+ void CopyOutput(UInt32 inNumFrames, AudioBufferList* inOutput);
+ void ProcessSpectrum(UInt32 inFFTSize, SpectralBufferList* inSpectra);
+
+ UInt32 mFFTSize;
+ UInt32 mHopSize;
+ UInt32 mNumChannels;
+ UInt32 mMaxFrames;
+
+ UInt32 mLog2FFTSize;
+ UInt32 mFFTMask;
+ UInt32 mFFTByteSize;
+ UInt32 mIOBufSize;
+ UInt32 mIOMask;
+ UInt32 mInputSize;
+ UInt32 mInputPos;
+ UInt32 mOutputPos;
+ UInt32 mInFFTPos;
+ UInt32 mOutFFTPos;
+ FFTSetup mFFTSetup;
+
+ CAAutoFree<Float32> mWindow;
+ struct SpectralChannel
+ {
+ CAAutoFree<Float32> mInputBuf; // log2ceil(FFT size + max frames)
+ CAAutoFree<Float32> mOutputBuf; // log2ceil(FFT size + max frames)
+ CAAutoFree<Float32> mFFTBuf; // FFT size
+ CAAutoFree<Float32> mSplitFFTBuf; // FFT size
+ };
+ CAAutoArrayDelete<SpectralChannel> mChannels;
+
+ CAAutoFree<SpectralBufferList> mSpectralBufferList;
+
+ SpectralFunction mSpectralFunction;
+ void *mUserData;
+
+};
+
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp
new file mode 100644
index 0000000000..d56947ab59
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp
@@ -0,0 +1,879 @@
+/*
+ File: CAStreamBasicDescription.cpp
+ Abstract: CAStreamBasicDescription.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAStreamBasicDescription.h"
+#include "CAMath.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CFByteOrder.h>
+#else
+ #include <CFByteOrder.h>
+#endif
+
+#pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it
+
+char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize)
+{
+ if (bufsize > 0) {
+ char *p = writeLocation, *pend = writeLocation + bufsize;
+ union { UInt32 i; unsigned char str[4]; } u;
+ unsigned char *q = u.str;
+ u.i = CFSwapInt32HostToBig(t);
+
+ bool hasNonPrint = false;
+ for (int i = 0; i < 4; ++i) {
+ if (!(isprint(*q) && *q != '\\')) {
+ hasNonPrint = true;
+ break;
+ }
+ q++;
+ }
+ q = u.str;
+
+ if (hasNonPrint)
+ p += snprintf (p, pend - p, "0x");
+ else if (p < pend)
+ *p++ = '\'';
+
+ for (int i = 0; i < 4 && p < pend; ++i) {
+ if (hasNonPrint) {
+ p += snprintf(p, pend - p, "%02X", *q++);
+ } else {
+ *p++ = *q++;
+ }
+ }
+ if (!hasNonPrint && p < pend)
+ *p++ = '\'';
+ if (p >= pend) p -= 1;
+ *p = '\0';
+ }
+ return writeLocation;
+}
+
+
+const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+CAStreamBasicDescription::CAStreamBasicDescription()
+{
+ memset (this, 0, sizeof(AudioStreamBasicDescription));
+}
+
+CAStreamBasicDescription::CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
+{
+ SetFrom(desc);
+}
+
+
+CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID,
+ UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
+ UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
+ UInt32 inBitsPerChannel, UInt32 inFormatFlags)
+{
+ mSampleRate = inSampleRate;
+ mFormatID = inFormatID;
+ mBytesPerPacket = inBytesPerPacket;
+ mFramesPerPacket = inFramesPerPacket;
+ mBytesPerFrame = inBytesPerFrame;
+ mChannelsPerFrame = inChannelsPerFrame;
+ mBitsPerChannel = inBitsPerChannel;
+ mFormatFlags = inFormatFlags;
+ mReserved = 0;
+}
+
+char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize, bool brief /*=false*/) const
+{
+ int bufsize = (int)_bufsize; // must be signed to protect against overflow
+ char *theBuffer = buf;
+ int nc;
+ char formatID[24];
+ CAStringForOSType(mFormatID, formatID, sizeof(formatID));
+ if (brief) {
+ CommonPCMFormat com;
+ bool interleaved;
+ if (IdentifyCommonPCMFormat(com, &interleaved) && com != kPCMFormatOther) {
+ const char *desc;
+ switch (com) {
+ case kPCMFormatInt16:
+ desc = "Int16";
+ break;
+ case kPCMFormatFixed824:
+ desc = "Int8.24";
+ break;
+ case kPCMFormatFloat32:
+ desc = "Float32";
+ break;
+ case kPCMFormatFloat64:
+ desc = "Float64";
+ break;
+ default:
+ desc = NULL;
+ break;
+ }
+ if (desc) {
+ const char *inter ="";
+ if (mChannelsPerFrame > 1)
+ inter = !interleaved ? ", non-inter" : ", inter";
+ snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s%s", (int)mChannelsPerFrame, mSampleRate, desc, inter);
+ return theBuffer;
+ }
+ }
+ if (mChannelsPerFrame == 0 && mSampleRate == 0.0 && mFormatID == 0) {
+ snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz", (int)mChannelsPerFrame, mSampleRate);
+ return theBuffer;
+ }
+ }
+
+ nc = snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags);
+ buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+ if (mFormatID == kAudioFormatLinearPCM) {
+ bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
+ int wordSize = static_cast<int>(SampleWordSize());
+ const char *endian = (wordSize > 1) ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
+ const char *sign = isInt ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
+ const char *floatInt = isInt ? "integer" : "float";
+ char packed[32];
+ if (wordSize > 0 && PackednessIsSignificant()) {
+ if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
+ snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize);
+ else
+ snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize);
+ } else
+ packed[0] = '\0';
+ const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
+ const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
+ const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
+ char bitdepth[20];
+
+ int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+ if (fracbits > 0)
+ snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits);
+ else
+ snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel);
+
+ /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%s-bit%s%s %s%s%s%s%s",
+ bitdepth, endian, sign, floatInt,
+ commaSpace, packed, align, deinter);
+ // buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+ } else if (mFormatID == kAudioFormatAppleLossless) {
+ int sourceBits = 0;
+ switch (mFormatFlags)
+ {
+ case 1: // kAppleLosslessFormatFlag_16BitSourceData
+ sourceBits = 16;
+ break;
+ case 2: // kAppleLosslessFormatFlag_20BitSourceData
+ sourceBits = 20;
+ break;
+ case 3: // kAppleLosslessFormatFlag_24BitSourceData
+ sourceBits = 24;
+ break;
+ case 4: // kAppleLosslessFormatFlag_32BitSourceData
+ sourceBits = 32;
+ break;
+ }
+ if (sourceBits)
+ nc = snprintf(buf, static_cast<size_t>(bufsize), "from %d-bit source, ", sourceBits);
+ else
+ nc = snprintf(buf, static_cast<size_t>(bufsize), "from UNKNOWN source bit depth, ");
+ buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+ /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%d frames/packet", (int)mFramesPerPacket);
+ // buf += nc; if ((bufsize -= nc) <= 0) goto exit;
+ }
+ else
+ /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame",
+ (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame);
+exit:
+ return theBuffer;
+}
+
+void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
+{
+ // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
+ if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ // the canonical linear PCM format
+ ioDescription.mFormatFlags = kAudioFormatFlagsCanonical;
+ ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+ ioDescription.mFramesPerPacket = 1;
+ ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+ ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
+ }
+}
+
+void CAStreamBasicDescription::NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription)
+{
+ // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
+ if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ // the canonical linear PCM format
+ ioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
+ if(inNativeEndian)
+ {
+#if TARGET_RT_BIG_ENDIAN
+ ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+ }
+ else
+ {
+#if TARGET_RT_LITTLE_ENDIAN
+ ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+ }
+ ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+ ioDescription.mFramesPerPacket = 1;
+ ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame;
+ ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType);
+ }
+}
+
+void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
+{
+ ioDescription.mSampleRate = 0;
+ ioDescription.mFormatID = 0;
+ ioDescription.mBytesPerPacket = 0;
+ ioDescription.mFramesPerPacket = 0;
+ ioDescription.mBytesPerFrame = 0;
+ ioDescription.mChannelsPerFrame = 0;
+ ioDescription.mBitsPerChannel = 0;
+ ioDescription.mFormatFlags = 0;
+}
+
+void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
+{
+ if(fiszero(ioDescription.mSampleRate))
+ {
+ ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
+ }
+ if(ioDescription.mFormatID == 0)
+ {
+ ioDescription.mFormatID = inTemplateDescription.mFormatID;
+ }
+ if(ioDescription.mFormatFlags == 0)
+ {
+ ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
+ }
+ if(ioDescription.mBytesPerPacket == 0)
+ {
+ ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
+ }
+ if(ioDescription.mFramesPerPacket == 0)
+ {
+ ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
+ }
+ if(ioDescription.mBytesPerFrame == 0)
+ {
+ ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
+ }
+ if(ioDescription.mChannelsPerFrame == 0)
+ {
+ ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
+ }
+ if(ioDescription.mBitsPerChannel == 0)
+ {
+ ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
+ }
+}
+
+void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate)
+{
+ if(inIncludeSampleRate)
+ {
+ int theCharactersWritten = snprintf(outName, inMaxNameLength, "%.0f ", inDescription.mSampleRate);
+ outName += theCharactersWritten;
+ inMaxNameLength -= static_cast<UInt32>(theCharactersWritten);
+ }
+
+ switch(inDescription.mFormatID)
+ {
+ case kAudioFormatLinearPCM:
+ {
+ const char* theEndianString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
+ {
+ #if TARGET_RT_LITTLE_ENDIAN
+ theEndianString = "Big Endian";
+ #endif
+ }
+ else
+ {
+ #if TARGET_RT_BIG_ENDIAN
+ theEndianString = "Little Endian";
+ #endif
+ }
+
+ const char* theKindString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
+ {
+ theKindString = (inAbbreviate ? "Float" : "Floating Point");
+ }
+ else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
+ {
+ theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
+ }
+ else
+ {
+ theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
+ }
+
+ const char* thePackingString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
+ {
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
+ {
+ thePackingString = "High";
+ }
+ else
+ {
+ thePackingString = "Low";
+ }
+ }
+
+ const char* theMixabilityString = NULL;
+ if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
+ {
+ theMixabilityString = "Mixable";
+ }
+ else
+ {
+ theMixabilityString = "Unmixable";
+ }
+
+ if(inAbbreviate)
+ {
+ if(theEndianString != NULL)
+ {
+ if(thePackingString != NULL)
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
+ }
+ }
+ else
+ {
+ if(thePackingString != NULL)
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
+ }
+ else
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
+ }
+ }
+ }
+ else
+ {
+ if(theEndianString != NULL)
+ {
+ if(thePackingString != NULL)
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
+ }
+ }
+ else
+ {
+ if(thePackingString != NULL)
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
+ }
+ }
+ }
+ }
+ break;
+
+ case kAudioFormatAC3:
+ strlcpy(outName, "AC-3", sizeof(outName));
+ break;
+
+ case kAudioFormat60958AC3:
+ strlcpy(outName, "AC-3 for SPDIF", sizeof(outName));
+ break;
+
+ default:
+ CACopy4CCToCString(outName, inDescription.mFormatID);
+ break;
+ };
+}
+
+#if CoreAudio_Debug
+#include "CALogMacros.h"
+
+void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
+{
+ PrintFloat (" Sample Rate: ", inDesc.mSampleRate);
+ Print4CharCode (" Format ID: ", inDesc.mFormatID);
+ PrintHex (" Format Flags: ", inDesc.mFormatFlags);
+ PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket);
+ PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket);
+ PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame);
+ PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame);
+ PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel);
+}
+#endif
+
+bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ bool theAnswer = false;
+ bool isDone = false;
+
+ // note that if either side is 0, that field is skipped
+
+ // format ID is the first order sort
+ if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
+ {
+ if(x.mFormatID != y.mFormatID)
+ {
+ // formats are sorted numerically except that linear
+ // PCM is always first
+ if(x.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = true;
+ }
+ else if(y.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = false;
+ }
+ else
+ {
+ theAnswer = x.mFormatID < y.mFormatID;
+ }
+ isDone = true;
+ }
+ }
+
+
+ // mixable is always better than non-mixable for linear PCM and should be the second order sort item
+ if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
+ {
+ theAnswer = true;
+ isDone = true;
+ }
+ else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ theAnswer = false;
+ isDone = true;
+ }
+ }
+
+ // floating point vs integer for linear PCM only
+ if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
+ {
+ // floating point is better than integer
+ theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
+ isDone = true;
+ }
+ }
+
+ // bit depth
+ if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
+ {
+ if(x.mBitsPerChannel != y.mBitsPerChannel)
+ {
+ // deeper bit depths are higher quality
+ theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
+ isDone = true;
+ }
+ }
+
+ // sample rate
+ if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
+ {
+ if(fnotequal(x.mSampleRate, y.mSampleRate))
+ {
+ // higher sample rates are higher quality
+ theAnswer = x.mSampleRate < y.mSampleRate;
+ isDone = true;
+ }
+ }
+
+ // number of channels
+ if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
+ {
+ if(x.mChannelsPerFrame != y.mChannelsPerFrame)
+ {
+ // more channels is higher quality
+ theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
+ //isDone = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+void CAStreamBasicDescription::ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly )
+{
+ // match wildcards
+ if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
+ {
+ // Obliterate all flags.
+ xFlags = yFlags = 0;
+ return;
+ }
+
+ if (x.mFormatID == kAudioFormatLinearPCM) {
+ // knock off the all clear flag
+ xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
+ yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
+
+ // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
+ if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
+ xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh);
+ yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh);
+ }
+
+ // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
+ if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
+ xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger);
+ yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger);
+ }
+
+ // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
+ if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+ {
+ xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsBigEndian);
+ }
+ if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+ {
+ yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsBigEndian);
+ }
+
+ // if the number of channels is 1, we don't care about non-interleavedness
+ if (x.mChannelsPerFrame == 1 && y.mChannelsPerFrame == 1) {
+ xFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsNonInterleaved);
+ yFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsNonInterleaved);
+ }
+
+ if (converterOnly) {
+ CAStreamBasicDescription cas_x = CAStreamBasicDescription(x);
+ CAStreamBasicDescription cas_y = CAStreamBasicDescription(y);
+ if (!cas_x.PackednessIsSignificant() && !cas_y.PackednessIsSignificant()) {
+ xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsPacked);
+ yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsPacked);
+ }
+ if (!cas_x.AlignmentIsSignificant() && !cas_y.AlignmentIsSignificant()) {
+ xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh);
+ yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh);
+ }
+ // We don't care about whether the streams are mixable in this case
+ xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonMixable);
+ yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonMixable);
+ }
+ }
+}
+
+static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ UInt32 xFlags = x.mFormatFlags;
+ UInt32 yFlags = y.mFormatFlags;
+
+ CAStreamBasicDescription::ModifyFormatFlagsForMatching(x, y, xFlags, yFlags, false);
+ return xFlags == yFlags;
+}
+
+bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ // the semantics for equality are:
+ // 1) Values must match exactly -- except for PCM format flags, see above.
+ // 2) wildcard's are ignored in the comparison
+
+#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
+
+ return
+ // check all but the format flags
+ CAStreamBasicDescription::FlagIndependentEquivalence(x, y)
+ // check the format flags
+ && MatchFormatFlags(x, y);
+}
+
+bool CAStreamBasicDescription::FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y)
+{
+ return
+ // check the sample rate
+ (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
+
+ // check the format ids
+ && MATCH(mFormatID)
+
+ // check the bytes per packet
+ && MATCH(mBytesPerPacket)
+
+ // check the frames per packet
+ && MATCH(mFramesPerPacket)
+
+ // check the bytes per frame
+ && MATCH(mBytesPerFrame)
+
+ // check the channels per frame
+ && MATCH(mChannelsPerFrame)
+
+ // check the channels per frame
+ && MATCH(mBitsPerChannel) ;
+}
+
+bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const
+{
+ if (interpretingWildcards)
+ return *this == other;
+ return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0;
+}
+
+bool CAStreamBasicDescription::IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y)
+{
+ UInt32 xFlags = x.mFormatFlags, yFlags = y.mFormatFlags;
+ CAStreamBasicDescription::ModifyFormatFlagsForMatching(x, y, xFlags, yFlags, true);
+
+ return
+ // check all but the format flags
+ CAStreamBasicDescription::FlagIndependentEquivalence(x, y)
+ // check the format flags with converter focus
+ && (xFlags == yFlags);
+
+}
+
+bool SanityCheck(const AudioStreamBasicDescription& x)
+{
+ // This function returns false if there are sufficiently insane values in any field.
+ // It is very conservative so even some very unlikely values will pass.
+ // This is just meant to catch the case where the data from a file is corrupted.
+
+ return
+ (x.mSampleRate >= 0.)
+ && (x.mSampleRate < 3e6) // SACD sample rate is 2.8224 MHz
+ && (x.mBytesPerPacket < 1000000)
+ && (x.mFramesPerPacket < 1000000)
+ && (x.mBytesPerFrame < 1000000)
+ && (x.mChannelsPerFrame <= 1024)
+ && (x.mBitsPerChannel <= 1024)
+ && (x.mFormatID != 0)
+ && !(x.mFormatID == kAudioFormatLinearPCM && (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame));
+}
+
+bool CAStreamBasicDescription::FromText(const char *inTextDesc, AudioStreamBasicDescription &fmt)
+{
+ const char *p = inTextDesc;
+
+ memset(&fmt, 0, sizeof(fmt));
+
+ bool isPCM = true; // until proven otherwise
+ UInt32 pcmFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
+
+ if (p[0] == '-') // previously we required a leading dash on PCM formats
+ ++p;
+
+ if (p[0] == 'B' && p[1] == 'E') {
+ pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
+ p += 2;
+ } else if (p[0] == 'L' && p[1] == 'E') {
+ p += 2;
+ } else {
+ // default is native-endian
+#if TARGET_RT_BIG_ENDIAN
+ pcmFlags |= kLinearPCMFormatFlagIsBigEndian;
+#endif
+ }
+ if (p[0] == 'F') {
+ pcmFlags = (pcmFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger)) | kAudioFormatFlagIsFloat;
+ ++p;
+ } else {
+ if (p[0] == 'U') {
+ pcmFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger);
+ ++p;
+ }
+ if (p[0] == 'I')
+ ++p;
+ else {
+ // it's not PCM; presumably some other format (NOT VALIDATED; use AudioFormat for that)
+ isPCM = false;
+ p = inTextDesc; // go back to the beginning
+ char buf[4] = { ' ',' ',' ',' ' };
+ for (int i = 0; i < 4; ++i) {
+ if (*p != '\\') {
+ if ((buf[i] = *p++) == '\0') {
+ // special-case for 'aac'
+ if (i != 3) return false;
+ --p; // keep pointing at the terminating null
+ buf[i] = ' ';
+ break;
+ }
+ } else {
+ // "\xNN" is a hex byte
+ if (*++p != 'x') return false;
+ int x;
+ if (sscanf(++p, "%02X", &x) != 1) return false;
+ buf[i] = static_cast<char>(x);
+ p += 2;
+ }
+ }
+
+ if (strchr("-@/#", buf[3])) {
+ // further special-casing for 'aac'
+ buf[3] = ' ';
+ --p;
+ }
+
+ memcpy(&fmt.mFormatID, buf, 4);
+ fmt.mFormatID = CFSwapInt32BigToHost(fmt.mFormatID);
+ }
+ }
+
+ if (isPCM) {
+ fmt.mFormatID = kAudioFormatLinearPCM;
+ fmt.mFormatFlags = pcmFlags;
+ fmt.mFramesPerPacket = 1;
+ fmt.mChannelsPerFrame = 1;
+ UInt32 bitdepth = 0, fracbits = 0;
+ while (isdigit(*p))
+ bitdepth = 10 * bitdepth + static_cast<UInt32>(*p++ - '0');
+ if (*p == '.') {
+ ++p;
+ if (!isdigit(*p)) {
+ fprintf(stderr, "Expected fractional bits following '.'\n");
+ goto Bail;
+ }
+ while (isdigit(*p))
+ fracbits = 10 * fracbits + static_cast<UInt32>(*p++ - '0');
+ bitdepth += fracbits;
+ fmt.mFormatFlags |= (fracbits << kLinearPCMFormatFlagsSampleFractionShift);
+ }
+ fmt.mBitsPerChannel = bitdepth;
+ fmt.mBytesPerPacket = fmt.mBytesPerFrame = (bitdepth + 7) / 8;
+ if (bitdepth & 7) {
+ // assume unpacked. (packed odd bit depths are describable but not supported in AudioConverter.)
+ fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsPacked);
+ // alignment matters; default to high-aligned. use ':L_' for low.
+ fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
+ }
+ }
+ if (*p == '@') {
+ ++p;
+ while (isdigit(*p))
+ fmt.mSampleRate = 10 * fmt.mSampleRate + (*p++ - '0');
+ }
+ if (*p == '/') {
+ UInt32 flags = 0;
+ while (true) {
+ char c = *++p;
+ if (c >= '0' && c <= '9')
+ flags = (flags << 4) | static_cast<UInt32>(c - '0');
+ else if (c >= 'A' && c <= 'F')
+ flags = (flags << 4) | static_cast<UInt32>(c - 'A' + 10);
+ else if (c >= 'a' && c <= 'f')
+ flags = (flags << 4) | static_cast<UInt32>(c - 'a' + 10);
+ else break;
+ }
+ fmt.mFormatFlags = flags;
+ }
+ if (*p == '#') {
+ ++p;
+ while (isdigit(*p))
+ fmt.mFramesPerPacket = 10 * fmt.mFramesPerPacket + static_cast<UInt32>(*p++ - '0');
+ }
+ if (*p == ':') {
+ ++p;
+ fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsPacked);
+ if (*p == 'L')
+ fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsAlignedHigh);
+ else if (*p == 'H')
+ fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
+ else
+ goto Bail;
+ ++p;
+ UInt32 bytesPerFrame = 0;
+ while (isdigit(*p))
+ bytesPerFrame = 10 * bytesPerFrame + static_cast<UInt32>(*p++ - '0');
+ fmt.mBytesPerFrame = fmt.mBytesPerPacket = bytesPerFrame;
+ }
+ if (*p == ',') {
+ ++p;
+ int ch = 0;
+ while (isdigit(*p))
+ ch = 10 * ch + (*p++ - '0');
+ fmt.mChannelsPerFrame = static_cast<UInt32>(ch);
+ if (*p == 'D') {
+ ++p;
+ if (fmt.mFormatID != kAudioFormatLinearPCM) {
+ fprintf(stderr, "non-interleaved flag invalid for non-PCM formats\n");
+ goto Bail;
+ }
+ fmt.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ } else {
+ if (*p == 'I') ++p; // default
+ if (fmt.mFormatID == kAudioFormatLinearPCM)
+ fmt.mBytesPerPacket = fmt.mBytesPerFrame *= static_cast<UInt32>(ch);
+ }
+ }
+ if (*p != '\0') {
+ fprintf(stderr, "extra characters at end of format string: %s\n", p);
+ goto Bail;
+ }
+ return true;
+
+Bail:
+ fprintf(stderr, "Invalid format string: %s\n", inTextDesc);
+ fprintf(stderr, "Syntax of format strings is: \n");
+ return false;
+}
+
+const char *CAStreamBasicDescription::sTextParsingUsageString =
+ "format[@sample_rate_hz][/format_flags][#frames_per_packet][:LHbytesPerFrame][,channelsDI].\n"
+ "Format for PCM is [-][BE|LE]{F|I|UI}{bitdepth}; else a 4-char format code (e.g. aac, alac).\n";
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.h b/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.h
new file mode 100644
index 0000000000..8b81dba69a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAStreamBasicDescription.h
@@ -0,0 +1,424 @@
+/*
+ File: CAStreamBasicDescription.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAStreamBasicDescription_h__
+#define __CAStreamBasicDescription_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include "CoreAudioTypes.h"
+ #include "CoreFoundation.h"
+#endif
+
+#include "CADebugMacros.h"
+#include <string.h> // for memset, memcpy
+#include <stdio.h> // for FILE *
+
+#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
+
+extern char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize);
+
+// define Leopard specific symbols for backward compatibility if applicable
+#if COREAUDIOTYPES_VERSION < 1050
+typedef Float32 AudioSampleType;
+enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
+#endif
+#if COREAUDIOTYPES_VERSION < 1051
+typedef Float32 AudioUnitSampleType;
+enum {
+ kLinearPCMFormatFlagsSampleFractionShift = 7,
+ kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
+};
+#endif
+
+// define the IsMixable format flag for all versions of the system
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
+ enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
+#else
+ enum { kIsNonMixableFlag = (1L << 6) };
+#endif
+
+//=============================================================================
+// CAStreamBasicDescription
+//
+// This is a wrapper class for the AudioStreamBasicDescription struct.
+// It adds a number of convenience routines, but otherwise adds nothing
+// to the footprint of the original struct.
+//=============================================================================
+class CAStreamBasicDescription :
+ public AudioStreamBasicDescription
+{
+
+// Constants
+public:
+ static const AudioStreamBasicDescription sEmpty;
+
+ enum CommonPCMFormat {
+ kPCMFormatOther = 0,
+ kPCMFormatFloat32 = 1,
+ kPCMFormatInt16 = 2,
+ kPCMFormatFixed824 = 3,
+ kPCMFormatFloat64 = 4
+ };
+
+// Construction/Destruction
+public:
+ CAStreamBasicDescription();
+
+ CAStreamBasicDescription(const AudioStreamBasicDescription &desc);
+
+ CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
+ UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
+ UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
+ UInt32 inBitsPerChannel, UInt32 inFormatFlags);
+
+ CAStreamBasicDescription( double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) {
+ unsigned wordsize;
+
+ mSampleRate = inSampleRate;
+ mFormatID = kAudioFormatLinearPCM;
+ mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
+ mFramesPerPacket = 1;
+ mChannelsPerFrame = inNumChannels;
+ mBytesPerFrame = mBytesPerPacket = 0;
+ mReserved = 0;
+
+ switch (pcmf) {
+ default:
+ return;
+ case kPCMFormatFloat32:
+ wordsize = 4;
+ mFormatFlags |= kAudioFormatFlagIsFloat;
+ break;
+ case kPCMFormatFloat64:
+ wordsize = 8;
+ mFormatFlags |= kAudioFormatFlagIsFloat;
+ break;
+ case kPCMFormatInt16:
+ wordsize = 2;
+ mFormatFlags |= kAudioFormatFlagIsSignedInteger;
+ break;
+ case kPCMFormatFixed824:
+ wordsize = 4;
+ mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift);
+ break;
+ }
+ mBitsPerChannel = wordsize * 8;
+ if (inIsInterleaved)
+ mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels;
+ else {
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ mBytesPerFrame = mBytesPerPacket = wordsize;
+ }
+ }
+
+// Assignment
+ CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
+
+ void SetFrom(const AudioStreamBasicDescription &desc)
+ {
+ memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
+ }
+
+ bool FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); }
+ static bool FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc);
+ // return true if parsing was successful
+
+ static const char *sTextParsingUsageString;
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // interrogation
+
+ bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
+
+ bool PackednessIsSignificant() const
+ {
+ Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
+ return (SampleWordSize() << 3) != mBitsPerChannel;
+ }
+
+ bool AlignmentIsSignificant() const
+ {
+ return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
+ }
+
+ bool IsInterleaved() const
+ {
+ return !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
+ }
+
+ bool IsSignedInteger() const
+ {
+ return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger);
+ }
+
+ bool IsFloat() const
+ {
+ return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat);
+ }
+
+ bool IsNativeEndian() const
+ {
+ return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
+ }
+
+ // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
+ UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
+ UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
+ UInt32 NumberChannels() const { return mChannelsPerFrame; }
+ UInt32 SampleWordSize() const {
+ return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0;
+ }
+
+ UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
+ UInt32 BytesToFrames(UInt32 nbytes) const {
+ Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
+ return nbytes / mBytesPerFrame;
+ }
+
+ bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
+ {
+ return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
+ }
+
+ bool IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const
+ { // return true if it's a valid PCM format.
+
+ outFormat = kPCMFormatOther;
+ // trap out patently invalid formats.
+ if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0)
+ return false;
+ bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+ if (outIsInterleaved != NULL) *outIsInterleaved = interleaved;
+ unsigned wordsize = mBytesPerFrame;
+ if (interleaved) {
+ if (wordsize % mChannelsPerFrame != 0) return false;
+ wordsize /= mChannelsPerFrame;
+ }
+
+ if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian
+ && wordsize * 8 == mBitsPerChannel) {
+ // packed and native endian, good
+ if (mFormatFlags & kLinearPCMFormatFlagIsFloat) {
+ // float: reject nonsense bits
+ if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
+ return false;
+ if (wordsize == 4)
+ outFormat = kPCMFormatFloat32;
+ if (wordsize == 8)
+ outFormat = kPCMFormatFloat64;
+ } else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
+ // signed int
+ unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
+ if (wordsize == 4 && fracbits == 24)
+ outFormat = kPCMFormatFixed824;
+ else if (wordsize == 2 && fracbits == 0)
+ outFormat = kPCMFormatInt16;
+ }
+ }
+ return true;
+ }
+
+ bool IsCommonFloat32(bool *outIsInterleaved=NULL) const {
+ CommonPCMFormat fmt;
+ return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32;
+ }
+ bool IsCommonFloat64(bool *outIsInterleaved=NULL) const {
+ CommonPCMFormat fmt;
+ return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat64;
+ }
+ bool IsCommonFixed824(bool *outIsInterleaved=NULL) const {
+ CommonPCMFormat fmt;
+ return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824;
+ }
+ bool IsCommonInt16(bool *outIsInterleaved=NULL) const {
+ CommonPCMFormat fmt;
+ return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16;
+ }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // manipulation
+
+ void SetCanonical(UInt32 nChannels, bool interleaved)
+ // note: leaves sample rate untouched
+ {
+ mFormatID = kAudioFormatLinearPCM;
+ UInt32 sampleSize = SizeOf32(AudioSampleType);
+ mFormatFlags = kAudioFormatFlagsCanonical;
+ mBitsPerChannel = 8 * sampleSize;
+ mChannelsPerFrame = nChannels;
+ mFramesPerPacket = 1;
+ if (interleaved)
+ mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
+ else {
+ mBytesPerPacket = mBytesPerFrame = sampleSize;
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ }
+ }
+
+ bool IsCanonical() const
+ {
+ if (mFormatID != kAudioFormatLinearPCM) return false;
+ UInt32 reqFormatFlags;
+ UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask);
+ bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+ unsigned sampleSize = SizeOf32(AudioSampleType);
+ reqFormatFlags = kAudioFormatFlagsCanonical;
+ UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
+
+ return ((mFormatFlags & flagsMask) == reqFormatFlags
+ && mBitsPerChannel == 8 * sampleSize
+ && mFramesPerPacket == 1
+ && mBytesPerFrame == reqFrameSize
+ && mBytesPerPacket == reqFrameSize);
+ }
+
+ void SetAUCanonical(UInt32 nChannels, bool interleaved)
+ {
+ mFormatID = kAudioFormatLinearPCM;
+#if CA_PREFER_FIXED_POINT
+ mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
+#else
+ mFormatFlags = kAudioFormatFlagsCanonical;
+#endif
+ mChannelsPerFrame = nChannels;
+ mFramesPerPacket = 1;
+ mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
+ if (interleaved)
+ mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
+ else {
+ mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ }
+ }
+
+ void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
+ // alter an existing format
+ {
+ Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
+ UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
+ if (wordSize == 0)
+ wordSize = (mBitsPerChannel + 7) / 8;
+ mChannelsPerFrame = nChannels;
+ mFramesPerPacket = 1;
+ if (interleaved) {
+ mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
+ mFormatFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonInterleaved);
+ } else {
+ mBytesPerPacket = mBytesPerFrame = wordSize;
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ }
+ }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // other
+
+ bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
+ static bool FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
+ static bool IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
+
+ void Print() const {
+ Print (stdout);
+ }
+
+ void Print(FILE* file) const {
+ PrintFormat (file, "", "AudioStreamBasicDescription:");
+ }
+
+ void PrintFormat(FILE *f, const char *indent, const char *name) const {
+ char buf[256];
+ fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
+ }
+
+ void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
+ char buf[256];
+ fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
+ }
+
+ char * AsString(char *buf, size_t bufsize, bool brief=false) const;
+
+ static void Print (const AudioStreamBasicDescription &inDesc)
+ {
+ CAStreamBasicDescription desc(inDesc);
+ desc.Print ();
+ }
+
+ OSStatus Save(CFPropertyListRef *outData) const;
+
+ OSStatus Restore(CFPropertyListRef &inData);
+
+// Operations
+ static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
+ static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
+ static void NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription);
+ static void ResetFormat(AudioStreamBasicDescription& ioDescription);
+ static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
+ static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false);
+ static void ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly);
+
+#if CoreAudio_Debug
+ static void PrintToLog(const AudioStreamBasicDescription& inDesc);
+#endif
+};
+
+bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
+inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
+inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
+inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
+#endif
+
+bool SanityCheck(const AudioStreamBasicDescription& x);
+
+
+#endif // __CAStreamBasicDescription_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.cpp
new file mode 100644
index 0000000000..9b72054101
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.cpp
@@ -0,0 +1,183 @@
+/*
+ File: CAStreamRangedDescription.cpp
+ Abstract: CAStreamRangedDescription.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Self Include
+#include "CAStreamRangedDescription.h"
+#include "CAMath.h"
+
+//==================================================================================================
+// CAStreamRangedDescription
+//==================================================================================================
+
+const AudioStreamRangedDescription CAStreamRangedDescription::sEmpty = { { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0.0, 0.0 } };
+
+#if CoreAudio_Debug
+#include "CALogMacros.h"
+
+void CAStreamRangedDescription::PrintToLog(const AudioStreamRangedDescription& inDesc)
+{
+ PrintFloat (" Sample Rate: ", inDesc.mFormat.mSampleRate);
+ PrintFloat (" Max Sample Rate: ", inDesc.mSampleRateRange.mMaximum);
+ PrintFloat (" Min Sample Rate: ", inDesc.mSampleRateRange.mMinimum);
+ Print4CharCode (" Format ID: ", inDesc.mFormat.mFormatID);
+ PrintHex (" Format Flags: ", inDesc.mFormat.mFormatFlags);
+ PrintInt (" Bytes per Packet: ", inDesc.mFormat.mBytesPerPacket);
+ PrintInt (" Frames per Packet: ", inDesc.mFormat.mFramesPerPacket);
+ PrintInt (" Bytes per Frame: ", inDesc.mFormat.mBytesPerFrame);
+ PrintInt (" Channels per Frame: ", inDesc.mFormat.mChannelsPerFrame);
+ PrintInt (" Bits per Channel: ", inDesc.mFormat.mBitsPerChannel);
+}
+#endif
+
+bool CAStreamRangedDescription::Sorter(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y)
+{
+ bool theAnswer = false;
+ bool isDone = false;
+
+ // note that if either side is 0, that field is skipped
+
+ // format ID is the first order sort
+ if((!isDone) && ((x.mFormat.mFormatID != 0) && (y.mFormat.mFormatID != 0)))
+ {
+ if(x.mFormat.mFormatID != y.mFormat.mFormatID)
+ {
+ // formats are sorted numerically except that linear
+ // PCM is always first
+ if(x.mFormat.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = true;
+ }
+ else if(y.mFormat.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = false;
+ }
+ else
+ {
+ theAnswer = x.mFormat.mFormatID < y.mFormat.mFormatID;
+ }
+ isDone = true;
+ }
+ }
+
+
+ // mixable is always better than non-mixable for linear PCM and should be the second order sort item
+ if((!isDone) && ((x.mFormat.mFormatID == kAudioFormatLinearPCM) && (y.mFormat.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if(((x.mFormat.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormat.mFormatFlags & kIsNonMixableFlag) != 0))
+ {
+ theAnswer = true;
+ isDone = true;
+ }
+ else if(((x.mFormat.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormat.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ theAnswer = false;
+ isDone = true;
+ }
+ }
+
+ // floating point vs integer for linear PCM only
+ if((!isDone) && ((x.mFormat.mFormatID == kAudioFormatLinearPCM) && (y.mFormat.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if((x.mFormat.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormat.mFormatFlags & kAudioFormatFlagIsFloat))
+ {
+ // floating point is better than integer
+ theAnswer = y.mFormat.mFormatFlags & kAudioFormatFlagIsFloat;
+ isDone = true;
+ }
+ }
+
+ // bit depth
+ if((!isDone) && ((x.mFormat.mBitsPerChannel != 0) && (y.mFormat.mBitsPerChannel != 0)))
+ {
+ if(x.mFormat.mBitsPerChannel != y.mFormat.mBitsPerChannel)
+ {
+ // deeper bit depths are higher quality
+ theAnswer = x.mFormat.mBitsPerChannel > y.mFormat.mBitsPerChannel;
+ isDone = true;
+ }
+ }
+
+ // sample rate range
+ if((!isDone) && fnonzero(x.mSampleRateRange.mMinimum) && fnonzero(x.mSampleRateRange.mMaximum) && fnonzero(y.mSampleRateRange.mMinimum) && fnonzero(y.mSampleRateRange.mMaximum))
+ {
+ if(x.mSampleRateRange != y.mSampleRateRange)
+ {
+ // higher sample rates are higher quality
+ theAnswer = x.mSampleRateRange > y.mSampleRateRange;
+ isDone = true;
+ }
+ }
+
+ // sample rate
+ if((!isDone) && fnonzero(x.mFormat.mSampleRate) && fnonzero(y.mFormat.mSampleRate))
+ {
+ if(fnotequal(x.mFormat.mSampleRate, y.mFormat.mSampleRate))
+ {
+ // higher sample rates are higher quality
+ theAnswer = x.mFormat.mSampleRate > y.mFormat.mSampleRate;
+ isDone = true;
+ }
+ }
+
+ // number of channels
+ if((!isDone) && ((x.mFormat.mChannelsPerFrame != 0) && (y.mFormat.mChannelsPerFrame != 0)))
+ {
+ if(x.mFormat.mChannelsPerFrame != y.mFormat.mChannelsPerFrame)
+ {
+ // more channels is higher quality
+ theAnswer = x.mFormat.mChannelsPerFrame < y.mFormat.mChannelsPerFrame;
+ // commented out to prevent this from being flagged as a dead store by the static analyzer
+ //isDone = true;
+ }
+ }
+
+ return theAnswer;
+}
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.h b/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.h
new file mode 100644
index 0000000000..7f8284dee0
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAStreamRangedDescription.h
@@ -0,0 +1,140 @@
+/*
+ File: CAStreamRangedDescription.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAStreamRangedDescription_h__)
+#define __CAStreamRangedDescription_h__
+
+//==================================================================================================
+// Includes
+//==================================================================================================
+
+// Super Class Includes
+#include <CoreAudio/AudioHardware.h>
+
+// PublicUtility Includes
+#include "CAAudioValueRange.h"
+#include "CAStreamBasicDescription.h"
+
+//==================================================================================================
+// CAStreamRangedDescription
+//==================================================================================================
+
+class CAStreamRangedDescription
+:
+ public AudioStreamRangedDescription
+{
+
+// Constants
+public:
+ static const AudioStreamRangedDescription sEmpty;
+
+// Construction/Destruction
+public:
+ CAStreamRangedDescription() { memset(this, 0, sizeof(AudioStreamRangedDescription)); }
+ CAStreamRangedDescription(const CAStreamRangedDescription& inFormat) { mFormat = inFormat.mFormat; mSampleRateRange = inFormat.mSampleRateRange; }
+ CAStreamRangedDescription(const AudioStreamRangedDescription& inFormat) { mFormat = inFormat.mFormat; mSampleRateRange = inFormat.mSampleRateRange; }
+ CAStreamRangedDescription(const AudioStreamBasicDescription& inFormat) { mFormat = inFormat; mSampleRateRange.mMinimum = inFormat.mSampleRate; mSampleRateRange.mMaximum = inFormat.mSampleRate; }
+ CAStreamRangedDescription(const AudioStreamBasicDescription& inFormat, const AudioValueRange& inSampleRateRange) { mFormat = inFormat; mSampleRateRange = inSampleRateRange; }
+ CAStreamRangedDescription& operator=(const CAStreamRangedDescription& inFormat) { mFormat = inFormat.mFormat; mSampleRateRange = inFormat.mSampleRateRange; return *this; }
+ CAStreamRangedDescription& operator=(const AudioStreamRangedDescription& inFormat) { mFormat = inFormat.mFormat; mSampleRateRange = inFormat.mSampleRateRange; return *this; }
+
+ static bool IsMixable(const AudioStreamRangedDescription& inDescription) { return (inDescription.mFormat.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormat.mFormatFlags & kIsNonMixableFlag) == 0); }
+#if CoreAudio_Debug
+ static void PrintToLog(const AudioStreamRangedDescription& inDesc);
+#endif
+ static bool Sorter(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y);
+
+};
+
+inline bool operator<(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return (x.mFormat.mFormatID == y.mFormat.mFormatID) ?
+ (x.mFormat < y.mFormat) && (x.mSampleRateRange < y.mSampleRateRange) :
+ (x.mFormat.mFormatID == kAudioFormatLinearPCM) ? false : (x.mFormat.mFormatID < y.mFormat.mFormatID); }
+inline bool operator==(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return (x.mFormat == y.mFormat) && (x.mSampleRateRange == y.mSampleRateRange); }
+#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
+inline bool operator!=(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return !(x == y); }
+inline bool operator<=(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return !(x < y); }
+inline bool operator>(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) { return !((x < y) || (x == y)); }
+#endif
+
+inline bool operator<(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return (x.mFormatID == y.mFormat.mFormatID) ?
+ (x < y.mFormat) && (x.mSampleRate < y.mSampleRateRange.mMinimum) :
+ (x.mFormatID == kAudioFormatLinearPCM) ? false : (x.mFormatID < y.mFormat.mFormatID); }
+inline bool operator<(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return (x.mFormat.mFormatID == y.mFormatID) ?
+ (x.mFormat < y) && (x.mSampleRateRange.mMinimum < y.mSampleRate) :
+ (x.mFormat.mFormatID == kAudioFormatLinearPCM) ? false : (x.mFormat.mFormatID < y.mFormatID); }
+inline bool operator==(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return (x == y.mFormat) && CAAudioValueRange::ContainsValue(y.mSampleRateRange, x.mSampleRate); }
+inline bool operator==(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return (x.mFormat == y) && CAAudioValueRange::ContainsValue(x.mSampleRateRange, y.mSampleRate); }
+#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
+inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return !(x == y); }
+inline bool operator!=(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
+inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return (x < y) || (x == y); }
+inline bool operator<=(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return !(x < y); }
+inline bool operator>=(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
+inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamRangedDescription& y) { return !((x < y) || (x == y)); }
+inline bool operator>(const AudioStreamRangedDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
+#endif
+
+// STL Functors
+struct CAStreamRangedDescription_EqualToASBD
+:
+ public std::unary_function<AudioStreamRangedDescription, bool>
+{
+ CAStreamRangedDescription_EqualToASBD(const AudioStreamBasicDescription& inFormat) : mFormat(inFormat) {}
+ bool operator()(const AudioStreamRangedDescription& x) const { return mFormat == x; }
+
+ AudioStreamBasicDescription mFormat;
+};
+
+struct CAStreamRangedDescription_ReverseSort
+:
+ public std::binary_function<AudioStreamRangedDescription, AudioStreamRangedDescription, bool>
+{
+ bool operator()(const AudioStreamRangedDescription& x, const AudioStreamRangedDescription& y) const { return CAStreamRangedDescription::Sorter(x, y); }
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAThreadSafeList.h b/libs/appleutility/CoreAudio/PublicUtility/CAThreadSafeList.h
new file mode 100644
index 0000000000..d0b7391476
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAThreadSafeList.h
@@ -0,0 +1,233 @@
+/*
+ File: CAThreadSafeList.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAThreadSafeList_h__
+#define __CAThreadSafeList_h__
+
+#include "CAAtomicStack.h"
+
+// linked list of T's
+// T must define operator ==
+template <class T>
+class TThreadSafeList {
+private:
+ enum EEventType { kAdd, kRemove, kClear };
+ class Node {
+ public:
+ Node * mNext;
+ EEventType mEventType;
+ T mObject;
+
+ Node *& next() { return mNext; }
+ };
+
+public:
+ class iterator {
+ public:
+ iterator() { }
+ iterator(Node *n) : mNode(n) { }
+
+ bool operator == (const iterator &other) const { return this->mNode == other.mNode; }
+ bool operator != (const iterator &other) const { return this->mNode != other.mNode; }
+
+ T & operator * () const { return mNode->mObject; }
+
+ iterator & operator ++ () { mNode = mNode->next(); return *this; } // preincrement
+ iterator operator ++ (int) { iterator tmp = *this; mNode = mNode->next(); return tmp; } // postincrement
+
+ private:
+ Node * mNode;
+ };
+
+ TThreadSafeList() { }
+ ~TThreadSafeList()
+ {
+ mActiveList.free_all();
+ mPendingList.free_all();
+ mFreeList.free_all();
+ }
+
+ // These may be called on any thread
+
+ void deferred_add(const T &obj) // can be called on any thread
+ {
+ Node *node = AllocNode();
+ node->mEventType = kAdd;
+ node->mObject = obj;
+ mPendingList.push_atomic(node);
+ //mPendingList.dump("pending after add");
+ }
+
+ void deferred_remove(const T &obj) // can be called on any thread
+ {
+ Node *node = AllocNode();
+ node->mEventType = kRemove;
+ node->mObject = obj;
+ mPendingList.push_atomic(node);
+ //mPendingList.dump("pending after remove");
+ }
+
+ void deferred_clear() // can be called on any thread
+ {
+ Node *node = AllocNode();
+ node->mEventType = kClear;
+ mPendingList.push_atomic(node);
+ }
+
+ // These must be called from only one thread
+
+ void update() // must only be called from one thread
+ {
+ NodeStack reversed;
+ Node *event, *node, *next;
+ bool workDone = false;
+
+ // reverse the events so they are in order
+ event = mPendingList.pop_all();
+ while (event != NULL) {
+ next = event->mNext;
+ reversed.push_NA(event);
+ event = next;
+ workDone = true;
+ }
+ if (workDone) {
+ //reversed.dump("pending popped");
+ //mActiveList.dump("active before update");
+
+ // now process them
+ while ((event = reversed.pop_NA()) != NULL) {
+ switch (event->mEventType) {
+ case kAdd:
+ {
+ Node **pnode;
+ bool needToInsert = true;
+ for (pnode = mActiveList.phead(); *pnode != NULL; pnode = &node->mNext) {
+ node = *pnode;
+ if (node->mObject == event->mObject) {
+ //printf("already active!!!\n");
+ FreeNode(event);
+ needToInsert = false;
+ break;
+ }
+ }
+ if (needToInsert) {
+ // link the new event in at the end of the active list
+ *pnode = event;
+ event->mNext = NULL;
+ }
+ }
+ break;
+ case kRemove:
+ // find matching node in the active list, remove it
+ for (Node **pnode = mActiveList.phead(); *pnode != NULL; ) {
+ node = *pnode;
+ if (node->mObject == event->mObject) {
+ *pnode = node->mNext; // remove from linked list
+ FreeNode(node);
+ break;
+ }
+ pnode = &node->mNext;
+ }
+ // dispose the request node
+ FreeNode(event);
+ break;
+ case kClear:
+ for (node = mActiveList.head(); node != NULL; ) {
+ next = node->mNext;
+ FreeNode(node);
+ node = next;
+ }
+ FreeNode(event);
+ break;
+ default:
+ //printf("invalid node type %d!\n", event->mEventType);
+ break;
+ }
+ }
+ //mActiveList.dump("active after update");
+ }
+ }
+
+ iterator begin() const {
+ //mActiveList.dump("active at begin");
+ return iterator(mActiveList.head());
+ }
+ iterator end() const { return iterator(NULL); }
+
+
+private:
+ Node * AllocNode()
+ {
+ Node *node = mFreeList.pop_atomic();
+ if (node == NULL)
+ node = (Node *)CA_malloc(sizeof(Node));
+ return node;
+ }
+
+ void FreeNode(Node *node)
+ {
+ mFreeList.push_atomic(node);
+ }
+
+private:
+ class NodeStack : public TAtomicStack<Node> {
+ public:
+ void free_all() {
+ Node *node;
+ while ((node = this->pop_NA()) != NULL)
+ free(node);
+ }
+
+ Node ** phead() { return &this->mHead; }
+ Node * head() const { return this->mHead; }
+ };
+
+ NodeStack mActiveList; // what's actually in the container - only accessed on one thread
+ NodeStack mPendingList; // add or remove requests - threadsafe
+ NodeStack mFreeList; // free nodes for reuse - threadsafe
+};
+
+#endif // __CAThreadSafeList_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CATink.h b/libs/appleutility/CoreAudio/PublicUtility/CATink.h
new file mode 100644
index 0000000000..f0829359a6
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CATink.h
@@ -0,0 +1,146 @@
+/*
+ File: CATink.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CATink_h__)
+#define __CATink_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+#else
+ #include <CoreServices.h>
+#endif
+
+
+//=============================================================================
+// CATink
+//
+// A Tink is a small jump island that can make one function appear as if it
+// has many addresses. Note that Tinks are not supported for 64 bit environments
+// as the APIs that made tinks useful have been replaced by APIs that do away
+// with all the reasons for using a tink.
+//=============================================================================
+
+template <class F>
+class CATink
+{
+
+public:
+ CATink(F proc) { Set(proc); }
+
+ ~CATink() { Set((F)0xDEADDEAD); } // jump to an obviously bad (odd) address if accessed after destruction
+
+#if TARGET_CPU_PPC
+ void Set(F proc)
+ {
+ /*
+ lis r11,0x1234
+ 00000000: 3D601234 lis r11,4660
+ ori r11,r11,0x5678
+ 00000004: 616B5678 ori r11,r11,$5678
+ mtctr r11
+ 00000008: 7D6903A6 mtctr r11
+ bctr
+ 0000000C: 4E800420 bctr
+ */
+ UInt32 p = UInt32(proc);
+ mCode[0] = 0x3D600000 | (p >> 16);
+ mCode[1] = 0x616B0000 | (p & 0xFFFF);
+ mCode[2] = 0x7D6903A6;
+ mCode[3] = 0x4E800420;
+ MakeDataExecutable(mCode, sizeof(mCode));
+ }
+
+ operator F () { return F(mCode); }
+
+private:
+ UInt32 mCode[4];
+#elif TARGET_CPU_X86
+ void Set(F proc)
+ {
+ /*
+ <tink>: push $0x12345678
+ <tink+5>: ret
+ <tink>: 0x34567868
+ <tink+4>: 0x00e8c312
+ */
+ UInt32 p = UInt32(proc);
+ mCode[0] = ((p & 0xFFFFFF) << 8) | 0x00000068;
+ mCode[1] = 0xCCCCC300 | (p >> 24);
+ MakeDataExecutable(mCode, sizeof(mCode));
+ }
+
+ operator F () { return F(&mCode[0]); }
+
+private:
+ UInt32 mCode[2];
+#else
+ #warning: CPU not directly supported by CATink
+
+ // For other CPU's, just wrap the function pointer for now.
+ // this bypasses what we're trying to accomplish with the Tink
+ // (multiple unique "instances" of a function), but it will at
+ // least compile and run.
+
+ void Set(F proc) { mProcPtr = proc; }
+
+ operator F () { return mProcPtr; }
+private:
+ F mProcPtr;
+#endif
+
+// Tinks cannot be allocated in STL Containers, so we make a few key methods private
+private:
+ CATink(){}
+ CATink(const CATink&){}
+ CATink& operator=(const CATink&){ return *this;}
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CATokenMap.h b/libs/appleutility/CoreAudio/PublicUtility/CATokenMap.h
new file mode 100644
index 0000000000..f85f393022
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CATokenMap.h
@@ -0,0 +1,212 @@
+/*
+ File: CATokenMap.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CATokenMap_h__)
+#define __CATokenMap_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+// PublicUtility Includes
+#include "CAMutex.h"
+
+// Standard Library Includes
+#include <map>
+#include <iterator>
+
+//=============================================================================
+// CATokenMap
+//=============================================================================
+
+template <class T>
+class CATokenMap
+{
+
+// Types
+private:
+ typedef std::map<UInt32, T*> TokenMap;
+
+// Construction/Destruction
+public:
+ CATokenMap() : mTokenMap(), mNextToken(256), mTokenMapMutex("CATokenMap Mutex") {}
+ ~CATokenMap() {}
+
+// Operations
+public:
+ bool Lock()
+ {
+ return mTokenMapMutex.Lock();
+ }
+
+ void Unlock()
+ {
+ mTokenMapMutex.Unlock();
+ }
+
+ UInt32 GetToken(T* inObject) const
+ {
+ CAMutex::Locker theLocker(const_cast<CAMutex&>(mTokenMapMutex));
+ UInt32 theAnswer = 0;
+ typename TokenMap::const_iterator i = mTokenMap.begin();
+ while((theAnswer == 0) && (i != mTokenMap.end()))
+ {
+ if(i->second == inObject)
+ {
+ theAnswer = i->first;
+ }
+ std::advance(i, 1);
+ }
+ return theAnswer;
+ }
+
+ T* GetObject(UInt32 inToken) const
+ {
+ CAMutex::Locker theLocker(const_cast<CAMutex&>(mTokenMapMutex));
+ typename TokenMap::const_iterator i = mTokenMap.find(inToken);
+ return i != mTokenMap.end() ? i->second : NULL;
+ }
+
+ T* GetObject(const void* inToken) const
+ {
+ #if __LP64__
+ return GetObject((UInt32)((UInt64)inToken));
+ #else
+ return GetObject((UInt32)inToken);
+ #endif
+ }
+
+ UInt32 GetNumberObjects() const
+ {
+ CAMutex::Locker theLocker(const_cast<CAMutex&>(mTokenMapMutex));
+ return static_cast<UInt32>(mTokenMap.size());
+ }
+
+ T* GetObjectByIndex(UInt32 inIndex) const
+ {
+ T* theAnswer = NULL;
+ CAMutex::Locker theLocker(const_cast<CAMutex&>(mTokenMapMutex));
+ if(inIndex < mTokenMap.size())
+ {
+ typename TokenMap::const_iterator i = mTokenMap.begin();
+ std::advance(i, inIndex);
+ theAnswer = (i != mTokenMap.end()) ? i->second : NULL;
+ }
+ return theAnswer;
+ }
+
+ void AddMapping(UInt32 inToken, T* inObject)
+ {
+ CAMutex::Locker theLocker(mTokenMapMutex);
+ typename TokenMap::iterator i = mTokenMap.find(inToken);
+ if(i != mTokenMap.end())
+ {
+ i->second = inObject;
+ }
+ else
+ {
+ mTokenMap.insert(typename TokenMap::value_type(inToken, inObject));
+ }
+ }
+
+ void RemoveMapping(UInt32 inToken, T* /*inObject*/)
+ {
+ CAMutex::Locker theLocker(mTokenMapMutex);
+ typename TokenMap::iterator i = mTokenMap.find(inToken);
+ if(i != mTokenMap.end())
+ {
+ mTokenMap.erase(i);
+ }
+ }
+
+ UInt32 GetNextToken()
+ {
+ return mNextToken++;
+ }
+
+ UInt32 MapObject(T* inObject)
+ {
+ CAMutex::Locker theLocker(mTokenMapMutex);
+ UInt32 theToken = GetNextToken();
+ mTokenMap.insert(typename TokenMap::value_type(theToken, inObject));
+ return theToken;
+ }
+
+ void UnmapObject(T* inObject)
+ {
+ CAMutex::Locker theLocker(mTokenMapMutex);
+ bool isDone = false;
+ typename TokenMap::iterator i = mTokenMap.begin();
+ while(!isDone && (i != mTokenMap.end()))
+ {
+ if(i->second == inObject)
+ {
+ mTokenMap.erase(i);
+ isDone = true;
+ }
+ else
+ {
+ std::advance(i, 1);
+ }
+ }
+ }
+
+// Implementation
+private:
+ TokenMap mTokenMap;
+ UInt32 mNextToken;
+ CAMutex mTokenMapMutex;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.cpp
new file mode 100644
index 0000000000..83bfb8c889
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.cpp
@@ -0,0 +1,195 @@
+/*
+ File: CAVectorUnit.cpp
+ Abstract: CAVectorUnit.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAVectorUnit.h"
+
+#if !TARGET_OS_WIN32
+ #include <sys/sysctl.h>
+#elif HAS_IPP
+ #include "ippdefs.h"
+ #include "ippcore.h"
+#endif
+
+int gCAVectorUnitType = kVecUninitialized;
+
+#if TARGET_OS_WIN32
+// Use cpuid to check if SSE2 is available.
+// Before calling this function make sure cpuid is available
+static SInt32 IsSSE2Available()
+{
+ int return_value;
+
+ {
+ int r_edx;
+ _asm
+ {
+ mov eax, 0x01
+ cpuid
+ mov r_edx, edx
+ }
+ return_value = (r_edx >> 26) & 0x1;
+ }
+ return return_value;
+}
+
+// Use cpuid to check if SSE3 is available.
+// Before calling this function make sure cpuid is available
+static SInt32 IsSSE3Available()
+{
+ SInt32 return_value;
+
+ {
+ SInt32 r_ecx;
+ _asm
+ {
+ mov eax, 0x01
+ cpuid
+ mov r_ecx, ecx
+ }
+ return_value = r_ecx & 0x1;
+ }
+ return return_value;
+}
+
+// Return true if the cpuid instruction is available.
+// The cpuid instruction is available if bit 21 in the EFLAGS register can be changed
+// This function may not work on Intel CPUs prior to Pentium (didn't test)
+static bool IsCpuidAvailable()
+{
+ SInt32 return_value = 0x0;
+ _asm{
+ pushfd ; //push original EFLAGS
+ pop eax ; //get original EFLAGS
+ mov ecx, eax ; //save original EFLAGS
+ xor eax, 200000h ; //flip ID bit in EFLAGS
+ push eax ; //save new EFLAGS value on stack
+ popfd ; //replace current EFLAGS value
+ pushfd ; //get new EFLAGS
+ pop eax ; //store new EFLAGS in EAX
+ xor eax, ecx ;
+ je end_cpuid_identify ; //can't toggle ID bit
+ mov return_value, 0x1;
+end_cpuid_identify:
+ nop;
+ }
+ return return_value;
+}
+
+#endif
+
+SInt32 CAVectorUnit_Examine()
+{
+ int result = kVecNone;
+
+#if TARGET_OS_WIN32
+#if HAS_IPP
+ // Initialize the static IPP library! This needs to be done before
+ // any IPP function calls, otherwise we may have a performance penalty
+ int status = ippStaticInit();
+ if ( status == ippStsNonIntelCpu )
+ {
+ IppCpuType cpuType = ippGetCpuType();
+ if ( cpuType >= ippCpuSSE || cpuType <= ippCpuSSE42 )
+ ippStaticInitCpu( cpuType );
+ }
+#endif
+ {
+ // On Windows we use cpuid to detect the vector unit because it works on Intel and AMD.
+ // The IPP library does not detect SSE on AMD processors.
+ if (IsCpuidAvailable())
+ {
+ if(IsSSE3Available())
+ {
+ result = kVecSSE3;
+ }
+ else if(IsSSE2Available())
+ {
+ result = kVecSSE2;
+ }
+ }
+ }
+#elif TARGET_OS_MAC
+#if DEBUG
+ if (getenv("CA_NoVector")) {
+ fprintf(stderr, "CA_NoVector set; Vector unit optimized routines will be bypassed\n");
+ return result;
+ }
+ else
+#endif
+ {
+ #if (TARGET_CPU_PPC || TARGET_CPU_PPC64)
+ int sels[2] = { CTL_HW, HW_VECTORUNIT };
+ int vType = 0; //0 == scalar only
+ size_t length = sizeof(vType);
+ int error = sysctl(sels, 2, &vType, &length, NULL, 0);
+ if (!error && vType > 0)
+ result = kVecAltivec;
+ #elif (TARGET_CPU_X86 || TARGET_CPU_X86_64)
+ static const struct { const char* kName; const int kVectype; } kStringVectypes[] = {
+ { "hw.optional.avx1_0", kVecAVX1 }, { "hw.optional.sse3", kVecSSE3 }, { "hw.optional.sse2", kVecSSE2 }
+ };
+ static const size_t kNumStringVectypes = sizeof(kStringVectypes)/sizeof(kStringVectypes[0]);
+ int i = 0, answer = 0;
+ while(i != kNumStringVectypes)
+ {
+ size_t length = sizeof(answer);
+ int error = sysctlbyname(kStringVectypes[i].kName, &answer, &length, NULL, 0);
+ if (!error && answer)
+ {
+ result = kStringVectypes[i].kVectype;
+ break;
+ }
+ ++i;
+ };
+ #elif CA_ARM_NEON
+ result = kVecNeon;
+ #endif
+ }
+#endif
+ gCAVectorUnitType = result;
+ return result;
+}
+
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.h b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.h
new file mode 100644
index 0000000000..cf3a16c7a9
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnit.h
@@ -0,0 +1,101 @@
+/*
+ File: CAVectorUnit.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAVectorUnit_h__
+#define __CAVectorUnit_h__
+
+#include <TargetConditionals.h>
+#include "CAVectorUnitTypes.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CFBase.h>
+#else
+ #include "CFBase.h"
+#endif
+
+// Unify checks for vector units.
+// Allow setting an environment variable "CA_NoVector" to turn off vectorized code at runtime (very useful for performance testing).
+
+extern int gCAVectorUnitType;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern SInt32 CAVectorUnit_Examine(); // expensive. use GetType() for lazy initialization and caching.
+
+static inline SInt32 CAVectorUnit_GetType()
+{
+ int x = gCAVectorUnitType;
+ return (x != kVecUninitialized) ? x : CAVectorUnit_Examine();
+}
+
+static inline Boolean CAVectorUnit_HasVectorUnit()
+{
+ return CAVectorUnit_GetType() > kVecNone;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+class CAVectorUnit {
+public:
+ static SInt32 GetVectorUnitType() { return CAVectorUnit_GetType(); }
+ static bool HasVectorUnit() { return GetVectorUnitType() > kVecNone; }
+ static bool HasAltivec() { return GetVectorUnitType() == kVecAltivec; }
+ static bool HasSSE2() { return GetVectorUnitType() >= kVecSSE2; }
+ static bool HasSSE3() { return GetVectorUnitType() >= kVecSSE3; }
+ static bool HasAVX1() { return GetVectorUnitType() >= kVecAVX1; }
+ static bool HasNeon() { return GetVectorUnitType() == kVecNeon; }
+};
+#endif
+
+#endif // __CAVectorUnit_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnitTypes.h b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnitTypes.h
new file mode 100644
index 0000000000..85ff837afe
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAVectorUnitTypes.h
@@ -0,0 +1,60 @@
+/*
+ File: CAVectorUnitTypes.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAVectorUnitTypes_h__
+#define __CAVectorUnitTypes_h__
+
+enum {
+ kVecUninitialized = -1,
+ kVecNone = 0,
+ kVecAltivec = 1,
+ kVecSSE2 = 100,
+ kVecSSE3 = 101,
+ kVecAVX1 = 110,
+ kVecNeon = 200
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.cpp
new file mode 100644
index 0000000000..bb6e70cb8e
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.cpp
@@ -0,0 +1,482 @@
+/*
+ File: CAVolumeCurve.cpp
+ Abstract: CAVolumeCurve.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CAVolumeCurve.h"
+#include "CADebugMacros.h"
+#include <math.h>
+
+//=============================================================================
+// CAVolumeCurve
+//=============================================================================
+
+CAVolumeCurve::CAVolumeCurve()
+:
+ mTag(0),
+ mCurveMap(),
+ mIsApplyingTransferFunction(true),
+ mTransferFunction(kPow2Over1Curve),
+ mRawToScalarExponentNumerator(2.0f),
+ mRawToScalarExponentDenominator(1.0f)
+{
+}
+
+CAVolumeCurve::~CAVolumeCurve()
+{
+}
+
+SInt32 CAVolumeCurve::GetMinimumRaw() const
+{
+ SInt32 theAnswer = 0;
+
+ if(!mCurveMap.empty())
+ {
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+ theAnswer = theIterator->first.mMinimum;
+ }
+
+ return theAnswer;
+}
+
+SInt32 CAVolumeCurve::GetMaximumRaw() const
+{
+ SInt32 theAnswer = 0;
+
+ if(!mCurveMap.empty())
+ {
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+ std::advance(theIterator, static_cast<int>(mCurveMap.size() - 1));
+ theAnswer = theIterator->first.mMaximum;
+ }
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::GetMinimumDB() const
+{
+ Float32 theAnswer = 0;
+
+ if(!mCurveMap.empty())
+ {
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+ theAnswer = theIterator->second.mMinimum;
+ }
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::GetMaximumDB() const
+{
+ Float32 theAnswer = 0;
+
+ if(!mCurveMap.empty())
+ {
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+ std::advance(theIterator, static_cast<int>(mCurveMap.size() - 1));
+ theAnswer = theIterator->second.mMaximum;
+ }
+
+ return theAnswer;
+}
+
+void CAVolumeCurve::SetTransferFunction(UInt32 inTransferFunction)
+{
+ mTransferFunction = inTransferFunction;
+
+ // figure out the co-efficients
+ switch(inTransferFunction)
+ {
+ case kLinearCurve:
+ mIsApplyingTransferFunction = false;
+ mRawToScalarExponentNumerator = 1.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow1Over3Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 1.0f;
+ mRawToScalarExponentDenominator = 3.0f;
+ break;
+
+ case kPow1Over2Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 1.0f;
+ mRawToScalarExponentDenominator = 2.0f;
+ break;
+
+ case kPow3Over4Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 3.0f;
+ mRawToScalarExponentDenominator = 4.0f;
+ break;
+
+ case kPow3Over2Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 3.0f;
+ mRawToScalarExponentDenominator = 2.0f;
+ break;
+
+ case kPow2Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 2.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow3Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 3.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow4Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 4.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow5Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 5.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow6Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 6.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow7Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 7.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow8Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 8.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow9Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 9.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow10Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 10.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow11Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 11.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ case kPow12Over1Curve:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 12.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+
+ default:
+ mIsApplyingTransferFunction = true;
+ mRawToScalarExponentNumerator = 2.0f;
+ mRawToScalarExponentDenominator = 1.0f;
+ break;
+ };
+}
+
+void CAVolumeCurve::AddRange(SInt32 inMinRaw, SInt32 inMaxRaw, Float32 inMinDB, Float32 inMaxDB)
+{
+ CARawPoint theRaw(inMinRaw, inMaxRaw);
+ CADBPoint theDB(inMinDB, inMaxDB);
+
+ bool isOverlapped = false;
+ bool isDone = false;
+ CurveMap::iterator theIterator = mCurveMap.begin();
+ while((theIterator != mCurveMap.end()) && !isOverlapped && !isDone)
+ {
+ isOverlapped = CARawPoint::Overlap(theRaw, theIterator->first);
+ isDone = theRaw >= theIterator->first;
+
+ if(!isOverlapped && !isDone)
+ {
+ std::advance(theIterator, 1);
+ }
+ }
+
+ if(!isOverlapped)
+ {
+ mCurveMap.insert(CurveMap::value_type(theRaw, theDB));
+ }
+ else
+ {
+ DebugMessage("CAVolumeCurve::AddRange: new point overlaps");
+ }
+}
+
+void CAVolumeCurve::ResetRange()
+{
+ mCurveMap.clear();
+}
+
+bool CAVolumeCurve::CheckForContinuity() const
+{
+ bool theAnswer = true;
+
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+ if(theIterator != mCurveMap.end())
+ {
+ SInt32 theRaw = theIterator->first.mMinimum;
+ Float32 theDB = theIterator->second.mMinimum;
+ do
+ {
+ SInt32 theRawMin = theIterator->first.mMinimum;
+ SInt32 theRawMax = theIterator->first.mMaximum;
+ SInt32 theRawRange = theRawMax - theRawMin;
+
+ Float32 theDBMin = theIterator->second.mMinimum;
+ Float32 theDBMax = theIterator->second.mMaximum;
+ Float32 theDBRange = theDBMax - theDBMin;
+
+ theAnswer = theRaw == theRawMin;
+ theAnswer = theAnswer && (theDB == theDBMin);
+
+ theRaw += theRawRange;
+ theDB += theDBRange;
+
+ std::advance(theIterator, 1);
+ }
+ while((theIterator != mCurveMap.end()) && theAnswer);
+ }
+
+ return theAnswer;
+}
+
+SInt32 CAVolumeCurve::ConvertDBToRaw(Float32 inDB) const
+{
+ // clamp the value to the dB range
+ Float32 theOverallDBMin = GetMinimumDB();
+ Float32 theOverallDBMax = GetMaximumDB();
+
+ if(inDB < theOverallDBMin) inDB = theOverallDBMin;
+ if(inDB > theOverallDBMax) inDB = theOverallDBMax;
+
+ // get the first entry in the curve map;
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+
+ // initialize the answer to the minimum raw of the first item in the curve map
+ SInt32 theAnswer = theIterator->first.mMinimum;
+
+ // iterate through the curve map until we run out of dB
+ bool isDone = false;
+ while(!isDone && (theIterator != mCurveMap.end()))
+ {
+ SInt32 theRawMin = theIterator->first.mMinimum;
+ SInt32 theRawMax = theIterator->first.mMaximum;
+ SInt32 theRawRange = theRawMax - theRawMin;
+
+ Float32 theDBMin = theIterator->second.mMinimum;
+ Float32 theDBMax = theIterator->second.mMaximum;
+ Float32 theDBRange = theDBMax - theDBMin;
+
+ Float32 theDBPerRaw = theDBRange / static_cast<Float32>(theRawRange);
+
+ // figure out how many steps we are into this entry in the curve map
+ if(inDB > theDBMax)
+ {
+ // we're past the end of this one, so add in the whole range for this entry
+ theAnswer += theRawRange;
+ }
+ else
+ {
+ // it's somewhere within the current entry
+ // figure out how many steps it is
+ Float32 theNumberRawSteps = inDB - theDBMin;
+ theNumberRawSteps /= theDBPerRaw;
+
+ // only move in whole steps
+ theNumberRawSteps = roundf(theNumberRawSteps);
+
+ // add this many steps to the answer
+ theAnswer += static_cast<SInt32>(theNumberRawSteps);
+
+ // mark that we are done
+ isDone = true;
+ }
+
+ // go to the next entry in the curve map
+ std::advance(theIterator, 1);
+ }
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::ConvertRawToDB(SInt32 inRaw) const
+{
+ Float32 theAnswer = 0;
+
+ // clamp the raw value
+ SInt32 theOverallRawMin = GetMinimumRaw();
+ SInt32 theOverallRawMax = GetMaximumRaw();
+
+ if(inRaw < theOverallRawMin) inRaw = theOverallRawMin;
+ if(inRaw > theOverallRawMax) inRaw = theOverallRawMax;
+
+ // figure out how many raw steps need to be taken from the first one
+ SInt32 theNumberRawSteps = inRaw - theOverallRawMin;
+
+ // get the first item in the curve map
+ CurveMap::const_iterator theIterator = mCurveMap.begin();
+
+ // initialize the answer to the minimum dB of the first item in the curve map
+ theAnswer = theIterator->second.mMinimum;
+
+ // iterate through the curve map until we run out of steps
+ while((theNumberRawSteps > 0) && (theIterator != mCurveMap.end()))
+ {
+ // compute some values
+ SInt32 theRawMin = theIterator->first.mMinimum;
+ SInt32 theRawMax = theIterator->first.mMaximum;
+ SInt32 theRawRange = theRawMax - theRawMin;
+
+ Float32 theDBMin = theIterator->second.mMinimum;
+ Float32 theDBMax = theIterator->second.mMaximum;
+ Float32 theDBRange = theDBMax - theDBMin;
+
+ Float32 theDBPerRaw = theDBRange / static_cast<Float32>(theRawRange);
+
+ // there might be more steps than the current map entry accounts for
+ SInt32 theRawStepsToAdd = std::min(theRawRange, theNumberRawSteps);
+
+ // add this many steps worth of db to the answer;
+ theAnswer += theRawStepsToAdd * theDBPerRaw;
+
+ // figure out how many steps are left
+ theNumberRawSteps -= theRawStepsToAdd;
+
+ // go to the next map entry
+ std::advance(theIterator, 1);
+ }
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::ConvertRawToScalar(SInt32 inRaw) const
+{
+ // get some important values
+ Float32 theDBMin = GetMinimumDB();
+ Float32 theDBMax = GetMaximumDB();
+ Float32 theDBRange = theDBMax - theDBMin;
+ SInt32 theRawMin = GetMinimumRaw();
+ SInt32 theRawMax = GetMaximumRaw();
+ SInt32 theRawRange = theRawMax - theRawMin;
+
+ // range the raw value
+ if(inRaw < theRawMin) inRaw = theRawMin;
+ if(inRaw > theRawMax) inRaw = theRawMax;
+
+ // calculate the distance in the range inRaw is
+ Float32 theAnswer = static_cast<Float32>(inRaw - theRawMin) / static_cast<Float32>(theRawRange);
+
+ // only apply a curve to the scalar values if the dB range is greater than 30
+ if(mIsApplyingTransferFunction && (theDBRange > 30.0f))
+ {
+ theAnswer = powf(theAnswer, mRawToScalarExponentNumerator / mRawToScalarExponentDenominator);
+ }
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::ConvertDBToScalar(Float32 inDB) const
+{
+ SInt32 theRawValue = ConvertDBToRaw(inDB);
+ Float32 theAnswer = ConvertRawToScalar(theRawValue);
+ return theAnswer;
+}
+
+SInt32 CAVolumeCurve::ConvertScalarToRaw(Float32 inScalar) const
+{
+ // range the scalar value
+ inScalar = std::min(1.0f, std::max(0.0f, inScalar));
+
+ // get some important values
+ Float32 theDBMin = GetMinimumDB();
+ Float32 theDBMax = GetMaximumDB();
+ Float32 theDBRange = theDBMax - theDBMin;
+ SInt32 theRawMin = GetMinimumRaw();
+ SInt32 theRawMax = GetMaximumRaw();
+ SInt32 theRawRange = theRawMax - theRawMin;
+
+ // have to undo the curve if the dB range is greater than 30
+ if(mIsApplyingTransferFunction && (theDBRange > 30.0f))
+ {
+ inScalar = powf(inScalar, mRawToScalarExponentDenominator / mRawToScalarExponentNumerator);
+ }
+
+ // now we can figure out how many raw steps this is
+ Float32 theNumberRawSteps = inScalar * static_cast<Float32>(theRawRange);
+ theNumberRawSteps = roundf(theNumberRawSteps);
+
+ // the answer is the minimum raw value plus the number of raw steps
+ SInt32 theAnswer = theRawMin + static_cast<SInt32>(theNumberRawSteps);
+
+ return theAnswer;
+}
+
+Float32 CAVolumeCurve::ConvertScalarToDB(Float32 inScalar) const
+{
+ SInt32 theRawValue = ConvertScalarToRaw(inScalar);
+ Float32 theAnswer = ConvertRawToDB(theRawValue);
+ return theAnswer;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.h b/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.h
new file mode 100644
index 0000000000..4f9544682a
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAVolumeCurve.h
@@ -0,0 +1,178 @@
+/*
+ File: CAVolumeCurve.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#if !defined(__CAVolumeCurve_h__)
+#define __CAVolumeCurve_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+#include <map>
+
+//=============================================================================
+// Types
+//=============================================================================
+
+struct CARawPoint
+{
+ SInt32 mMinimum;
+ SInt32 mMaximum;
+
+ CARawPoint() : mMinimum(0), mMaximum(0) {}
+ CARawPoint(const CARawPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
+ CARawPoint(SInt32 inMinimum, SInt32 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
+ CARawPoint& operator=(const CARawPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
+
+ static bool Overlap(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum > y.mMinimum); }
+};
+
+inline bool operator<(const CARawPoint& x, const CARawPoint& y) { return x.mMinimum < y.mMinimum; }
+inline bool operator==(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
+inline bool operator!=(const CARawPoint& x, const CARawPoint& y) { return !(x == y); }
+inline bool operator<=(const CARawPoint& x, const CARawPoint& y) { return (x < y) || (x == y); }
+inline bool operator>=(const CARawPoint& x, const CARawPoint& y) { return !(x < y); }
+inline bool operator>(const CARawPoint& x, const CARawPoint& y) { return !((x < y) || (x == y)); }
+
+struct CADBPoint
+{
+ Float32 mMinimum;
+ Float32 mMaximum;
+
+ CADBPoint() : mMinimum(0), mMaximum(0) {}
+ CADBPoint(const CADBPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
+ CADBPoint(Float32 inMinimum, Float32 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
+ CADBPoint& operator=(const CADBPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
+
+ static bool Overlap(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum >= y.mMinimum); }
+};
+
+inline bool operator<(const CADBPoint& x, const CADBPoint& y) { return x.mMinimum < y.mMinimum; }
+inline bool operator==(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
+inline bool operator!=(const CADBPoint& x, const CADBPoint& y) { return !(x == y); }
+inline bool operator<=(const CADBPoint& x, const CADBPoint& y) { return (x < y) || (x == y); }
+inline bool operator>=(const CADBPoint& x, const CADBPoint& y) { return !(x < y); }
+inline bool operator>(const CADBPoint& x, const CADBPoint& y) { return !((x < y) || (x == y)); }
+
+//=============================================================================
+// CAVolumeCurve
+//=============================================================================
+
+class CAVolumeCurve
+{
+
+// Constants
+public:
+ enum
+ {
+ kLinearCurve = 0,
+ kPow1Over3Curve = 1,
+ kPow1Over2Curve = 2,
+ kPow3Over4Curve = 3,
+ kPow3Over2Curve = 4,
+ kPow2Over1Curve = 5,
+ kPow3Over1Curve = 6,
+ kPow4Over1Curve = 7,
+ kPow5Over1Curve = 8,
+ kPow6Over1Curve = 9,
+ kPow7Over1Curve = 10,
+ kPow8Over1Curve = 11,
+ kPow9Over1Curve = 12,
+ kPow10Over1Curve = 13,
+ kPow11Over1Curve = 14,
+ kPow12Over1Curve = 15
+ };
+
+// Construction/Destruction
+public:
+ CAVolumeCurve();
+ virtual ~CAVolumeCurve();
+
+// Attributes
+public:
+ UInt32 GetTag() const { return mTag; }
+ void SetTag(UInt32 inTag) { mTag = inTag; }
+ SInt32 GetMinimumRaw() const;
+ SInt32 GetMaximumRaw() const;
+ Float32 GetMinimumDB() const;
+ Float32 GetMaximumDB() const;
+
+ void SetIsApplyingTransferFunction(bool inIsApplyingTransferFunction) { mIsApplyingTransferFunction = inIsApplyingTransferFunction; }
+ UInt32 GetTransferFunction() const { return mTransferFunction; }
+ void SetTransferFunction(UInt32 inTransferFunction);
+
+// Operations
+public:
+ void AddRange(SInt32 mMinRaw, SInt32 mMaxRaw, Float32 inMinDB, Float32 inMaxDB);
+ void ResetRange();
+ bool CheckForContinuity() const;
+
+ SInt32 ConvertDBToRaw(Float32 inDB) const;
+ Float32 ConvertRawToDB(SInt32 inRaw) const;
+ Float32 ConvertRawToScalar(SInt32 inRaw) const;
+ Float32 ConvertDBToScalar(Float32 inDB) const;
+ SInt32 ConvertScalarToRaw(Float32 inScalar) const;
+ Float32 ConvertScalarToDB(Float32 inScalar) const;
+
+// Implementation
+private:
+ typedef std::map<CARawPoint, CADBPoint> CurveMap;
+
+ UInt32 mTag;
+ CurveMap mCurveMap;
+ bool mIsApplyingTransferFunction;
+ UInt32 mTransferFunction;
+ Float32 mRawToScalarExponentNumerator;
+ Float32 mRawToScalarExponentDenominator;
+
+};
+
+#endif
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAXException.cpp b/libs/appleutility/CoreAudio/PublicUtility/CAXException.cpp
new file mode 100644
index 0000000000..c2dbac5d60
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAXException.cpp
@@ -0,0 +1,49 @@
+/*
+ File: CAXException.cpp
+ Abstract: CAXException.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "CAXException.h"
+
+CAXException::WarningHandler CAXException::sWarningHandler = NULL;
diff --git a/libs/appleutility/CoreAudio/PublicUtility/CAXException.h b/libs/appleutility/CoreAudio/PublicUtility/CAXException.h
new file mode 100644
index 0000000000..90dabe97de
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/CAXException.h
@@ -0,0 +1,361 @@
+/*
+ File: CAXException.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __CAXException_h__
+#define __CAXException_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <CoreFoundation.h>
+#endif
+#include "CADebugMacros.h"
+#include <ctype.h>
+//#include <stdio.h>
+#include <string.h>
+
+
+class CAX4CCString {
+public:
+ CAX4CCString(OSStatus error) {
+ // see if it appears to be a 4-char-code
+ UInt32 beErr = CFSwapInt32HostToBig(error);
+ char *str = mStr;
+ memcpy(str + 1, &beErr, 4);
+ if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
+ str[0] = str[5] = '\'';
+ str[6] = '\0';
+ } else if (error > -200000 && error < 200000)
+ // no, format it as an integer
+ snprintf(str, sizeof(mStr), "%d", (int)error);
+ else
+ snprintf(str, sizeof(mStr), "0x%x", (int)error);
+ }
+ const char *get() const { return mStr; }
+ operator const char *() const { return mStr; }
+private:
+ char mStr[16];
+};
+
+class CAX4CCStringNoQuote {
+public:
+ CAX4CCStringNoQuote(OSStatus error) {
+ // see if it appears to be a 4-char-code
+ UInt32 beErr = CFSwapInt32HostToBig(error);
+ char *str = mStr;
+ memcpy(str, &beErr, 4);
+ if (isprint(str[0]) && isprint(str[1]) && isprint(str[2]) && isprint(str[3])) {
+ str[4] = '\0';
+ } else if (error > -200000 && error < 200000)
+ // no, format it as an integer
+ snprintf(str, sizeof(mStr), "%d", (int)error);
+ else
+ snprintf(str, sizeof(mStr), "0x%x", (int)error);
+ }
+ const char *get() const { return mStr; }
+ operator const char *() const { return mStr; }
+private:
+ char mStr[16];
+};
+
+
+// An extended exception class that includes the name of the failed operation
+class CAXException {
+public:
+ CAXException(const char *operation, OSStatus err) :
+ mError(err)
+ {
+ if (operation == NULL)
+ mOperation[0] = '\0';
+ else if (strlen(operation) >= sizeof(mOperation)) {
+ memcpy(mOperation, operation, sizeof(mOperation) - 1);
+ mOperation[sizeof(mOperation) - 1] = '\0';
+ } else
+
+ strlcpy(mOperation, operation, sizeof(mOperation));
+ }
+
+ char *FormatError(char *str, size_t strsize) const
+ {
+ return FormatError(str, strsize, mError);
+ }
+
+ char mOperation[256];
+ const OSStatus mError;
+
+ // -------------------------------------------------
+
+ typedef void (*WarningHandler)(const char *msg, OSStatus err);
+
+ static char *FormatError(char *str, size_t strsize, OSStatus error)
+ {
+ strlcpy(str, CAX4CCString(error), strsize);
+ return str;
+ }
+
+ static void Warning(const char *s, OSStatus error)
+ {
+ if (sWarningHandler)
+ (*sWarningHandler)(s, error);
+ }
+
+ static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
+private:
+ static WarningHandler sWarningHandler;
+};
+
+#if DEBUG || CoreAudio_Debug
+ #define XThrowIfError(error, operation) \
+ do { \
+ OSStatus __err = error; \
+ if (__err) { \
+ DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
+ __THROW_STOP; \
+ throw CAXException(operation, __err); \
+ } \
+ } while (0)
+
+ #define XThrowIf(condition, error, operation) \
+ do { \
+ if (condition) { \
+ OSStatus __err = error; \
+ DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
+ __THROW_STOP; \
+ throw CAXException(operation, __err); \
+ } \
+ } while (0)
+
+ #define XRequireNoError(error, label) \
+ do { \
+ OSStatus __err = error; \
+ if (__err) { \
+ DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
+ STOP; \
+ goto label; \
+ } \
+ } while (0)
+
+ #define XAssert(assertion) \
+ do { \
+ if (!(assertion)) { \
+ DebugMessageN3("%s:%d: error: failed assertion: %s", __FILE__, __LINE__, #assertion); \
+ __ASSERT_STOP; \
+ } \
+ } while (0)
+
+ #define XAssertNoError(error) \
+ do { \
+ OSStatus __err = error; \
+ if (__err) { \
+ DebugMessageN4("%s:%d: error %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
+ STOP; \
+ } \
+ } while (0)
+
+ #define ca_require_noerr(errorCode, exceptionLabel) \
+ do \
+ { \
+ int evalOnceErrorCode = (errorCode); \
+ if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
+ { \
+ DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d", \
+ #errorCode, evalOnceErrorCode, \
+ #exceptionLabel, \
+ __FILE__, \
+ __LINE__); \
+ goto exceptionLabel; \
+ } \
+ } while ( 0 )
+
+ #define ca_verify_noerr(errorCode) \
+ do \
+ { \
+ int evalOnceErrorCode = (errorCode); \
+ if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
+ { \
+ DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d", \
+ #errorCode, evalOnceErrorCode, \
+ __FILE__, \
+ __LINE__); \
+ } \
+ } while ( 0 )
+
+ #define ca_debug_string(message) \
+ do \
+ { \
+ DebugMessageN3("ca_debug_string: %s %s:%d", \
+ message, \
+ __FILE__, \
+ __LINE__); \
+ } while ( 0 )
+
+
+ #define ca_verify(assertion) \
+ do \
+ { \
+ if ( __builtin_expect(!(assertion), 0) ) \
+ { \
+ DebugMessageN3("ca_verify: %s %s:%d", \
+ #assertion, \
+ __FILE__, \
+ __LINE__); \
+ } \
+ } while ( 0 )
+
+ #define ca_require(assertion, exceptionLabel) \
+ do \
+ { \
+ if ( __builtin_expect(!(assertion), 0) ) \
+ { \
+ DebugMessageN4("ca_require: %s %s %s:%d", \
+ #assertion, \
+ #exceptionLabel, \
+ __FILE__, \
+ __LINE__); \
+ goto exceptionLabel; \
+ } \
+ } while ( 0 )
+
+ #define ca_check(assertion) \
+ do \
+ { \
+ if ( __builtin_expect(!(assertion), 0) ) \
+ { \
+ DebugMessageN3("ca_check: %s %s:%d", \
+ #assertion, \
+ __FILE__, \
+ __LINE__); \
+ } \
+ } while ( 0 )
+
+#else
+ #define XThrowIfError(error, operation) \
+ do { \
+ OSStatus __err = error; \
+ if (__err) { \
+ throw CAXException(operation, __err); \
+ } \
+ } while (0)
+
+ #define XThrowIf(condition, error, operation) \
+ do { \
+ if (condition) { \
+ OSStatus __err = error; \
+ throw CAXException(operation, __err); \
+ } \
+ } while (0)
+
+ #define XRequireNoError(error, label) \
+ do { \
+ OSStatus __err = error; \
+ if (__err) { \
+ goto label; \
+ } \
+ } while (0)
+
+ #define XAssert(assertion) \
+ do { \
+ if (!(assertion)) { \
+ } \
+ } while (0)
+
+ #define XAssertNoError(error) \
+ do { \
+ /*OSStatus __err =*/ error; \
+ } while (0)
+
+ #define ca_require_noerr(errorCode, exceptionLabel) \
+ do \
+ { \
+ if ( __builtin_expect(0 != (errorCode), 0) ) \
+ { \
+ goto exceptionLabel; \
+ } \
+ } while ( 0 )
+
+ #define ca_verify_noerr(errorCode) \
+ do \
+ { \
+ if ( 0 != (errorCode) ) \
+ { \
+ } \
+ } while ( 0 )
+
+ #define ca_debug_string(message)
+
+ #define ca_verify(assertion) \
+ do \
+ { \
+ if ( !(assertion) ) \
+ { \
+ } \
+ } while ( 0 )
+
+ #define ca_require(assertion, exceptionLabel) \
+ do \
+ { \
+ if ( __builtin_expect(!(assertion), 0) ) \
+ { \
+ goto exceptionLabel; \
+ } \
+ } while ( 0 )
+
+ #define ca_check(assertion) \
+ do \
+ { \
+ if ( !(assertion) ) \
+ { \
+ } \
+ } while ( 0 )
+
+
+#endif
+
+#define XThrow(error, operation) XThrowIf(true, error, operation)
+#define XThrowIfErr(error) XThrowIfError(error, #error)
+
+#endif // __CAXException_h__
diff --git a/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.cpp b/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.cpp
new file mode 100644
index 0000000000..98d868eb73
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.cpp
@@ -0,0 +1,149 @@
+/*
+ File: MatrixMixerVolumes.cpp
+ Abstract: MatrixMixerVolumes.h
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#include "MatrixMixerVolumes.h"
+#include "CAXException.h"
+
+OSStatus NumberChannels (AudioUnit au,
+ AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans);
+
+
+OSStatus PrintBuses (FILE* file, const char* str, AudioUnit au, AudioUnitScope inScope)
+{
+ OSStatus result;
+ UInt32 busCount;
+ UInt32 theSize = sizeof(busCount);
+
+ ca_require_noerr (result = AudioUnitGetProperty (au, kAudioUnitProperty_ElementCount,
+ inScope, 0, &busCount, &theSize), home);
+
+ fprintf (file, "\t%s Elements:\n\t\t", str);
+ for (UInt32 i = 0; i < busCount; ++i) {
+ Float32 val;
+ ca_require_noerr (result = AudioUnitGetParameter (au, kMatrixMixerParam_Enable, inScope, i, &val), home);
+ UInt32 numChans;
+ ca_require_noerr (result = NumberChannels (au, inScope, i, numChans), home);
+ char frameCharStart = (val != 0 ? '[' : '{');
+ char frameCharEnd = (val != 0 ? ']' : '}');
+ fprintf (file, "%d:%c%d, %c%c ", (int)i, frameCharStart, (int)numChans, (val != 0 ? 'T' : 'F'), frameCharEnd);
+ }
+ fprintf (file, "\n");
+home:
+ return result;
+}
+
+void PrintMatrixMixerVolumes (FILE* file, AudioUnit au)
+{
+ UInt32 dims[2];
+ UInt32 theSize = sizeof(UInt32) * 2;
+ Float32 *theVols = NULL;
+ OSStatus result;
+
+// this call will fail if the unit is NOT initialized as it would present an incomplete state
+ ca_require_noerr (result = AudioUnitGetProperty (au, kAudioUnitProperty_MatrixDimensions,
+ kAudioUnitScope_Global, 0, dims, &theSize), home);
+
+ theSize = ((dims[0] + 1) * (dims[1] + 1)) * sizeof(Float32);
+
+ theVols = static_cast<Float32*> (malloc (theSize));
+
+ ca_require_noerr (result = AudioUnitGetProperty (au, kAudioUnitProperty_MatrixLevels,
+ kAudioUnitScope_Global, 0, theVols, &theSize), home);
+
+home:
+ if (result) {
+ if (theVols)
+ free(theVols);
+ return;
+ }
+
+ theSize /= sizeof(Float32);
+
+ unsigned int inputs = dims[0];
+ unsigned int outputs = dims[1];
+
+ fprintf (file, "\tInput Channels = %d, Output Channels = %d\n", (int)dims[0], (int)dims[1]);
+ PrintBuses (file, "Input", au, kAudioUnitScope_Input);
+ PrintBuses (file, "Output", au, kAudioUnitScope_Output);
+ fprintf (file, "\tGlobal Volume: %.3f\n", theVols [theSize - 1]);
+ for (unsigned int i = 0; i < (inputs + 1); ++i) {
+ if (i < inputs) {
+ fprintf (file, "\t%.3f ", theVols[(i + 1) * (outputs + 1) - 1]);
+
+ for (unsigned int j = 0; j < outputs; ++j)
+ fprintf (file, "(%.3f) ", theVols[(i * (outputs + 1)) + j]);
+ } else {
+ fprintf (file, "\t ");
+ for (unsigned int j = 0; j < outputs; ++j)
+ fprintf (file, " %.3f ", theVols[(i * (outputs + 1)) + j]);
+ }
+ fprintf (file, "\n");
+ }
+
+#if 0
+ for (unsigned int i = 0; i < theSize; ++i)
+ printf ("%f, ", theVols[i]);
+#endif
+ free(theVols);
+}
+
+// Utility routine that gets the number of channels from an audio unit
+OSStatus NumberChannels (AudioUnit au,
+ AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans)
+{
+ AudioStreamBasicDescription desc;
+ UInt32 dataSize = sizeof (AudioStreamBasicDescription);
+ OSStatus result = AudioUnitGetProperty (au, kAudioUnitProperty_StreamFormat,
+ inScope, inEl,
+ &desc, &dataSize);
+ if (!result)
+ outChans = desc.mChannelsPerFrame;
+ return result;
+}
diff --git a/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.h b/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.h
new file mode 100644
index 0000000000..06854f0774
--- /dev/null
+++ b/libs/appleutility/CoreAudio/PublicUtility/MatrixMixerVolumes.h
@@ -0,0 +1,71 @@
+/*
+ File: MatrixMixerVolumes.h
+ Abstract: Part of CoreAudio Utility Classes
+ Version: 1.1
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+
+*/
+#ifndef __MatrixMixerVolumes_h__
+#define __MatrixMixerVolumes_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioUnit/AudioUnit.h>
+#else
+ #include <AudioUnit.h>
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// prints the matrix mixer volumes of a specific audio unit to the given file
+void PrintMatrixMixerVolumes (FILE* file, AudioUnit au);
+
+// prints the mixer volumes for the specific scope of the audio unit
+// results will be printed to the speficied file "file" with identifiying string tag "str"
+OSStatus PrintBuses (FILE* file, char* str, AudioUnit au, AudioUnitScope inScope);
+#if defined(__cplusplus)
+}
+#endif
+
+#endif