Jamoma API  0.6.0.a19
CABufferList.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 __CABufferList_h__
42 #define __CABufferList_h__
43 
44 #include <stddef.h>
45 #include "CAStreamBasicDescription.h"
46 #include "CAXException.h"
47 
48 void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &fmt, const char *label=NULL);
49 void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label=NULL);
50 extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize);
51 extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullOK=false);
52 
53 /* ____________________________________________________________________________
54 // CABufferList - variable length buffer list
55 
56  This class is designed for use in non-simplistic cases. For AudioUnits, AUBufferList
57  is preferred.
58 
59  CABufferList can be used in one of two ways:
60  - as mutable pointers into non-owned memory
61  - as an immutable array of buffers (owns its own memory).
62 
63  All buffers are assumed to have the same format (number of channels, word size), so that
64  we can assume their mDataByteSizes are all the same.
65 ____________________________________________________________________________ */
66 class CABufferList {
67 public:
68  void * operator new(size_t /*size*/, int nBuffers) {
69  return ::operator new(sizeof(CABufferList) + (nBuffers-1) * sizeof(AudioBuffer));
70  }
71  static CABufferList * New(const char *name, const CAStreamBasicDescription &format)
72  {
73  UInt32 numBuffers = format.NumberChannelStreams(), channelsPerBuffer = format.NumberInterleavedChannels();
74  return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
75  }
76 
77 protected:
78  CABufferList(const char *name, UInt32 numBuffers, UInt32 channelsPerBuffer) :
79  mName(name),
80  mBufferMemory(NULL)
81  {
82  //XAssert(numBuffers > 0 /*&& channelsPerBuffer > 0*/);
83  mNumberBuffers = numBuffers;
84  AudioBuffer *buf = mBuffers;
85  for (UInt32 i = mNumberBuffers; i--; ++buf) {
86  buf->mNumberChannels = channelsPerBuffer;
87  buf->mDataByteSize = 0;
88  buf->mData = NULL;
89  }
90  }
91 
92 public:
93  ~CABufferList()
94  {
95  if (mBufferMemory)
96  delete[] mBufferMemory;
97  }
98 
99  const char * Name() { return mName; }
100 
101  const AudioBufferList & GetBufferList() const { return *(AudioBufferList *)&mNumberBuffers; }
102 
103  AudioBufferList & GetModifiableBufferList()
104  {
105  VerifyNotTrashingOwnedBuffer();
106  return _GetBufferList();
107  }
108 
109  UInt32 GetNumberBuffers() const { return mNumberBuffers; }
110 
111  UInt32 GetNumBytes() const
112  {
113  return mBuffers[0].mDataByteSize;
114  }
115 
116  void SetBytes(UInt32 nBytes, void *data)
117  {
118  VerifyNotTrashingOwnedBuffer();
119  XAssert(mNumberBuffers == 1);
120  mBuffers[0].mDataByteSize = nBytes;
121  mBuffers[0].mData = data;
122  }
123 
124  void CopyAllFrom(CABufferList *srcbl, CABufferList *ptrbl)
125  // copies bytes from srcbl
126  // make ptrbl reflect the length copied
127  // note that srcbl may be same as ptrbl!
128  {
129  // Note that this buffer *can* own memory and its pointers/lengths are not
130  // altered; only its buffer contents, which are copied from srcbl.
131  // The pointers/lengths in ptrbl are updated to reflect the addresses/lengths
132  // of the copied data, and srcbl's contents are consumed.
133  ptrbl->VerifyNotTrashingOwnedBuffer();
134  UInt32 nBytes = srcbl->GetNumBytes();
135  AudioBuffer *mybuf = mBuffers, *srcbuf = srcbl->mBuffers,
136  *ptrbuf = ptrbl->mBuffers;
137  for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf, ++ptrbuf) {
138  memmove(mybuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
139  ptrbuf->mData = mybuf->mData;
140  ptrbuf->mDataByteSize = srcbuf->mDataByteSize;
141  }
142  if (srcbl != ptrbl)
143  srcbl->BytesConsumed(nBytes);
144  }
145 
146  void AppendFrom(CABufferList *blp, UInt32 nBytes)
147  {
148  VerifyNotTrashingOwnedBuffer();
149  AudioBuffer *mybuf = mBuffers, *srcbuf = blp->mBuffers;
150  for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf) {
151  XAssert(nBytes <= srcbuf->mDataByteSize);
152  memcpy((Byte *)mybuf->mData + mybuf->mDataByteSize, srcbuf->mData, nBytes);
153  mybuf->mDataByteSize += nBytes;
154  }
155  blp->BytesConsumed(nBytes);
156  }
157 
158  void PadWithZeroes(UInt32 desiredBufferSize)
159  // for cases where an algorithm (e.g. SRC) requires some
160  // padding to create silence following end-of-file
161  {
162  VerifyNotTrashingOwnedBuffer();
163  if (GetNumBytes() > desiredBufferSize) return;
164  AudioBuffer *buf = mBuffers;
165  for (UInt32 i = mNumberBuffers; i--; ++buf) {
166  memset((Byte *)buf->mData + buf->mDataByteSize, 0, desiredBufferSize - buf->mDataByteSize);
167  buf->mDataByteSize = desiredBufferSize;
168  }
169  }
170 
171  void SetToZeroes(UInt32 nBytes)
172  {
173  VerifyNotTrashingOwnedBuffer();
174  AudioBuffer *buf = mBuffers;
175  for (UInt32 i = mNumberBuffers; i--; ++buf) {
176  memset((Byte *)buf->mData, 0, nBytes);
177  buf->mDataByteSize = nBytes;
178  }
179  }
180 
181  void Reset()
182  {
183  DeallocateBuffers();
184  }
185 
186  Boolean SameDataAs(const CABufferList* anotherBufferList)
187  {
188  // check to see if two buffer lists point to the same memory.
189  if (mNumberBuffers != anotherBufferList->mNumberBuffers) return false;
190 
191  for (UInt32 i = 0; i < mNumberBuffers; ++i) {
192  if (mBuffers[i].mData != anotherBufferList->mBuffers[i].mData) return false;
193  }
194  return true;
195  }
196 
197  void BytesConsumed(UInt32 nBytes)
198  // advance buffer pointers, decrease buffer sizes
199  {
200  VerifyNotTrashingOwnedBuffer();
201  AudioBuffer *buf = mBuffers;
202  for (UInt32 i = mNumberBuffers; i--; ++buf) {
203  XAssert(nBytes <= buf->mDataByteSize);
204  buf->mData = (Byte *)buf->mData + nBytes;
205  buf->mDataByteSize -= nBytes;
206  }
207  }
208 
209  void SetFrom(const AudioBufferList *abl)
210  {
211  VerifyNotTrashingOwnedBuffer();
212  memcpy(&_GetBufferList(), abl, (char *)&abl->mBuffers[abl->mNumberBuffers] - (char *)abl);
213  }
214 
215  void SetFrom(const CABufferList *blp)
216  {
217  SetFrom(&blp->GetBufferList());
218  }
219 
220  void SetFrom(const AudioBufferList *abl, UInt32 nBytes)
221  {
222  VerifyNotTrashingOwnedBuffer();
223  AudioBuffer *mybuf = mBuffers;
224  const AudioBuffer *srcbuf = abl->mBuffers;
225  for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf) {
226  mybuf->mNumberChannels = srcbuf->mNumberChannels;
227  mybuf->mDataByteSize = nBytes;
228  mybuf->mData = srcbuf->mData;
229  }
230  }
231 
232  void SetFrom(const CABufferList *blp, UInt32 nBytes)
233  {
234  SetFrom(&blp->GetBufferList(), nBytes);
235  }
236 
237  AudioBufferList * ToAudioBufferList(AudioBufferList *abl) const
238  {
239  memcpy(abl, &GetBufferList(), (char *)&abl->mBuffers[mNumberBuffers] - (char *)abl);
240  return abl;
241  }
242 
243  void AllocateBuffers(UInt32 nBytes);
244  void AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inCopyFromList, CABufferList *inSetPtrList);
245 
246  void DeallocateBuffers();
247 
248  void UseExternalBuffer(Byte *ptr, UInt32 nBytes);
249 
250  void AdvanceBufferPointers(UInt32 nBytes)
251  // this is for bufferlists that function simply as
252  // an array of pointers into another bufferlist, being advanced,
253  // as in RenderOutput implementations
254  {
255  VerifyNotTrashingOwnedBuffer();
256  AudioBuffer *buf = mBuffers;
257  for (UInt32 i = mNumberBuffers; i--; ++buf) {
258  buf->mData = (Byte *)buf->mData + nBytes;
259  buf->mDataByteSize -= nBytes;
260  }
261  }
262 
263  void SetNumBytes(UInt32 nBytes)
264  {
265  VerifyNotTrashingOwnedBuffer();
266  AudioBuffer *buf = mBuffers;
267  for (UInt32 i = mNumberBuffers; i--; ++buf)
268  buf->mDataByteSize = nBytes;
269  }
270 
271  void Print(const char *label=NULL, int nframes=0, int wordSize=0) const
272  {
273  if (label == NULL)
274  label = mName;
275  printf("%s - ", label);
276  CAShowAudioBufferList(&GetBufferList(), nframes, wordSize);
277  if (mBufferMemory)
278  printf(" owned memory @ 0x%p:\n", mBufferMemory);
279  }
280 
281 protected:
282  AudioBufferList & _GetBufferList() { return *(AudioBufferList *)&mNumberBuffers; } // use with care
283  // if we make this public, then we lose ability to call VerifyNotTrashingOwnedBuffer
284  void VerifyNotTrashingOwnedBuffer()
285  {
286  // This needs to be called from places where we are modifying the buffer list.
287  // It's an error to modify the buffer pointers or lengths if we own the buffer memory.
288  XAssert(mBufferMemory == NULL);
289  }
290 
291  const char * mName; // for debugging
292  Byte * mBufferMemory;
293  // the rest must exactly mirror the structure of AudioBufferList
294  UInt32 mNumberBuffers;
295  AudioBuffer mBuffers[1];
296 };
297 
298 #endif // __CABufferList_h__