Playlist Generator
1.0
|
00001 /* 00002 00003 File: CAStreamBasicDescription.h 00004 Abstract: Helper class for audio stream descriptions 00005 Version: 1.5 00006 00007 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 00008 Inc. ("Apple") in consideration of your agreement to the following 00009 terms, and your use, installation, modification or redistribution of 00010 this Apple software constitutes acceptance of these terms. If you do 00011 not agree with these terms, please do not use, install, modify or 00012 redistribute this Apple software. 00013 00014 In consideration of your agreement to abide by the following terms, and 00015 subject to these terms, Apple grants you a personal, non-exclusive 00016 license, under Apple's copyrights in this original Apple software (the 00017 "Apple Software"), to use, reproduce, modify and redistribute the Apple 00018 Software, with or without modifications, in source and/or binary forms; 00019 provided that if you redistribute the Apple Software in its entirety and 00020 without modifications, you must retain this notice and the following 00021 text and disclaimers in all such redistributions of the Apple Software. 00022 Neither the name, trademarks, service marks or logos of Apple Inc. may 00023 be used to endorse or promote products derived from the Apple Software 00024 without specific prior written permission from Apple. Except as 00025 expressly stated in this notice, no other rights or licenses, express or 00026 implied, are granted by Apple herein, including but not limited to any 00027 patent rights that may be infringed by your derivative works or by other 00028 works in which the Apple Software may be incorporated. 00029 00030 The Apple Software is provided by Apple on an "AS IS" basis. APPLE 00031 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 00032 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 00033 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 00034 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 00035 00036 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 00037 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00038 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00039 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 00040 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 00041 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 00042 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 00043 POSSIBILITY OF SUCH DAMAGE. 00044 00045 Copyright (C) 2008 Apple Inc. All Rights Reserved. 00046 00047 00048 */ 00049 00050 00051 #ifndef __CAStreamBasicDescription_h__ 00052 #define __CAStreamBasicDescription_h__ 00053 00054 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) 00055 #include <CoreAudio/CoreAudioTypes.h> 00056 #include <CoreFoundation/CoreFoundation.h> 00057 #else 00058 #include "CoreAudioTypes.h" 00059 #include "CoreFoundation.h" 00060 #endif 00061 00062 #include "CADebugMacros.h" 00063 #include <string.h> // for memset, memcpy 00064 #include <stdio.h> // for FILE * 00065 00066 #pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it 00067 00068 // define Leopard specific symbols for backward compatibility if applicable 00069 #if COREAUDIOTYPES_VERSION < 1050 00070 typedef Float32 AudioSampleType; 00071 enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; 00072 #endif 00073 #if COREAUDIOTYPES_VERSION < 1051 00074 typedef Float32 AudioUnitSampleType; 00075 #endif 00076 00077 // define the IsMixable format flag for all versions of the system 00078 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) 00079 enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; 00080 #else 00081 enum { kIsNonMixableFlag = (1L << 6) }; 00082 #endif 00083 00084 //============================================================================= 00085 // CAStreamBasicDescription 00086 // 00087 // This is a wrapper class for the AudioStreamBasicDescription struct. 00088 // It adds a number of convenience routines, but otherwise adds nothing 00089 // to the footprint of the original struct. 00090 //============================================================================= 00091 class CAStreamBasicDescription : 00092 public AudioStreamBasicDescription 00093 { 00094 00095 // Constants 00096 public: 00097 static const AudioStreamBasicDescription sEmpty; 00098 00099 // Construction/Destruction 00100 public: 00101 CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); } 00102 00103 CAStreamBasicDescription(const AudioStreamBasicDescription &desc) 00104 { 00105 SetFrom(desc); 00106 } 00107 00108 CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, 00109 UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, 00110 UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, 00111 UInt32 inBitsPerChannel, UInt32 inFormatFlags); 00112 00113 // Assignment 00114 CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } 00115 00116 void SetFrom(const AudioStreamBasicDescription &desc) 00117 { 00118 memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); 00119 } 00120 00121 // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 00122 // 00123 // interrogation 00124 00125 bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } 00126 00127 bool PackednessIsSignificant() const 00128 { 00129 Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); 00130 return (SampleWordSize() << 3) != mBitsPerChannel; 00131 } 00132 00133 bool AlignmentIsSignificant() const 00134 { 00135 return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; 00136 } 00137 00138 bool IsInterleaved() const 00139 { 00140 return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); 00141 } 00142 00143 // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: 00144 UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } 00145 UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } 00146 UInt32 NumberChannels() const { return mChannelsPerFrame; } 00147 UInt32 SampleWordSize() const { 00148 return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; 00149 } 00150 00151 UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } 00152 UInt32 BytesToFrames(UInt32 nbytes) const { 00153 Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); 00154 return nbytes / mBytesPerFrame; 00155 } 00156 00157 bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const 00158 { 00159 return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); 00160 } 00161 00162 // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 00163 // 00164 // manipulation 00165 00166 void SetCanonical(UInt32 nChannels, bool interleaved) 00167 // note: leaves sample rate untouched 00168 { 00169 mFormatID = kAudioFormatLinearPCM; 00170 #if CA_ENV_MACOSX 00171 int sampleSize = sizeof(Float32); 00172 mFormatFlags = kAudioFormatFlagsNativeFloatPacked; 00173 #else 00174 int sampleSize = sizeof(AudioSampleType); 00175 mFormatFlags = kAudioFormatFlagsCanonical; 00176 #endif 00177 mBitsPerChannel = 8 * sampleSize; 00178 mChannelsPerFrame = nChannels; 00179 mFramesPerPacket = 1; 00180 if (interleaved) 00181 mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; 00182 else { 00183 mBytesPerPacket = mBytesPerFrame = sampleSize; 00184 mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 00185 } 00186 } 00187 00188 bool IsCanonical() const 00189 { 00190 if (mFormatID != kAudioFormatLinearPCM) return false; 00191 UInt32 reqFormatFlags; 00192 #if (COREAUDIOTYPES_VERSION <= 1050) 00193 UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh); 00194 #else 00195 UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask); 00196 #endif 00197 bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; 00198 #if CA_ENV_MACOSX 00199 unsigned sampleSize = sizeof(Float32); 00200 reqFormatFlags = kAudioFormatFlagsNativeFloatPacked; 00201 #else 00202 unsigned sampleSize = sizeof(AudioSampleType); 00203 reqFormatFlags = kAudioFormatFlagsCanonical; 00204 #endif 00205 UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; 00206 00207 return ((mFormatFlags & flagsMask) == reqFormatFlags 00208 && mBitsPerChannel == 8 * sampleSize 00209 && mFramesPerPacket == 1 00210 && mBytesPerFrame == reqFrameSize 00211 && mBytesPerPacket == reqFrameSize); 00212 } 00213 00214 void SetAUCanonical(UInt32 nChannels, bool interleaved) 00215 { 00216 mFormatID = kAudioFormatLinearPCM; 00217 #if CA_PREFER_FIXED_POINT 00218 mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); 00219 #else 00220 mFormatFlags = kAudioFormatFlagsCanonical; 00221 #endif 00222 mChannelsPerFrame = nChannels; 00223 mFramesPerPacket = 1; 00224 mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); 00225 if (interleaved) 00226 mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); 00227 else { 00228 mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); 00229 mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 00230 } 00231 } 00232 00233 void ChangeNumberChannels(UInt32 nChannels, bool interleaved) 00234 // alter an existing format 00235 { 00236 Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); 00237 UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING 00238 if (wordSize == 0) 00239 wordSize = (mBitsPerChannel + 7) / 8; 00240 mChannelsPerFrame = nChannels; 00241 mFramesPerPacket = 1; 00242 if (interleaved) { 00243 mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; 00244 mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved; 00245 } else { 00246 mBytesPerPacket = mBytesPerFrame = wordSize; 00247 mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 00248 } 00249 } 00250 00251 // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 00252 // 00253 // other 00254 00255 bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; 00256 00257 void Print() const { 00258 Print (stdout); 00259 } 00260 00261 void Print(FILE* file) const { 00262 PrintFormat (file, "", "AudioStreamBasicDescription:"); 00263 } 00264 00265 void PrintFormat(FILE *f, const char *indent, const char *name) const { 00266 char buf[256]; 00267 fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); 00268 } 00269 00270 void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline 00271 char buf[256]; 00272 fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); 00273 } 00274 00275 char * AsString(char *buf, size_t bufsize) const; 00276 00277 static void Print (const AudioStreamBasicDescription &inDesc) 00278 { 00279 CAStreamBasicDescription desc(inDesc); 00280 desc.Print (); 00281 } 00282 00283 OSStatus Save(CFPropertyListRef *outData) const; 00284 00285 OSStatus Restore(CFPropertyListRef &inData); 00286 00287 // Operations 00288 static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } 00289 static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); 00290 static void ResetFormat(AudioStreamBasicDescription& ioDescription); 00291 static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); 00292 static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate); 00293 #if CoreAudio_Debug 00294 static void PrintToLog(const AudioStreamBasicDescription& inDesc); 00295 #endif 00296 }; 00297 00298 bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); 00299 bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); 00300 #if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) 00301 inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } 00302 inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } 00303 inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } 00304 inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } 00305 #endif 00306 00307 bool SanityCheck(const AudioStreamBasicDescription& x); 00308 00309 00310 #endif // __CAStreamBasicDescription_h__