mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
Added libappleutility from /Developer/Examples/CoreAudio/PublicUtility
More PluginManager refactoring Rearranged AUPluginInfo for better maintainability git-svn-id: svn://localhost/ardour2/trunk@748 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c3a00bf1e9
commit
58b71b15d8
31 changed files with 5586 additions and 39 deletions
520
libs/appleutility/CAStreamBasicDescription.cpp
Normal file
520
libs/appleutility/CAStreamBasicDescription.cpp
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, 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 Computer, 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.
|
||||
*/
|
||||
/*=============================================================================
|
||||
CAStreamBasicDescription.cpp
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "CAConditionalMacros.h"
|
||||
|
||||
#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 more earlier versions of the OS, so please keep that in mind when editing it
|
||||
|
||||
const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CAStreamBasicDescription::PrintFormat(FILE *f, const char *indent, const char *name) const
|
||||
{
|
||||
fprintf(f, "%s%s ", indent, name);
|
||||
char formatID[5];
|
||||
*(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
|
||||
formatID[4] = '\0';
|
||||
fprintf(f, "%2ld ch, %6.0f Hz, '%-4.4s' (0x%08lX) ",
|
||||
NumberChannels(), mSampleRate, formatID,
|
||||
mFormatFlags);
|
||||
if (mFormatID == kAudioFormatLinearPCM) {
|
||||
bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
|
||||
int wordSize = 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)
|
||||
sprintf(packed, "packed in %d bytes", wordSize);
|
||||
else
|
||||
sprintf(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') ? ", " : "";
|
||||
|
||||
fprintf(f, "%ld-bit%s%s %s%s%s%s%s\n",
|
||||
mBitsPerChannel, endian, sign, floatInt,
|
||||
commaSpace, packed, align, deinter);
|
||||
} else if (mFormatID == 'alac') { // 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)
|
||||
fprintf(f, "from %d-bit source, ", sourceBits);
|
||||
else
|
||||
fprintf(f, "from UNKNOWN source bit depth, ");
|
||||
|
||||
fprintf(f, "%ld frames/packet\n", mFramesPerPacket);
|
||||
}
|
||||
else
|
||||
fprintf(f, "%ld bits/channel, %ld bytes/packet, %ld frames/packet, %ld bytes/frame\n",
|
||||
mBitsPerChannel, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame);
|
||||
}
|
||||
|
||||
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 is 32 bit native endian floats
|
||||
ioDescription.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
|
||||
ioDescription.mBytesPerPacket = sizeof(Float32) * ioDescription.mChannelsPerFrame;
|
||||
ioDescription.mFramesPerPacket = 1;
|
||||
ioDescription.mBytesPerFrame = sizeof(Float32) * ioDescription.mChannelsPerFrame;
|
||||
ioDescription.mBitsPerChannel = 8 * sizeof(Float32);
|
||||
}
|
||||
}
|
||||
|
||||
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, bool inAbbreviate)
|
||||
{
|
||||
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)
|
||||
{
|
||||
sprintf(outName, "%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
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%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
|
||||
{
|
||||
sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(theEndianString != NULL)
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%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
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thePackingString != NULL)
|
||||
{
|
||||
sprintf(outName, "%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
|
||||
{
|
||||
sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioFormatAC3:
|
||||
strcpy(outName, "AC-3");
|
||||
break;
|
||||
|
||||
case kAudioFormat60958AC3:
|
||||
strcpy(outName, "AC-3 for SPDIF");
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char* the4CCString = (char*)&inDescription.mFormatID;
|
||||
outName[0] = the4CCString[0];
|
||||
outName[1] = the4CCString[1];
|
||||
outName[2] = the4CCString[2];
|
||||
outName[3] = the4CCString[3];
|
||||
outName[4] = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
|
||||
{
|
||||
UInt32 xFlags = x.mFormatFlags;
|
||||
UInt32 yFlags = y.mFormatFlags;
|
||||
|
||||
// match wildcards
|
||||
if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
|
||||
return true;
|
||||
|
||||
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 & ~kAudioFormatFlagIsAlignedHigh;
|
||||
yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
|
||||
}
|
||||
|
||||
// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
|
||||
if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
|
||||
xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
|
||||
yFlags = yFlags & ~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 & ~kAudioFormatFlagIsBigEndian;
|
||||
}
|
||||
if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
|
||||
{
|
||||
yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
|
||||
}
|
||||
|
||||
// if the number of channels is 0 or 1, we don't care about non-interleavedness
|
||||
if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) {
|
||||
xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
|
||||
yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
return xFlags == yFlags;
|
||||
}
|
||||
|
||||
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
|
||||
{
|
||||
// the semantics for equality are:
|
||||
// 1) Values must match exactly
|
||||
// 2) wildcard's are ignored in the comparison
|
||||
|
||||
#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
|
||||
|
||||
return
|
||||
// check the sample rate
|
||||
(fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
|
||||
|
||||
// check the format ids
|
||||
&& MATCH(mFormatID)
|
||||
|
||||
// check the format flags
|
||||
&& MatchFormatFlags(x, y)
|
||||
|
||||
// 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 SanityCheck(const AudioStreamBasicDescription& x)
|
||||
{
|
||||
return (x.mSampleRate >= 0.);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue