summaryrefslogtreecommitdiff
path: root/engine/audio/private/circularbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engine/audio/private/circularbuffer.cpp')
-rw-r--r--engine/audio/private/circularbuffer.cpp271
1 files changed, 271 insertions, 0 deletions
diff --git a/engine/audio/private/circularbuffer.cpp b/engine/audio/private/circularbuffer.cpp
new file mode 100644
index 0000000..8c188e3
--- /dev/null
+++ b/engine/audio/private/circularbuffer.cpp
@@ -0,0 +1,271 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Circular Buffer
+//
+//=============================================================================//
+
+#include "tier0/dbg.h"
+#include "circularbuffer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+CCircularBuffer::CCircularBuffer()
+{
+ SetSize( 0 );
+}
+
+CCircularBuffer::CCircularBuffer(int size)
+{
+ SetSize(size);
+}
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Sets the maximum size for a circular buffer. This does not do any
+// memory allocation, it simply informs the buffer of its size.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+void CCircularBuffer::SetSize(int size)
+{
+ Assert( this );
+
+ m_nSize = size;
+ m_nRead = 0;
+ m_nWrite = 0;
+ m_nCount = 0;
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Empties a circular buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+void CCircularBuffer::Flush()
+{
+ AssertValid();
+
+ m_nRead = 0;
+ m_nWrite = 0;
+ m_nCount = 0;
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Returns the available space in a circular buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::GetWriteAvailable()
+{
+ AssertValid();
+
+ return(m_nSize - m_nCount);
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Returns the size of a circular buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::GetSize()
+{
+ AssertValid();
+
+ return(m_nSize);
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Returns the number of bytes in a circular buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::GetReadAvailable()
+{
+ AssertValid();
+
+ return(m_nCount);
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Reads a specified number of bytes from a circular buffer without
+// consuming them. They will still be available for future calls to
+// Read or Peek.
+//Input : pchDest - destination buffer.
+// m_nCount - number of bytes to place in destination buffer.
+//Output : Returns the number of bytes placed in the destination buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::Peek(char *pchDest, int nCount)
+{
+ // If no data available, just return.
+ if(m_nCount == 0)
+ {
+ return(0);
+ }
+
+ //
+ // Requested amount should not exceed the available amount.
+ //
+ nCount = MIN(m_nCount, nCount);
+
+ //
+ // Copy as many of the requested bytes as possible.
+ // If buffer wrap occurs split the data into two chunks.
+ //
+ if (m_nRead + nCount > m_nSize)
+ {
+ int nCount1 = m_nSize - m_nRead;
+ memcpy(pchDest, &m_chData[m_nRead], nCount1);
+ pchDest += nCount1;
+
+ int nCount2 = nCount - nCount1;
+ memcpy(pchDest, m_chData, nCount2);
+ }
+ // Otherwise copy it in one go.
+ else
+ {
+ memcpy(pchDest, &m_chData[m_nRead], nCount);
+ }
+
+ AssertValid();
+ return nCount;
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Advances the read index, consuming a specified number of bytes from
+// the circular buffer.
+//Input : m_nCount - number of bytes to consume.
+//Output : Returns the actual number of bytes consumed.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::Advance(int nCount)
+{
+ // If no data available, just return.
+ if (m_nCount == 0)
+ {
+ return(0);
+ }
+
+ //
+ // Requested amount should not exceed the available amount.
+ //
+ nCount = MIN(m_nCount, nCount);
+
+ // Advance the read pointer, checking for buffer
+ //wrap.
+ //
+ m_nRead = (m_nRead + nCount) % m_nSize;
+ m_nCount -= nCount;
+
+ //
+ // If we have emptied the buffer, reset the read and write indices
+ // to minimize buffer wrap.
+ //
+ if (m_nCount == 0)
+ {
+ m_nRead = 0;
+ m_nWrite = 0;
+ }
+
+ AssertValid();
+ return nCount;
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Reads a specified number of bytes from a circular buffer. The bytes
+// will be consumed by the read process.
+//Input : pchDest - destination buffer.
+// m_nCount - number of bytes to place in destination buffer.
+//Output : Returns the number of bytes placed in the destination buffer.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::Read(void *pchDestIn, int nCount)
+{
+ int nPeeked;
+ int nRead;
+
+ char *pchDest = (char*)pchDestIn;
+
+ nPeeked = Peek(pchDest, nCount);
+
+ if (nPeeked != 0)
+ {
+ nRead = Advance(nPeeked);
+
+ assert( nRead == nPeeked);
+ }
+ else
+ {
+ nRead = 0;
+ }
+
+ AssertValid();
+ return(nRead);
+}
+
+
+//------------------ Copyright (c) 1999 Valve, LLC. ----------------------------
+//Purpose : Writes a specified number of bytes to the buffer.
+//Input : pm_chData - buffer containing bytes to bw written.
+// m_nCount - the number of bytes to write.
+//Output : Returns the number of bytes written. If there wa insufficient space
+// to write all requested bytes, the value returned will be less than
+// the requested amount.
+//Author : DSpeyrer
+//------------------------------------------------------------------------------
+int CCircularBuffer::Write(void *pData, int nBytesRequested)
+{
+ // Write all the data.
+ int nBytesToWrite = nBytesRequested;
+ char *pDataToWrite = (char*)pData;
+
+ while(nBytesToWrite)
+ {
+ int from = m_nWrite;
+ int to = m_nWrite + nBytesToWrite;
+
+ if(to >= m_nSize)
+ {
+ to = m_nSize;
+ }
+
+ memcpy(&m_chData[from], pDataToWrite, to - from);
+ pDataToWrite += to - from;
+
+ m_nWrite = to % m_nSize;
+ nBytesToWrite -= to - from;
+ }
+
+ // Did it cross the read pointer? Then slide the read pointer up.
+ // This way, we will discard the old data.
+ if(nBytesRequested > (m_nSize - m_nCount))
+ {
+ m_nCount = m_nSize;
+ m_nRead = m_nWrite;
+ }
+ else
+ {
+ m_nCount += nBytesRequested;
+ }
+
+ AssertValid();
+ return nBytesRequested;
+}
+
+CCircularBuffer *AllocateCircularBuffer( int nSize )
+{
+ char *pBuff = (char *)malloc( sizeof( CCircularBuffer ) + nSize - 1 );
+
+ CCircularBuffer *pCCircularBuffer = (CCircularBuffer *)pBuff;
+
+ pCCircularBuffer->SetSize( nSize );
+ return pCCircularBuffer;
+}
+
+void FreeCircularBuffer( CCircularBuffer *pCircularBuffer )
+{
+ free( (char*)pCircularBuffer );
+}
+