Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Relevant replacement documents include:
AUPublic/Utility/AUBuffer.h
/* |
<codex> |
<abstract>Part of CoreAudio Utility Classes</abstract> |
<\codex> |
*/ |
#ifndef __AUBuffer_h__ |
#define __AUBuffer_h__ |
#include <TargetConditionals.h> |
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) |
#include <AudioUnit/AudioUnit.h> |
#else |
#include <AudioUnit.h> |
#endif |
#include <string.h> |
#include "CAStreamBasicDescription.h" |
#include "CAAutoDisposer.h" |
#include "CADebugMacros.h" |
// make this usable outside the stricter context of AudiUnits |
#ifndef COMPONENT_THROW |
#define COMPONENT_THROW(err) \ |
do { DebugMessage(#err); throw static_cast<OSStatus>(err); } while (0) |
#endif |
/*! @class AUBufferList */ |
class AUBufferList { |
enum EPtrState { |
kPtrsInvalid, |
kPtrsToMyMemory, |
kPtrsToExternalMemory |
}; |
public: |
/*! @ctor AUBufferList */ |
AUBufferList() : mPtrState(kPtrsInvalid), mExternalMemory(false), mPtrs(NULL), mMemory(NULL), |
mAllocatedStreams(0), mAllocatedFrames(0), mAllocatedBytes(0) { } |
/*! @dtor ~AUBufferList */ |
~AUBufferList(); |
/*! @method PrepareBuffer */ |
AudioBufferList & PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames); |
/*! @method PrepareNullBuffer */ |
AudioBufferList & PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames); |
/*! @method SetBufferList */ |
AudioBufferList & SetBufferList(const AudioBufferList &abl) { |
if (mAllocatedStreams < abl.mNumberBuffers) |
COMPONENT_THROW(-1); |
mPtrState = kPtrsToExternalMemory; |
memcpy(mPtrs, &abl, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl); |
return *mPtrs; |
} |
/*! @method SetBuffer */ |
void SetBuffer(UInt32 index, const AudioBuffer &ab) { |
if (mPtrState == kPtrsInvalid || index >= mPtrs->mNumberBuffers) |
COMPONENT_THROW(-1); |
mPtrState = kPtrsToExternalMemory; |
mPtrs->mBuffers[index] = ab; |
} |
/*! @method InvalidateBufferList */ |
void InvalidateBufferList() { mPtrState = kPtrsInvalid; } |
/*! @method GetBufferList */ |
AudioBufferList & GetBufferList() const { |
if (mPtrState == kPtrsInvalid) |
COMPONENT_THROW(-1); |
return *mPtrs; |
} |
/*! @method CopyBufferListTo */ |
void CopyBufferListTo(AudioBufferList &abl) const { |
if (mPtrState == kPtrsInvalid) |
COMPONENT_THROW(-1); |
memcpy(&abl, mPtrs, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl); |
} |
/*! @method CopyBufferContentsTo */ |
void CopyBufferContentsTo(AudioBufferList &abl) const { |
if (mPtrState == kPtrsInvalid) |
COMPONENT_THROW(-1); |
const AudioBuffer *srcbuf = mPtrs->mBuffers; |
AudioBuffer *destbuf = abl.mBuffers; |
for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) { |
if (i >= mPtrs->mNumberBuffers) // duplicate last source to additional outputs [4341137] |
--srcbuf; |
if (destbuf->mData != srcbuf->mData) |
memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize); |
destbuf->mDataByteSize = srcbuf->mDataByteSize; |
} |
} |
/*! @method Allocate */ |
void Allocate(const CAStreamBasicDescription &format, UInt32 nFrames); |
/*! @method Deallocate */ |
void Deallocate(); |
/*! @method UseExternalBuffer */ |
void UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf); |
// AudioBufferList utilities |
/*! @method ZeroBuffer */ |
static void ZeroBuffer(AudioBufferList &abl) { |
AudioBuffer *buf = abl.mBuffers; |
for (UInt32 i = abl.mNumberBuffers ; i--; ++buf) |
memset(buf->mData, 0, buf->mDataByteSize); |
} |
#if DEBUG |
/*! @method PrintBuffer */ |
static void PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames = 8, bool asFloats = true); |
#endif |
/*! @method GetAllocatedFrames */ |
UInt32 GetAllocatedFrames() const { return mAllocatedFrames; } |
private: |
/*! @ctor AUBufferList */ |
AUBufferList(AUBufferList &) { } // prohibit copy constructor |
/*! @var mPtrState */ |
EPtrState mPtrState; |
/*! @var mExternalMemory */ |
bool mExternalMemory; |
/*! @var mPtrs */ |
AudioBufferList * mPtrs; |
/*! @var mMemory */ |
Byte * mMemory; |
/*! @var mAllocatedStreams */ |
UInt32 mAllocatedStreams; |
/*! @var mAllocatedFrames */ |
UInt32 mAllocatedFrames; |
/*! @var mAllocatedBytes */ |
UInt32 mAllocatedBytes; |
}; |
// Allocates an array of samples (type T), to be optimally aligned for the processor |
/*! @class TAUBuffer */ |
template <class T> |
class TAUBuffer { |
public: |
enum { |
kAlignInterval = 0x10, |
kAlignMask = kAlignInterval - 1 |
}; |
/*! @ctor TAUBuffer.0 */ |
TAUBuffer() : mMemObject(NULL), mAlignedBuffer(NULL), mBufferSizeBytes(0) |
{ |
} |
/*! @ctor TAUBuffer.1 */ |
TAUBuffer(UInt32 numElems, UInt32 numChannels) : mMemObject(NULL), mAlignedBuffer(NULL), |
mBufferSizeBytes(0) |
{ |
Allocate(numElems, numChannels); |
} |
/*! @dtor ~TAUBuffer */ |
~TAUBuffer() |
{ |
Deallocate(); |
} |
/*! @method Allocate */ |
void Allocate(UInt32 numElems) // can also re-allocate |
{ |
UInt32 reqSize = numElems * sizeof(T); |
if (mMemObject != NULL && reqSize == mBufferSizeBytes) |
return; // already allocated |
mBufferSizeBytes = reqSize; |
mMemObject = CA_realloc(mMemObject, reqSize); |
UInt32 misalign = (uintptr_t)mMemObject & kAlignMask; |
if (misalign) { |
mMemObject = CA_realloc(mMemObject, reqSize + kAlignMask); |
mAlignedBuffer = (T *)((char *)mMemObject + kAlignInterval - misalign); |
} else |
mAlignedBuffer = (T *)mMemObject; |
} |
/*! @method Deallocate */ |
void Deallocate() |
{ |
if (mMemObject == NULL) return; // so this method has no effect if we're using |
// an external buffer |
free(mMemObject); |
mMemObject = NULL; |
mAlignedBuffer = NULL; |
mBufferSizeBytes = 0; |
} |
/*! @method AllocateClear */ |
void AllocateClear(UInt32 numElems) // can also re-allocate |
{ |
Allocate(numElems); |
Clear(); |
} |
/*! @method Clear */ |
void Clear() |
{ |
memset(mAlignedBuffer, 0, mBufferSizeBytes); |
} |
// accessors |
/*! @method operator T *()@ */ |
operator T *() { return mAlignedBuffer; } |
private: |
/*! @var mMemObject */ |
void * mMemObject; // null when using an external buffer |
/*! @var mAlignedBuffer */ |
T * mAlignedBuffer; // always valid once allocated |
/*! @var mBufferSizeBytes */ |
UInt32 mBufferSizeBytes; |
}; |
#endif // __AUBuffer_h__ |
Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2012-10-08