CARingBuffer::Error CARingBuffer::store(const AudioBufferList* list, size_t framesToWrite, uint64_t startFrame) { if (!framesToWrite) return Ok; if (framesToWrite > m_frameCount) return TooMuch; uint64_t endFrame = startFrame + framesToWrite; if (startFrame < currentEndFrame()) { // Throw everything out when going backwards. setCurrentFrameBounds(startFrame, startFrame); } else if (endFrame - currentStartFrame() <= m_frameCount) { // The buffer has not yet wrapped and will not need to. // No-op. } else { // Advance the start time past the region we are about to overwrite // starting one buffer of time behind where we're writing. uint64_t newStartFrame = endFrame - m_frameCount; uint64_t newEndFrame = std::max(newStartFrame, currentEndFrame()); setCurrentFrameBounds(newStartFrame, newEndFrame); } // Write the new frames. Byte** buffers = static_cast<Byte**>(m_buffers->data()); size_t offset0; size_t offset1; uint64_t curEnd = currentEndFrame(); if (startFrame > curEnd) { // We are skipping some samples, so zero the range we are skipping. offset0 = frameOffset(curEnd); offset1 = frameOffset(startFrame); if (offset0 < offset1) ZeroRange(buffers, m_channelCount, offset0, offset1 - offset0); else { ZeroRange(buffers, m_channelCount, offset0, m_capacityBytes - offset0); ZeroRange(buffers, m_channelCount, 0, offset1); } offset0 = offset1; } else offset0 = frameOffset(startFrame); offset1 = frameOffset(endFrame); if (offset0 < offset1) StoreABL(buffers, offset0, list, 0, offset1 - offset0); else { size_t nbytes = m_capacityBytes - offset0; StoreABL(buffers, offset0, list, 0, nbytes); StoreABL(buffers, 0, list, nbytes, offset1); } // Now update the end time. setCurrentFrameBounds(currentStartFrame(), endFrame); return Ok; }
CARingBufferError CARingBuffer::Store(const AudioBufferList *abl, UInt32 framesToWrite, SampleTime startWrite) { if (framesToWrite > mCapacityFrames) return kCARingBufferError_TooMuch; // too big! SampleTime endWrite = startWrite + framesToWrite; if (startWrite < EndTime()) { // going backwards, throw everything out SetTimeBounds(startWrite, startWrite); } else if (endWrite - StartTime() <= mCapacityFrames) { // the buffer has not yet wrapped and will not need to } else { // advance the start time past the region we are about to overwrite SampleTime newStart = endWrite - mCapacityFrames; // one buffer of time behind where we're writing SampleTime newEnd = std::max(newStart, EndTime()); SetTimeBounds(newStart, newEnd); } // write the new frames Byte **buffers = mBuffers; int nchannels = mNumberChannels; int offset0, offset1, nbytes; SampleTime curEnd = EndTime(); if (startWrite > curEnd) { // we are skipping some samples, so zero the range we are skipping offset0 = FrameOffset(curEnd); offset1 = FrameOffset(startWrite); if (offset0 < offset1) ZeroRange(buffers, nchannels, offset0, offset1 - offset0); else { ZeroRange(buffers, nchannels, offset0, mCapacityBytes - offset0); ZeroRange(buffers, nchannels, 0, offset1); } offset0 = offset1; } else { offset0 = FrameOffset(startWrite); } offset1 = FrameOffset(endWrite); if (offset0 < offset1) StoreABL(buffers, offset0, abl, 0, offset1 - offset0); else { nbytes = mCapacityBytes - offset0; StoreABL(buffers, offset0, abl, 0, nbytes); StoreABL(buffers, 0, abl, nbytes, offset1); } // now update the end time SetTimeBounds(StartTime(), endWrite); return kCARingBufferError_OK; // success }
FSTCARingBufferError FSTCARingBuffer::Store(const AudioBufferList *abl, UInt32 framesToWrite, SampleTime startWrite) { if (framesToWrite > mCapacityFrames) return kFSTCARingBufferError_TooMuch; // too big! if(startWrite > mCapacityFrames) return kFSTCARingBufferError_CPUOverload; SampleTime endWrite = startWrite + framesToWrite; if (startWrite < EndTime()) { // going backwards, throw everything out SetTimeBounds(startWrite, startWrite); } else if (endWrite - StartTime() <= mCapacityFrames) { // the buffer has not yet wrapped and will not need to } else { // advance the start time past the region we are about to overwrite SampleTime newStart = endWrite - mCapacityFrames; // one buffer of time behind where we're writing SampleTime newEnd = std::max(newStart, EndTime()); SetTimeBounds(newStart, newEnd); } int idx, offset0, offset1, nbytes; SampleTime curEnd = EndTime(); if(mBufferList) { int numBuffs = abl->mNumberBuffers; if(numBuffs > mBufferList->mNumberBuffers) numBuffs = mBufferList->mNumberBuffers; for(idx=0; idx<numBuffs; idx++) { AudioBuffer * buffer = &mBufferList->mBuffers[idx]; mCapacityBytes = sizeof(float)*buffer->mNumberChannels * mCapacityFrames; if (startWrite > curEnd) { // we are skipping some samples, so zero the range we are skipping offset0 = curEnd * sizeof(float) * buffer->mNumberChannels; offset1 = startWrite * sizeof(float) * buffer->mNumberChannels; if (offset0 < offset1) { ZeroRangeAB(buffer, offset0, offset1 - offset0); } else { ZeroRangeAB(buffer, offset0, mCapacityBytes - offset0); ZeroRangeAB(buffer, 0, offset1); } offset0 = offset1; } else { offset0 = startWrite * sizeof(float) * buffer->mNumberChannels; } offset1 = endWrite * sizeof(float) * buffer->mNumberChannels; if (offset0 < offset1) StoreAB(buffer, offset0, &abl->mBuffers[idx], 0, offset1 - offset0); else { nbytes = mCapacityBytes - offset0; StoreAB(buffer, offset0, &abl->mBuffers[idx], 0, nbytes); StoreAB(buffer, 0, &abl->mBuffers[idx], nbytes, offset1); } } } else { // write the new frames Byte **buffers = mBuffers; int nchannels = mNumberChannels; if (startWrite > curEnd) { // we are skipping some samples, so zero the range we are skipping offset0 = FrameOffset(curEnd); offset1 = FrameOffset(startWrite); if (offset0 < offset1) ZeroRange(buffers, nchannels, offset0, offset1 - offset0); else { ZeroRange(buffers, nchannels, offset0, mCapacityBytes - offset0); ZeroRange(buffers, nchannels, 0, offset1); } offset0 = offset1; } else { offset0 = FrameOffset(startWrite); } offset1 = FrameOffset(endWrite); if (offset0 < offset1) StoreBufs(buffers, offset0, abl, 0, offset1 - offset0); else { nbytes = mCapacityBytes - offset0; StoreBufs(buffers, offset0, abl, 0, nbytes); StoreBufs(buffers, 0, abl, nbytes, offset1); } } // now update the end time SetTimeBounds(StartTime(), endWrite); return kFSTCARingBufferError_OK; // success }