void TPCircularBufferProduceAudioBufferList(TPCircularBuffer *buffer, const AudioTimeStamp *inTimestamp) { int32_t availableBytes; TPCircularBufferABLBlockHeader *block = (TPCircularBufferABLBlockHeader*)TPCircularBufferHead(buffer, &availableBytes); assert(block); assert(!((unsigned long)block & 0xF) /* Beware unaligned accesses */); assert(block->bufferList.mBuffers[0].mDataByteSize > 0); if ( inTimestamp ) { memcpy(&block->timestamp, inTimestamp, sizeof(AudioTimeStamp)); } UInt32 calculatedLength = (UInt32)(((char*)block->bufferList.mBuffers[block->bufferList.mNumberBuffers-1].mData + block->bufferList.mBuffers[block->bufferList.mNumberBuffers-1].mDataByteSize) - (char*)block); // Make sure whole buffer (including timestamp and length value) is 16-byte aligned in length calculatedLength = (UInt32)align16byte(calculatedLength); assert(calculatedLength <= block->totalLength && calculatedLength <= availableBytes); block->totalLength = calculatedLength; TPCircularBufferProduce(buffer, block->totalLength); }
void TPCircularBufferProduceAudioBufferList(TPCircularBuffer *buffer) { int32_t availableBytes; AudioTimeStamp *timestamp = (AudioTimeStamp*)TPCircularBufferHead(buffer, &availableBytes); UInt32 *totalLengthInBytes = (UInt32*)(timestamp+1); AudioBufferList *list = (AudioBufferList*)(totalLengthInBytes+1); UInt32 calculatedLength = ((char*)list->mBuffers[list->mNumberBuffers-1].mData + list->mBuffers[list->mNumberBuffers-1].mDataByteSize) - (char*)list; assert(calculatedLength < *totalLengthInBytes && sizeof(AudioTimeStamp)+sizeof(UInt32)+calculatedLength <= availableBytes); *totalLengthInBytes = calculatedLength; TPCircularBufferProduce(buffer, sizeof(AudioTimeStamp) + sizeof(UInt32) + *totalLengthInBytes); }
bool TPCircularBufferCopyAudioBufferList(TPCircularBuffer *buffer, const AudioBufferList *bufferList, const AudioTimeStamp *inTimestamp) { int bufferListSize = sizeof(AudioBufferList) + ((bufferList->mNumberBuffers-1) * sizeof(AudioBuffer)); int32_t availableBytes; AudioTimeStamp *timestamp = (AudioTimeStamp*)TPCircularBufferHead(buffer, &availableBytes); if ( availableBytes < sizeof(AudioTimeStamp) + bufferListSize ) return false; // Store timestamp, followed by buffer list if ( inTimestamp ) { *timestamp = *inTimestamp; } else { memset(timestamp, 0, sizeof(AudioTimeStamp)); } UInt32 *totalLengthInBytes = (UInt32*)(timestamp+1); AudioBufferList *list = (AudioBufferList*)(totalLengthInBytes+1); memcpy(list, bufferList, bufferListSize); char *dataPtr = (char*)list + bufferListSize; for ( int i=0; i<bufferList->mNumberBuffers; i++ ) { // Find the next 16-byte aligned memory area dataPtr = (char*)align16bit((long)dataPtr); if ( (dataPtr + bufferList->mBuffers[i].mDataByteSize) - (char*)timestamp > availableBytes ) { return false; } assert(bufferList->mBuffers[i].mData != NULL); list->mBuffers[i].mData = dataPtr; memcpy(dataPtr, bufferList->mBuffers[i].mData, bufferList->mBuffers[i].mDataByteSize); dataPtr += bufferList->mBuffers[i].mDataByteSize; } *totalLengthInBytes = (dataPtr-(char*)list); TPCircularBufferProduce(buffer, dataPtr-(char*)timestamp); return true; }