CARingBufferError CARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead) { SampleTime endRead = startRead + nFrames; SampleTime startRead0 = startRead; SampleTime endRead0 = endRead; CARingBufferError err = ClipTimeBounds(startRead, endRead); SampleTime readSizeFrames = endRead - startRead; if (err) { if ( readSizeFrames <= 0 ) { CARB_DEBUG( "POS1 read size frames too little. (%ld)\n", err ); return err; } } SInt32 destStartFrameOffset = startRead - startRead0; if ( destStartFrameOffset > 0 ) { CARB_DEBUG( "Fetch - Zeroing start bound\n" ); ZeroABL(abl, 0, destStartFrameOffset * mBytesPerFrame); } SInt32 destEndSize = endRead0 - endRead; if ( destEndSize > 0 ) { CARB_DEBUG( "Fetch - Zeroing end bound (%ld frames off)\n", destEndSize ); ZeroABL(abl, ( destStartFrameOffset + readSizeFrames ) * mBytesPerFrame, destEndSize * mBytesPerFrame); } Byte **buffers = mBuffers; int offset0 = FrameOffset(startRead); int offset1 = FrameOffset(endRead); int destStartByteOffset = destStartFrameOffset * mBytesPerFrame; int nbytes; if ( offset0 < offset1 ) { nbytes = offset1 - offset0; FetchABL( abl, destStartByteOffset , buffers, offset0, nbytes ); } else { nbytes = mCapacityBytes - offset0; FetchABL( abl, destStartByteOffset , buffers, offset0, nbytes ); FetchABL( abl, destStartByteOffset + nbytes, buffers, 0 , offset1 ); nbytes += offset1; } int nchannels = abl->mNumberBuffers; AudioBuffer *dest = abl->mBuffers; while (--nchannels >= 0) { dest->mDataByteSize = nbytes; dest++; } OSStatus err2 = ClipTimeBounds( startRead, endRead ); err2 = worse( err, err2 ); readSizeFrames = endRead - startRead; if ( err2 ) { if ( readSizeFrames <= 0 ) { CARB_DEBUG( "POS2 read size frames too little. (%ld)\n", err2 ); return err2; } } if ( err2 ) { CARB_DEBUG( "Returning error %ld.\n", err2 ); } return err2; }
CARingBufferError CARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead, bool outOfBoundsOK) { SampleTime endRead = startRead + nFrames; SampleTime startRead0 = startRead; SampleTime endRead0 = endRead; SampleTime size; CARingBufferError err = CheckTimeBounds(startRead, endRead); size = endRead - startRead; if (err) { if (!outOfBoundsOK) return err; if (size <= 0) return err; // there is nothing to read } SInt32 destStartOffset = startRead - startRead0; if (destStartOffset > 0) { ZeroABL(abl, 0, destStartOffset * mBytesPerFrame); } SInt32 destEndSize = endRead0 - endRead; if (destEndSize > 0) { ZeroABL(abl, destStartOffset + size, destEndSize * mBytesPerFrame); } Byte **buffers = mBuffers; int offset0 = FrameOffset(startRead); int offset1 = FrameOffset(endRead); int nbytes; if (offset0 < offset1) { FetchABL(abl, destStartOffset, buffers, offset0, nbytes = offset1 - offset0); } else { nbytes = mCapacityBytes - offset0; FetchABL(abl, destStartOffset, buffers, offset0, nbytes); FetchABL(abl, destStartOffset + nbytes, buffers, 0, offset1); nbytes += offset1; } int nchannels = abl->mNumberBuffers; AudioBuffer *dest = abl->mBuffers; while (--nchannels >= 0) { dest->mDataByteSize = nbytes; dest++; } // have to check bounds again because the data may have been overwritten before we could finish reading it. OSStatus err2 = CheckTimeBounds(startRead, endRead); err2 = worse(err, err2); size = endRead - startRead; if (err2) { if (!outOfBoundsOK) return err2; if (size <= 0) return err2; // there is nothing to read } return err2; }
CARingBuffer::Error CARingBuffer::fetch(AudioBufferList* list, size_t nFrames, uint64_t startRead) { if (!nFrames) return Ok; startRead = std::max<uint64_t>(0, startRead); uint64_t endRead = startRead + nFrames; uint64_t startRead0 = startRead; uint64_t endRead0 = endRead; clipTimeBounds(startRead, endRead); if (startRead == endRead) { ZeroABL(list, 0, nFrames * m_bytesPerFrame); return Ok; } size_t byteSize = static_cast<size_t>((endRead - startRead) * m_bytesPerFrame); size_t destStartByteOffset = static_cast<size_t>(std::max<uint64_t>(0, (startRead - startRead0) * m_bytesPerFrame)); if (destStartByteOffset > 0) ZeroABL(list, 0, std::min<size_t>(nFrames * m_bytesPerFrame, destStartByteOffset)); size_t destEndSize = static_cast<size_t>(std::max<uint64_t>(0, endRead0 - endRead)); if (destEndSize > 0) ZeroABL(list, destStartByteOffset + byteSize, destEndSize * m_bytesPerFrame); Byte **buffers = static_cast<Byte**>(m_buffers->data()); size_t offset0 = frameOffset(startRead); size_t offset1 = frameOffset(endRead); size_t nbytes; if (offset0 < offset1) { nbytes = offset1 - offset0; FetchABL(list, destStartByteOffset, buffers, offset0, nbytes); } else { nbytes = m_capacityBytes - offset0; FetchABL(list, destStartByteOffset, buffers, offset0, nbytes); FetchABL(list, destStartByteOffset + nbytes, buffers, 0, offset1); nbytes += offset1; } int channelCount = list->mNumberBuffers; AudioBuffer* dest = list->mBuffers; while (--channelCount >= 0) { dest->mDataByteSize = nbytes; dest++; } return Ok; }
CARingBufferError CARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead) { SampleTime endRead = startRead + nFrames; SampleTime startRead0 = startRead; SampleTime endRead0 = endRead; SampleTime size; CARingBufferError err = ClipTimeBounds(startRead, endRead); if (err) return err; size = endRead - startRead; SInt32 destStartOffset = startRead - startRead0; if(destStartOffset > nFrames) return kCARingBufferError_CPUOverload; if (destStartOffset > 0) { ZeroABL(abl, 0, destStartOffset * mBytesPerFrame); } SInt32 destEndSize = endRead0 - endRead; if (destEndSize > 0) { ZeroABL(abl, destStartOffset + size, destEndSize * mBytesPerFrame); } Byte **buffers = mBuffers; int offset0 = FrameOffset(startRead); int offset1 = FrameOffset(endRead); int nbytes; if (offset0 < offset1) { FetchABL(abl, destStartOffset, buffers, offset0, nbytes = offset1 - offset0); } else { nbytes = mCapacityBytes - offset0; FetchABL(abl, destStartOffset, buffers, offset0, nbytes); FetchABL(abl, destStartOffset + nbytes, buffers, 0, offset1); nbytes += offset1; } int nchannels = abl->mNumberBuffers; AudioBuffer *dest = abl->mBuffers; while (--nchannels >= 0) { dest->mDataByteSize = nbytes; dest++; } return noErr; }
size_t SFB::Audio::RingBuffer::ReadAudio(AudioBufferList *bufferList, size_t frameCount) { if(0 == frameCount) return 0; size_t framesAvailable = GetFramesAvailableToRead(); if(0 == framesAvailable) return 0; size_t framesToRead = std::min(framesAvailable, frameCount); size_t cnt2 = mReadPointer + framesToRead; size_t n1, n2; if(cnt2 > mCapacityFrames) { n1 = mCapacityFrames - mReadPointer; n2 = cnt2 & mCapacityFramesMask; } else { n1 = framesToRead; n2 = 0; } FetchABL(bufferList, 0, (const uint8_t **)mBuffers, mFormat.FrameCountToByteCount(mReadPointer), mFormat.FrameCountToByteCount(n1)); mReadPointer = (mReadPointer + n1) & mCapacityFramesMask; if(n2) { FetchABL(bufferList, mFormat.FrameCountToByteCount(n1), (const uint8_t **)mBuffers, mFormat.FrameCountToByteCount(mReadPointer), mFormat.FrameCountToByteCount(n2)); mReadPointer = (mReadPointer + n2) & mCapacityFramesMask; } // Set the buffer sizes for(UInt32 bufferIndex = 0; bufferIndex < bufferList->mNumberBuffers; ++bufferIndex) bufferList->mBuffers[bufferIndex].mDataByteSize = (UInt32)mFormat.FrameCountToByteCount(framesToRead); return framesToRead; }