Playlist Generator  1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Defines
CAStreamBasicDescription.h
Go to the documentation of this file.
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__