void TPCircularBufferDequeueBufferListFrames(TPCircularBuffer *buffer, UInt32 *ioLengthInFrames, AudioBufferList *outputBufferList, AudioTimeStamp *outTimestamp, const AudioStreamBasicDescription *audioFormat) { bool hasTimestamp = false; UInt32 bytesToGo = *ioLengthInFrames * audioFormat->mBytesPerFrame; UInt32 bytesCopied = 0; while ( bytesToGo > 0 ) { AudioBufferList *bufferList = TPCircularBufferNextBufferList(buffer, !hasTimestamp ? outTimestamp : NULL); if ( !bufferList ) break; hasTimestamp = true; long bytesToCopy = min(bytesToGo, bufferList->mBuffers[0].mDataByteSize); if ( outputBufferList ) { for ( int i=0; i<outputBufferList->mNumberBuffers; i++ ) { assert(bytesCopied + bytesToCopy <= outputBufferList->mBuffers[i].mDataByteSize); memcpy((char*)outputBufferList->mBuffers[i].mData + bytesCopied, bufferList->mBuffers[i].mData, bytesToCopy); } } TPCircularBufferConsumeNextBufferListPartial(buffer, (int)bytesToCopy/audioFormat->mBytesPerFrame, audioFormat); bytesToGo -= bytesToCopy; bytesCopied += bytesToCopy; } *ioLengthInFrames -= bytesToGo / audioFormat->mBytesPerFrame; }
void TPCircularBufferConsumeBufferListFrames(TPCircularBuffer *buffer, UInt32 *ioLengthInFrames, AudioBufferList *outputBufferList, AudioTimeStamp *outTimestamp, AudioStreamBasicDescription *audioFormat) { // We'll advance the buffer list pointers as we add audio - save the originals to restore later void *savedmData[2] = { outputBufferList ? outputBufferList->mBuffers[0].mData : NULL, outputBufferList && outputBufferList->mNumberBuffers == 2 ? outputBufferList->mBuffers[1].mData : NULL }; bool hasTimestamp = false; UInt32 bytesToGo = *ioLengthInFrames * audioFormat->mBytesPerFrame; while ( bytesToGo > 0 ) { AudioBufferList *bufferList = TPCircularBufferNextBufferList(buffer, hasTimestamp ? outTimestamp : NULL); hasTimestamp = true; if ( !bufferList ) break; UInt32 bytesToCopy = min(bytesToGo, bufferList->mBuffers[0].mDataByteSize); if ( outputBufferList ) { for ( int i=0; i<outputBufferList->mNumberBuffers; i++ ) { memcpy(outputBufferList->mBuffers[i].mData, bufferList->mBuffers[i].mData, bytesToCopy); outputBufferList->mBuffers[i].mData = (char*)outputBufferList->mBuffers[i].mData + bytesToCopy; } } if ( bytesToCopy == bufferList->mBuffers[0].mDataByteSize ) { TPCircularBufferConsumeNextBufferList(buffer); } else { for ( int i=0; i<bufferList->mNumberBuffers; i++ ) { bufferList->mBuffers[i].mData = (char*)bufferList->mBuffers[i].mData + bytesToCopy; bufferList->mBuffers[i].mDataByteSize -= bytesToCopy; } } bytesToGo -= bytesToCopy; } *ioLengthInFrames -= bytesToGo / audioFormat->mBytesPerFrame; // Restore buffers if ( outputBufferList ) { for ( int i=0; i<outputBufferList->mNumberBuffers; i++ ) { outputBufferList->mBuffers[i].mData = savedmData[i]; outputBufferList->mBuffers[i].mDataByteSize = *ioLengthInFrames * audioFormat->mBytesPerFrame; } } }