Jamoma API  0.6.0.a19
CAStreamBasicDescription.h
1 /* Copyright © 2007 Apple Inc. All Rights Reserved.
2 
3  Disclaimer: IMPORTANT: This Apple software is supplied to you by
4  Apple Inc. ("Apple") in consideration of your agreement to the
5  following terms, and your use, installation, modification or
6  redistribution of this Apple software constitutes acceptance of these
7  terms. If you do not agree with these terms, please do not use,
8  install, modify or redistribute this Apple software.
9 
10  In consideration of your agreement to abide by the following terms, and
11  subject to these terms, Apple grants you a personal, non-exclusive
12  license, under Apple's copyrights in this original Apple software (the
13  "Apple Software"), to use, reproduce, modify and redistribute the Apple
14  Software, with or without modifications, in source and/or binary forms;
15  provided that if you redistribute the Apple Software in its entirety and
16  without modifications, you must retain this notice and the following
17  text and disclaimers in all such redistributions of the Apple Software.
18  Neither the name, trademarks, service marks or logos of Apple Inc.
19  may be used to endorse or promote products derived from the Apple
20  Software without specific prior written permission from Apple. Except
21  as expressly stated in this notice, no other rights or licenses, express
22  or implied, are granted by Apple herein, including but not limited to
23  any patent rights that may be infringed by your derivative works or by
24  other works in which the Apple Software may be incorporated.
25 
26  The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
31 
32  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 #ifndef __CAStreamBasicDescription_h__
42 #define __CAStreamBasicDescription_h__
43 
44 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
45  #include <CoreAudio/CoreAudioTypes.h>
46  #include <CoreFoundation/CoreFoundation.h>
47 #else
48  #include "CoreAudioTypes.h"
49  #include "CoreFoundation.h"
50 #endif
51 
52 #include "CADebugMacros.h"
53 #include <string.h> // for memset, memcpy
54 #include <stdio.h> // for FILE *
55 
56 #pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
57 
58 extern char *CAStringForOSType (OSType t, char *writeLocation);
59 
60 // define Leopard specific symbols for backward compatibility if applicable
61 #if COREAUDIOTYPES_VERSION < 1050
62 typedef Float32 AudioSampleType;
63 enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
64 #endif
65 #if COREAUDIOTYPES_VERSION < 1051
66 typedef Float32 AudioUnitSampleType;
67 enum {
68  kLinearPCMFormatFlagsSampleFractionShift = 7,
69  kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
70 };
71 #endif
72 
73 // define the IsMixable format flag for all versions of the system
74 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
75  enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
76 #else
77  enum { kIsNonMixableFlag = (1L << 6) };
78 #endif
79 
80 //=============================================================================
81 // CAStreamBasicDescription
82 //
83 // This is a wrapper class for the AudioStreamBasicDescription struct.
84 // It adds a number of convenience routines, but otherwise adds nothing
85 // to the footprint of the original struct.
86 //=============================================================================
87 class CAStreamBasicDescription :
88  public AudioStreamBasicDescription
89 {
90 
91 // Constants
92 public:
93  static const AudioStreamBasicDescription sEmpty;
94 
95 // Construction/Destruction
96 public:
97  CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); }
98 
99  CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
100  {
101  SetFrom(desc);
102  }
103 
104  CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
105  UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
106  UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
107  UInt32 inBitsPerChannel, UInt32 inFormatFlags);
108 
109 // Assignment
110  CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
111 
112  void SetFrom(const AudioStreamBasicDescription &desc)
113  {
114  memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
115  }
116 
117  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
118  //
119  // interrogation
120 
121  bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
122 
123  bool PackednessIsSignificant() const
124  {
125  Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
126  return (SampleWordSize() << 3) != mBitsPerChannel;
127  }
128 
129  bool AlignmentIsSignificant() const
130  {
131  return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
132  }
133 
134  bool IsInterleaved() const
135  {
136  return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
137  }
138 
139  bool IsNativeEndian() const
140  {
141  return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
142  }
143 
144  // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
145  UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
146  UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
147  UInt32 NumberChannels() const { return mChannelsPerFrame; }
148  UInt32 SampleWordSize() const {
149  return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0;
150  }
151 
152  UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
153  UInt32 BytesToFrames(UInt32 nbytes) const {
154  Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
155  return nbytes / mBytesPerFrame;
156  }
157 
158  bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
159  {
160  return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
161  }
162 
163  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
164  //
165  // manipulation
166 
167  void SetCanonical(UInt32 nChannels, bool interleaved)
168  // note: leaves sample rate untouched
169  {
170  mFormatID = kAudioFormatLinearPCM;
171  int sampleSize = SizeOf32(AudioSampleType);
172  mFormatFlags = kAudioFormatFlagsCanonical;
173  mBitsPerChannel = 8 * sampleSize;
174  mChannelsPerFrame = nChannels;
175  mFramesPerPacket = 1;
176  if (interleaved)
177  mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
178  else {
179  mBytesPerPacket = mBytesPerFrame = sampleSize;
180  mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
181  }
182  }
183 
184  bool IsCanonical() const
185  {
186  if (mFormatID != kAudioFormatLinearPCM) return false;
187  UInt32 reqFormatFlags;
188  UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagsSampleFractionMask);
189  bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
190  unsigned sampleSize = SizeOf32(AudioSampleType);
191  reqFormatFlags = kAudioFormatFlagsCanonical;
192  UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
193 
194  return ((mFormatFlags & flagsMask) == reqFormatFlags
195  && mBitsPerChannel == 8 * sampleSize
196  && mFramesPerPacket == 1
197  && mBytesPerFrame == reqFrameSize
198  && mBytesPerPacket == reqFrameSize);
199  }
200 
201  void SetAUCanonical(UInt32 nChannels, bool interleaved)
202  {
203  mFormatID = kAudioFormatLinearPCM;
204 #if CA_PREFER_FIXED_POINT
205  mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
206 #else
207  mFormatFlags = kAudioFormatFlagsCanonical;
208 #endif
209  mChannelsPerFrame = nChannels;
210  mFramesPerPacket = 1;
211  mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
212  if (interleaved)
213  mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
214  else {
215  mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
216  mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
217  }
218  }
219 
220  void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
221  // alter an existing format
222  {
223  Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
224  UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
225  if (wordSize == 0)
226  wordSize = (mBitsPerChannel + 7) / 8;
227  mChannelsPerFrame = nChannels;
228  mFramesPerPacket = 1;
229  if (interleaved) {
230  mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
231  mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
232  } else {
233  mBytesPerPacket = mBytesPerFrame = wordSize;
234  mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
235  }
236  }
237 
238  // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
239  //
240  // other
241 
242  bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
243 
244  void Print() const {
245  Print (stdout);
246  }
247 
248  void Print(FILE* file) const {
249  PrintFormat (file, "", "AudioStreamBasicDescription:");
250  }
251 
252  void PrintFormat(FILE *f, const char *indent, const char *name) const {
253  char buf[256];
254  fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
255  }
256 
257  void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
258  char buf[256];
259  fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
260  }
261 
262  char * AsString(char *buf, size_t bufsize) const;
263 
264  static void Print (const AudioStreamBasicDescription &inDesc)
265  {
266  CAStreamBasicDescription desc(inDesc);
267  desc.Print ();
268  }
269 
270  OSStatus Save(CFPropertyListRef *outData) const;
271 
272  OSStatus Restore(CFPropertyListRef &inData);
273 
274 // Operations
275  static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
276  static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
277  static void ResetFormat(AudioStreamBasicDescription& ioDescription);
278  static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
279  static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate);
280 #if CoreAudio_Debug
281  static void PrintToLog(const AudioStreamBasicDescription& inDesc);
282 #endif
283 };
284 
285 bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
286 bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
287 #if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
288 inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
289 inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
290 inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
291 inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
292 #endif
293 
294 bool SanityCheck(const AudioStreamBasicDescription& x);
295 
296 
297 #endif // __CAStreamBasicDescription_h__
bool TTFOUNDATION_EXPORT operator!=(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for inequality.
Definition: TTObject.cpp:173
bool TTFOUNDATION_EXPORT operator==(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for equality.
Definition: TTObject.cpp:167