Example #1
0
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;
}
Example #2
0
bool  AudioRingBuffer::Store(const Byte *data, UInt32 nFrames, SInt64 startFrame)
{
  if (nFrames > mCapacityFrames) return false;

  // $$$ we have an unaddressed critical region here
  // reading and writing could well be in separate threads

  SInt64 endFrame = startFrame + nFrames;
  if (startFrame >= mEndFrame + mCapacityFrames)
    // writing more than one buffer ahead -- fine but that means that everything we have is now too far in the past
    Clear();

  if (mStartFrame == 0) {
    // empty buffer
    mStartOffset = 0;
    mStartFrame = startFrame;
    mEndFrame = endFrame;
    memcpy(mBuffer, data, nFrames * mBytesPerFrame);
  } else {
    UInt32 offset0, offset1, nBytes;
    if (endFrame > mEndFrame) {
      // advancing (as will be usual with sequential stores)

      if (startFrame > mEndFrame) {
        // we are skipping some samples, so zero the range we are skipping
        offset0 = FrameOffset(mEndFrame);
        offset1 = FrameOffset(startFrame);
        if (offset0 < offset1)
          memset(mBuffer + offset0, 0, offset1 - offset0);
        else {
          nBytes = mCapacityBytes - offset0;
          memset(mBuffer + offset0, 0, nBytes);
          memset(mBuffer, 0, offset1);
        }
      }
      mEndFrame = endFrame;

      // except for the case of not having wrapped yet, we will normally
      // have to advance the start
      SInt64 newStart = mEndFrame - mCapacityFrames;
      if (newStart > mStartFrame) {
        mStartOffset = (mStartOffset + (newStart - mStartFrame) * mBytesPerFrame) % mCapacityBytes;
        mStartFrame = newStart;
      }
    }
    // now everything is lined up and we can just write the new data
    offset0 = FrameOffset(startFrame);
    offset1 = FrameOffset(endFrame);
    if (offset0 < offset1)
      memcpy(mBuffer + offset0, data, offset1 - offset0);
    else {
      nBytes = mCapacityBytes - offset0;
      memcpy(mBuffer + offset0, data, nBytes);
      memcpy(mBuffer, data + nBytes, offset1);
    }
  }
  //printf("Store - buffer times: %.0f - %.0f, writing %.0f - %.0f\n", double(mStartFrame), double(mEndFrame), double(startFrame), double(endFrame));

  return true;
}
Example #3
0
double	AudioRingBuffer::Fetch(Byte *data, UInt32 nFrames, SInt64 startFrame)
{
	//printf("read()\n");
	SInt64 endFrame = startFrame + nFrames;
	if (startFrame < mStartFrame || endFrame > mEndFrame) {
		//printf("error - buffer times: %.0f - %.0f, reading for %.0f - %.0f\n", double(mStartFrame), double(mEndFrame), double(startFrame), double(endFrame));
		if (startFrame < mStartFrame)
			return double(startFrame - mStartFrame);
		else
			return double(endFrame - mEndFrame);
	}
	
	UInt32 offset0 = FrameOffset(startFrame);
	UInt32 offset1 = FrameOffset(endFrame);
	
	if (offset0 < offset1) {
		//printf("r-memcpy C\n");
		memcpy(data, mBuffer + offset0, offset1 - offset0);
	}
	else {
		//printf("r-memcpy D\n");
		UInt32 nBytes = mCapacityBytes - offset0;
		memcpy(data, mBuffer + offset0, nBytes);
		memcpy(data + nBytes, mBuffer, offset1);
	}
	return double((mEndFrame - nFrames) - startFrame);
}
Example #4
0
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;
}
Example #5
0
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
}
Example #6
0
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;
}
FSTCARingBufferError	FSTCARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead)
{
	SampleTime endRead = startRead + nFrames;
	
	SampleTime startRead0 = startRead;
	SampleTime endRead0 = endRead;
	SampleTime size;
	
	FSTCARingBufferError err = ClipTimeBounds(startRead, endRead);
	if (err) return err;
	size = endRead - startRead;
	
	SInt32 idx, destStartOffset = startRead - startRead0;
	
	if(mBufferList)
	{
		for(idx=0; idx<mBufferList->mNumberBuffers; idx++)
		{
			AudioBuffer *	storeBuf = &mBufferList->mBuffers[idx],
			*	fetchBuf = &abl->mBuffers[idx];
			mCapacityBytes = sizeof(float)*storeBuf->mNumberChannels * mCapacityFrames;
			
			if (destStartOffset > 0)
			{
				ZeroAB(fetchBuf, 0, destStartOffset * sizeof(float)*fetchBuf->mNumberChannels);
			}
			
			SInt32 destEndSize = endRead0 - endRead; 
			if (destEndSize > 0)
			{
				ZeroAB(fetchBuf, (destStartOffset + size) * sizeof(float)*fetchBuf->mNumberChannels, destEndSize * sizeof(float)*fetchBuf->mNumberChannels);
			}
			
			int offset0 = startRead * sizeof(float) * storeBuf->mNumberChannels;
			int offset1 = endRead * sizeof(float) * storeBuf->mNumberChannels;
			int nbytes;
			
			if(offset0 == offset1 == 0)
			{
				nbytes = 0;
			}
			if (offset0 < offset1)
			{
				FetchAB(fetchBuf, destStartOffset, storeBuf, offset0, nbytes = offset1 - offset0);
			}
			else
			{
				nbytes = mCapacityBytes - offset0;
				FetchAB(fetchBuf, destStartOffset, storeBuf, offset0, nbytes);
				FetchAB(fetchBuf, destStartOffset + nbytes, storeBuf, 0, offset1);
				nbytes += offset1;
			}
			
			fetchBuf->mDataByteSize = nbytes;
		}
	}
	else
	{
		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)
		{
			FetchBufs(abl, destStartOffset, buffers, offset0, nbytes = offset1 - offset0);
		}
		else
		{
			nbytes = mCapacityBytes - offset0;
			FetchBufs(abl, destStartOffset, buffers, offset0, nbytes);
			FetchBufs(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;
}
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
}