void SFXNullBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) { // Should never really be called, but to be safe... for( U32 i = 0; i < num; ++ i ) destructSingle( packets[ i ] ); }
void SFXWrapAroundBuffer::write( SFXStreamPacket* const* packets, U32 num ) { AssertFatal( SFXInternal::isSFXThread(), "SFXWrapAroundBuffer::write() - not on SFX thread" ); for( U32 i = 0; i < num; ++ i ) { const SFXStreamPacket* packet = packets[ i ]; // Determine where in the buffer to copy the data to. In case we are crossing over // the wrap-around point, we need to copy in two slices. U32 offset1 = 0; U32 offset2 = 0; U32 numBytes1 = 0; U32 numBytes2 = 0; offset1 = mWriteOffset % mBufferSize; numBytes1 = packet->size; if( offset1 + numBytes1 > mBufferSize ) { // Crossing wrap-around point. numBytes1 = mBufferSize - offset1; numBytes2 = packet->size - numBytes1; } offset2 = offset1 + numBytes1; #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXWrapAroundBuffer] writing %i bytes from packet #%i at %i (stream offset: %i)", numBytes1, packet->mIndex, offset1, mWriteOffset ); #endif // Copy the packet data. _copyData( offset1, packet->data, numBytes1 ); if( numBytes2 > 0 ) { #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXWrapAroundBuffer] writing %i more bytes at %i", numBytes2, offset2 ); #endif _copyData( offset2, &packet->data[ numBytes1 ], numBytes2 ); } dFetchAndAdd( mWriteOffset, packet->size ); // Free the packet. destructSingle( packet ); } }
void SFXMemoryStream::reset() { if( dynamic_cast< IResettable* >( getSourceStream() ) ) { reinterpret_cast< IResettable* >( getSourceStream() )->reset(); if( mCurrentPacket ) destructSingle( mCurrentPacket ); mCurrentPacket = NULL; mCurrentPacketOffset = 0; mNumSamplesLeft = mNumSamplesTotal; } else Con::errorf( "SFXMemoryStream - cannot reset source stream" ); }
U32 SFXMemoryStream::read( U8* buffer, U32 length ) { U32 bufferOffset = 0; // Determine how much we're supposed to read. U32 numBytesToCopy = length; if( mNumSamplesLeft != U32_MAX ) numBytesToCopy = getMin( length, mNumSamplesLeft * mFormat.getBytesPerSample() ); numBytesToCopy -= numBytesToCopy % mFormat.getBytesPerSample(); // Copy the data. U32 numBytesLeftToCopy = numBytesToCopy; while( numBytesLeftToCopy ) { // If we have a current packet, use its data. if( mCurrentPacket ) { U32 numBytesLeftInCurrentPacket = mCurrentPacket->size - mCurrentPacketOffset; // Copy data. if( numBytesLeftInCurrentPacket ) { const U32 numBytesToCopy = getMin( numBytesLeftInCurrentPacket, numBytesLeftToCopy ); dMemcpy( &buffer[ bufferOffset ], &mCurrentPacket->data[ mCurrentPacketOffset ], numBytesToCopy ); bufferOffset += numBytesToCopy; mCurrentPacketOffset += numBytesToCopy; numBytesLeftInCurrentPacket -= numBytesToCopy; numBytesLeftToCopy -= numBytesToCopy; } // Discard the packet if there's no data left. if( !numBytesLeftInCurrentPacket ) { destructSingle( mCurrentPacket ); mCurrentPacket = NULL; mCurrentPacketOffset = 0; } } else { // Read a new packet. if( !getSourceStream()->read( &mCurrentPacket, 1 ) ) break; } } // Update count of remaining samples. U32 numBytesCopied = numBytesToCopy - numBytesLeftToCopy; if( mNumSamplesLeft != U32_MAX ) mNumSamplesLeft -= ( numBytesCopied / mFormat.getBytesPerSample() ); return numBytesCopied; }