3 Abstract: Part of CoreAudio Utility Classes
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
7 Inc. ("Apple") in consideration of your agreement to the following
8 terms, and your use, installation, modification or redistribution of
9 this Apple software constitutes acceptance of these terms. If you do
10 not agree with these terms, please do not use, install, modify or
11 redistribute this Apple software.
13 In consideration of your agreement to abide by the following terms, and
14 subject to these terms, Apple grants you a personal, non-exclusive
15 license, under Apple's copyrights in this original Apple software (the
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple
17 Software, with or without modifications, in source and/or binary forms;
18 provided that if you redistribute the Apple Software in its entirety and
19 without modifications, you must retain this notice and the following
20 text and disclaimers in all such redistributions of the Apple Software.
21 Neither the name, trademarks, service marks or logos of Apple Inc. may
22 be used to endorse or promote products derived from the Apple Software
23 without specific prior written permission from Apple. Except as
24 expressly stated in this notice, no other rights or licenses, express or
25 implied, are granted by Apple herein, including but not limited to any
26 patent rights that may be infringed by your derivative works or by other
27 works in which the Apple Software may be incorporated.
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42 POSSIBILITY OF SUCH DAMAGE.
44 Copyright (C) 2014 Apple Inc. All Rights Reserved.
47 #ifndef __CABufferList_h__
48 #define __CABufferList_h__
51 #include "CAStreamBasicDescription.h"
52 #include "CAXException.h"
54 void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, const AudioStreamBasicDescription &fmt, const char *label=NULL);
55 void CAShowAudioBufferList(const AudioBufferList &abl, int framesToPrint, int wordSize, const char *label=NULL);
56 extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize);
57 extern "C" int CrashIfClientProvidedBogusAudioBufferList(const AudioBufferList *abl, bool nullOK=false);
59 /* ____________________________________________________________________________
60 // CABufferList - variable length buffer list
62 This class is designed for use in non-simplistic cases. For AudioUnits, AUBufferList
65 CABufferList can be used in one of two ways:
66 - as mutable pointers into non-owned memory
67 - as an immutable array of buffers (owns its own memory).
69 All buffers are assumed to have the same format (number of channels, word size), so that
70 we can assume their mDataByteSizes are all the same.
71 ____________________________________________________________________________ */
74 void * operator new(size_t /*size*/, int nBuffers) {
75 return ::operator new(sizeof(CABufferList) + (nBuffers-1) * sizeof(AudioBuffer));
77 static CABufferList * New(const char *name, const CAStreamBasicDescription &format)
79 UInt32 numBuffers = format.NumberChannelStreams(), channelsPerBuffer = format.NumberInterleavedChannels();
80 return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
82 static CABufferList * New(const CAStreamBasicDescription &format) { return New("", format); }
84 static CABufferList * New(UInt32 numBuffers, UInt32 channelsPerBuffer, const char *name="") {
85 return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
89 CABufferList(const char *name, UInt32 numBuffers, UInt32 channelsPerBuffer) :
94 //XAssert(numBuffers > 0 /*&& channelsPerBuffer > 0*/);
95 mABL.mNumberBuffers = numBuffers;
96 AudioBuffer *buf = mABL.mBuffers;
97 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
98 buf->mNumberChannels = channelsPerBuffer;
99 buf->mDataByteSize = 0;
108 delete[] mBufferMemory;
111 const char * Name() { return mName; }
113 const AudioBufferList & GetBufferList() const { return mABL; }
115 AudioBufferList & GetModifiableBufferList() { return _GetBufferList(); }
117 UInt32 GetNumberBuffers() const { return mABL.mNumberBuffers; }
119 UInt32 GetNumBytes() const
121 return mABL.mBuffers[0].mDataByteSize;
124 void SetBytes(UInt32 nBytes, void *data)
126 VerifyNotTrashingOwnedBuffer();
127 XAssert(mABL.mNumberBuffers == 1);
128 mABL.mBuffers[0].mDataByteSize = nBytes;
129 mABL.mBuffers[0].mData = data;
132 void CopyAllFrom(CABufferList *srcbl, CABufferList *ptrbl)
133 // copies bytes from srcbl
134 // make ptrbl reflect the length copied
135 // note that srcbl may be same as ptrbl!
137 // Note that this buffer *can* own memory and its pointers/lengths are not
138 // altered; only its buffer contents, which are copied from srcbl.
139 // The pointers/lengths in ptrbl are updated to reflect the addresses/lengths
140 // of the copied data, and srcbl's contents are consumed.
141 ptrbl->VerifyNotTrashingOwnedBuffer();
142 UInt32 nBytes = srcbl->GetNumBytes();
143 AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = srcbl->mABL.mBuffers,
144 *ptrbuf = ptrbl->mABL.mBuffers;
145 for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf, ++ptrbuf) {
146 memmove(mybuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
147 ptrbuf->mData = mybuf->mData;
148 ptrbuf->mDataByteSize = srcbuf->mDataByteSize;
151 srcbl->BytesConsumed(nBytes);
154 // copies data from another buffer list.
155 void CopyDataFrom(const AudioBufferList &other)
157 for (unsigned i = 0; i < other.mNumberBuffers; ++i) {
158 XAssert(mBufferCapacity == 0 || other.mBuffers[i].mDataByteSize <= mBufferCapacity);
159 memcpy(mABL.mBuffers[i].mData, other.mBuffers[i].mData,
160 mABL.mBuffers[i].mDataByteSize = other.mBuffers[i].mDataByteSize);
164 void AppendFrom(CABufferList *blp, UInt32 nBytes)
166 // this may mutate a buffer that owns memory.
167 AudioBuffer *mybuf = mABL.mBuffers, *srcbuf = blp->mABL.mBuffers;
168 for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
169 XAssert(nBytes <= srcbuf->mDataByteSize);
170 XAssert(mBufferCapacity == 0 || mybuf->mDataByteSize + nBytes <= mBufferCapacity);
171 memcpy((Byte *)mybuf->mData + mybuf->mDataByteSize, srcbuf->mData, nBytes);
172 mybuf->mDataByteSize += nBytes;
174 blp->BytesConsumed(nBytes);
177 void PadWithZeroes(UInt32 desiredBufferSize)
178 // for cases where an algorithm (e.g. SRC) requires some
179 // padding to create silence following end-of-file
181 XAssert(mBufferCapacity == 0 || desiredBufferSize <= mBufferCapacity);
182 if (GetNumBytes() > desiredBufferSize) return;
183 AudioBuffer *buf = mABL.mBuffers;
184 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
185 memset((Byte *)buf->mData + buf->mDataByteSize, 0, desiredBufferSize - buf->mDataByteSize);
186 buf->mDataByteSize = desiredBufferSize;
190 void SetToZeroes(UInt32 nBytes)
192 XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
193 AudioBuffer *buf = mABL.mBuffers;
194 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
195 memset((Byte *)buf->mData, 0, nBytes);
196 buf->mDataByteSize = nBytes;
205 Boolean SameDataAs(const CABufferList* anotherBufferList)
207 // check to see if two buffer lists point to the same memory.
208 if (mABL.mNumberBuffers != anotherBufferList->mABL.mNumberBuffers) return false;
210 for (UInt32 i = 0; i < mABL.mNumberBuffers; ++i) {
211 if (mABL.mBuffers[i].mData != anotherBufferList->mABL.mBuffers[i].mData) return false;
216 void BytesConsumed(UInt32 nBytes)
217 // advance buffer pointers, decrease buffer sizes
219 VerifyNotTrashingOwnedBuffer();
220 AudioBuffer *buf = mABL.mBuffers;
221 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
222 XAssert(nBytes <= buf->mDataByteSize);
223 buf->mData = (Byte *)buf->mData + nBytes;
224 buf->mDataByteSize -= nBytes;
228 void SetFrom(const AudioBufferList *abl)
230 VerifyNotTrashingOwnedBuffer();
231 memcpy(&_GetBufferList(), abl, (char *)&abl->mBuffers[abl->mNumberBuffers] - (char *)abl);
234 void SetFrom(const CABufferList *blp)
236 SetFrom(&blp->GetBufferList());
239 void SetFrom(const AudioBufferList *abl, UInt32 nBytes)
241 VerifyNotTrashingOwnedBuffer();
242 AudioBuffer *mybuf = mABL.mBuffers;
243 const AudioBuffer *srcbuf = abl->mBuffers;
244 for (UInt32 i = mABL.mNumberBuffers; i--; ++mybuf, ++srcbuf) {
245 mybuf->mNumberChannels = srcbuf->mNumberChannels;
246 mybuf->mDataByteSize = nBytes;
247 mybuf->mData = srcbuf->mData;
251 void SetFrom(const CABufferList *blp, UInt32 nBytes)
253 SetFrom(&blp->GetBufferList(), nBytes);
256 AudioBufferList * ToAudioBufferList(AudioBufferList *abl) const
258 memcpy(abl, &GetBufferList(), (char *)&abl->mBuffers[mABL.mNumberBuffers] - (char *)abl);
262 void AllocateBuffers(UInt32 nBytes);
263 void AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inCopyFromList, CABufferList *inSetPtrList);
265 void DeallocateBuffers();
267 void UseExternalBuffer(Byte *ptr, UInt32 nBytes);
269 void AdvanceBufferPointers(UInt32 nBytes) // $$$ ReducingSize
270 // this is for bufferlists that function simply as
271 // an array of pointers into another bufferlist, being advanced,
272 // as in RenderOutput implementations
274 VerifyNotTrashingOwnedBuffer();
275 AudioBuffer *buf = mABL.mBuffers;
276 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf) {
277 buf->mData = (Byte *)buf->mData + nBytes;
278 buf->mDataByteSize -= nBytes;
282 void SetNumBytes(UInt32 nBytes)
284 XAssert(mBufferCapacity == 0 || nBytes <= mBufferCapacity);
285 AudioBuffer *buf = mABL.mBuffers;
286 for (UInt32 i = mABL.mNumberBuffers; i--; ++buf)
287 buf->mDataByteSize = nBytes;
290 void Print(const char *label=NULL, int nframes=0, int wordSize=0) const
294 printf("%s - ", label);
295 CAShowAudioBufferList(&GetBufferList(), nframes, wordSize);
297 printf(" owned memory @ 0x%p:\n", mBufferMemory);
300 UInt32 GetCapacityBytes() const { return mBufferCapacity; }
302 template <typename T>
303 T* GetData(UInt32 inBuffer) {
304 return static_cast<T*>(mABL.mBuffers[inBuffer].mData);
308 AudioBufferList & _GetBufferList() { return mABL; } // use with care
309 // if we make this public, then we lose ability to call VerifyNotTrashingOwnedBuffer
310 void VerifyNotTrashingOwnedBuffer()
312 // This needs to be called from places where we are modifying the buffer pointers.
313 // It's an error to modify the buffer pointers or lengths if we own the buffer memory.
314 XAssert(mBufferMemory == NULL);
317 const char * mName; // for debugging
318 Byte * mBufferMemory;
319 UInt32 mBufferCapacity; // max mDataByteSize of each buffer
320 AudioBufferList mABL;
321 // don't add anything here
324 #endif // __CABufferList_h__