/*============================================================================= CABufferList.cpp $Log: CABufferList.cpp,v $ Revision 1.17 2004/08/23 19:14:02 bills fix spelling mistake Revision 1.16 2004/08/23 06:23:25 jcm10 make it build on Windows Revision 1.15 2004/03/15 22:56:34 dwyatt cleanup, lose changes made for benefit of CAAudioUnit, remove unimplemented "use external buffer" stuff Revision 1.14 2004/03/13 01:32:22 bills fix ExternalOwnedBuffer implementation Revision 1.13 2003/12/04 22:55:20 luke add PrepareBuffer() function & make prepareXXX() args frames, not bytes Revision 1.12 2003/12/04 20:13:07 luke wrong comparison (should be >, not <=) Revision 1.11 2003/12/03 23:14:18 bills change prepare NULL buffer list to return a pointer not a reference Revision 1.10 2003/12/03 20:47:10 dwyatt fix broken build Revision 1.9 2003/12/02 20:51:34 luke add PrepareNullBuffer (from AUBuffer) for CAAudioUnit's benefit Revision 1.8 2003/10/09 23:24:01 dwyatt cosmetic Revision 1.7 2003/08/02 00:26:40 dwyatt revamp print Revision 1.6 2003/04/11 19:05:08 asynth fix two bugs in AllocateBuffersAndCopyFrom Revision 1.5 2003/04/08 21:54:09 asynth use memmove Revision 1.4 2003/04/08 21:49:57 asynth FillBufferFromInputProc was copying memory that had just been freed it in a certain case. Revision 1.3 2003/03/13 01:22:01 crogers make allocated buffers "hot" by calling memset() Revision 1.2 2003/02/27 01:21:40 dwyatt remove unnecessary code for forcing alignment Revision 1.1 2002/06/06 01:33:35 dwyatt initial checkin created 31 Apr 2002, 09:13, Doug Wyatt Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved $NoKeywords: $ =============================================================================*/ #include "CABufferList.h" #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) #include #else #include #endif void CABufferList::AllocateBuffers(UInt32 nBytes) { if (nBytes <= GetNumBytes()) return; if (mNumberBuffers > 1) // align successive buffers for Altivec and to take alternating // cache line hits by spacing them by odd multiples of 16 nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10; UInt32 memorySize = nBytes * mNumberBuffers; Byte *newMemory = new Byte[memorySize], *p = newMemory; memset(newMemory, 0, memorySize); // get page faults now, not later AudioBuffer *buf = mBuffers; for (UInt32 i = mNumberBuffers; i--; ++buf) { if (buf->mData != NULL && buf->mDataByteSize > 0) // preserve existing buffer contents memcpy(p, buf->mData, buf->mDataByteSize); buf->mDataByteSize = nBytes; buf->mData = p; p += nBytes; } Byte *oldMemory = mBufferMemory; mBufferMemory = newMemory; delete[] oldMemory; } void CABufferList::AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inSrcList, CABufferList *inSetPtrList) { if (mNumberBuffers != inSrcList->mNumberBuffers) return; if (mNumberBuffers != inSetPtrList->mNumberBuffers) return; if (nBytes <= GetNumBytes()) { CopyAllFrom(inSrcList, inSetPtrList); return; } inSetPtrList->VerifyNotTrashingOwnedBuffer(); UInt32 fromByteSize = inSrcList->GetNumBytes(); if (mNumberBuffers > 1) // align successive buffers for Altivec and to take alternating // cache line hits by spacing them by odd multiples of 16 nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10; UInt32 memorySize = nBytes * mNumberBuffers; Byte *newMemory = new Byte[memorySize], *p = newMemory; memset(newMemory, 0, memorySize); // make buffer "hot" AudioBuffer *buf = mBuffers; AudioBuffer *ptrBuf = inSetPtrList->mBuffers; AudioBuffer *srcBuf = inSrcList->mBuffers; for (UInt32 i = mNumberBuffers; i--; ++buf, ++ptrBuf, ++srcBuf) { if (srcBuf->mData != NULL && srcBuf->mDataByteSize > 0) // preserve existing buffer contents memmove(p, srcBuf->mData, srcBuf->mDataByteSize); buf->mDataByteSize = nBytes; buf->mData = p; ptrBuf->mDataByteSize = srcBuf->mDataByteSize; ptrBuf->mData = p; p += nBytes; } Byte *oldMemory = mBufferMemory; mBufferMemory = newMemory; if (inSrcList != inSetPtrList) inSrcList->BytesConsumed(fromByteSize); delete[] oldMemory; } void CABufferList::DeallocateBuffers() { AudioBuffer *buf = mBuffers; for (UInt32 i = mNumberBuffers; i--; ++buf) { buf->mData = NULL; buf->mDataByteSize = 0; } if (mBufferMemory != NULL) { delete[] mBufferMemory; mBufferMemory = NULL; } } extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize) { printf("AudioBufferList @ %p:\n", abl); const AudioBuffer *buf = abl->mBuffers; for (UInt32 i = 0; i < abl->mNumberBuffers; ++i, ++buf) { printf(" [%2ld]: %ldch, %ld bytes @ %p", i, buf->mNumberChannels, buf->mDataByteSize, buf->mData); if (framesToPrint) { printf(":"); Byte *p = (Byte *)buf->mData; for (int j = 0; j < framesToPrint; ++j) switch (wordSize) { case 0: printf(" %6.3f", *(Float32 *)p); p += sizeof(Float32); break; case 1: case -1: printf(" %02X", *p); p += 1; break; case 2: printf(" %04X", EndianU16_BtoN(*(UInt16 *)p)); p += 2; break; case 3: printf(" %06X", (p[0] << 16) | (p[1] << 8) | p[2]); p += 3; break; case 4: printf(" %08lX", EndianU32_BtoN(*(UInt32 *)p)); p += 4; break; case -2: printf(" %04X", EndianU16_LtoN(*(UInt16 *)p)); p += 2; break; case -3: printf(" %06X", (p[2] << 16) | (p[1] << 8) | p[0]); p += 3; break; case -4: printf(" %08lX", EndianU32_LtoN(*(UInt32 *)p)); p += 4; break; } } printf("\n"); } }