size_t SFB::Audio::RingBuffer::WriteAudio(const AudioBufferList *bufferList, size_t frameCount) { if(0 == frameCount) return 0; size_t framesAvailable = GetFramesAvailableToWrite(); if(0 == framesAvailable) return 0; size_t framesToWrite = std::min(framesAvailable, frameCount); size_t cnt2 = mWritePointer + framesToWrite; size_t n1, n2; if(cnt2 > mCapacityFrames) { n1 = mCapacityFrames - mWritePointer; n2 = cnt2 & mCapacityFramesMask; } else { n1 = framesToWrite; n2 = 0; } StoreABL(mBuffers, mFormat.FrameCountToByteCount(mWritePointer), bufferList, 0, mFormat.FrameCountToByteCount(n1)); mWritePointer = (mWritePointer + n1) & mCapacityFramesMask; if(n2) { StoreABL(mBuffers, mFormat.FrameCountToByteCount(mWritePointer), bufferList, mFormat.FrameCountToByteCount(n1), mFormat.FrameCountToByteCount(n2)); mWritePointer = (mWritePointer + n2) & mCapacityFramesMask; } return framesToWrite; }
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 }