aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/base/URingBuffer.pas165
-rw-r--r--src/base/ringbuffer.cpp127
-rw-r--r--src/base/ringbuffer.hpp52
3 files changed, 179 insertions, 165 deletions
diff --git a/src/base/URingBuffer.pas b/src/base/URingBuffer.pas
deleted file mode 100644
index 684c13ee..00000000
--- a/src/base/URingBuffer.pas
+++ /dev/null
@@ -1,165 +0,0 @@
-{* UltraStar Deluxe - Karaoke Game
- *
- * UltraStar Deluxe is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *}
-
-unit URingBuffer;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SysUtils;
-
-type
- TRingBuffer = class
- private
- RingBuffer: PByteArray;
- BufferCount: integer;
- BufferSize: integer;
- WritePos: integer;
- ReadPos: integer;
- public
- constructor Create(Size: integer);
- destructor Destroy; override;
- function Read(Buffer: PByteArray; Count: integer): integer;
- function Write(Buffer: PByteArray; Count: integer): integer;
- function Size(): integer;
- function Available(): integer;
- procedure Flush();
- end;
-
-implementation
-
-uses
- Math;
-
-constructor TRingBuffer.Create(Size: integer);
-begin
- BufferSize := Size;
-
- GetMem(RingBuffer, Size);
- if (RingBuffer = nil) then
- raise Exception.Create('No memory');
-end;
-
-destructor TRingBuffer.Destroy;
-begin
- FreeMem(RingBuffer);
-end;
-
-function TRingBuffer.Read(Buffer: PByteArray; Count: integer): integer;
-var
- PartCount: integer;
-begin
- // adjust output count
- if (Count > BufferCount) then
- begin
- //DebugWriteln('Read too much: ' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
- Count := BufferCount;
- end;
-
- // check if there is something to do
- if (Count <= 0) then
- begin
- Result := Count;
- Exit;
- end;
-
- // copy data to output buffer
-
- // first step: copy from the area between the read-position and the end of the buffer
- PartCount := Min(Count, BufferSize - ReadPos);
- Move(RingBuffer[ReadPos], Buffer[0], PartCount);
-
- // second step: if we need more data, copy from the beginning of the buffer
- if (PartCount < Count) then
- Move(RingBuffer[0], Buffer[0], Count-PartCount);
-
- // mark the copied part of the buffer as free
- BufferCount := BufferCount - Count;
- ReadPos := (ReadPos + Count) mod BufferSize;
-
- Result := Count;
-end;
-
-function TRingBuffer.Write(Buffer: PByteArray; Count: integer): integer;
-var
- PartCount: integer;
-begin
- // check for a reasonable request
- if (Count <= 0) then
- begin
- Result := Count;
- Exit;
- end;
-
- // skip input data if the input buffer is bigger than the ring-buffer
- if (Count > BufferSize) then
- begin
- //DebugWriteln('Write skip data:' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
- Buffer := @Buffer[Count - BufferSize];
- Count := BufferSize;
- end;
-
- // first step: copy to the area between the write-position and the end of the buffer
- PartCount := Min(Count, BufferSize - WritePos);
- Move(Buffer[0], RingBuffer[WritePos], PartCount);
-
- // second step: copy data to front of buffer
- if (PartCount < Count) then
- Move(Buffer[PartCount], RingBuffer[0], Count-PartCount);
-
- // update info
- BufferCount := Min(BufferCount + Count, BufferSize);
- WritePos := (WritePos + Count) mod BufferSize;
- // if the buffer is full, we have to reposition the read-position
- if (BufferCount = BufferSize) then
- ReadPos := WritePos;
-
- Result := Count;
-end;
-
-function TRingBuffer.Available(): integer;
-begin
- Result := BufferCount;
-end;
-
-function TRingBuffer.Size(): integer;
-begin
- Result := BufferSize;
-end;
-
-procedure TRingBuffer.Flush();
-begin
- ReadPos := 0;
- WritePos := 0;
- BufferCount := 0;
-end;
-
-end.
diff --git a/src/base/ringbuffer.cpp b/src/base/ringbuffer.cpp
new file mode 100644
index 00000000..7adcd332
--- /dev/null
+++ b/src/base/ringbuffer.cpp
@@ -0,0 +1,127 @@
+/*
+ * UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "ringbuffer.hpp"
+#include <stdlib.h>
+#include <string.h>
+
+namespace usdx
+{
+
+ RingBuffer::RingBuffer(int size)
+ {
+ buffer_size = size;
+
+ ring_buffer = (char*)malloc(size);
+ if (ring_buffer == NULL)
+ throw "No memory";
+ }
+
+ RingBuffer::~RingBuffer()
+ {
+ free(ring_buffer);
+ }
+
+ int RingBuffer::read(char *buffer, int count)
+ {
+ // check if there is something to do
+ if (count <= 0)
+ return count;
+
+ // adjust output count
+ if (count > buffer_count)
+ {
+ //DebugWriteln('Read too much: ' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
+ count = buffer_count;
+ }
+
+ // copy data to output buffer
+
+ // first step: copy from the area between the read-position and the end of the buffer
+ int part_count = (count < buffer_size - read_pos) ? count : (buffer_size - read_pos);
+ memcpy(buffer, ring_buffer + read_pos, part_count);
+
+ // second step: if we need more data, copy from the beginning of the buffer
+ if (part_count < count)
+ memcpy(buffer + part_count, ring_buffer, count - part_count);
+
+ // mark the copied part of the buffer as free
+ buffer_count = buffer_count - count;
+ read_pos = (read_pos + count) % buffer_size;
+
+ return count;
+ }
+
+ int RingBuffer::write(char *buffer, int count)
+ {
+ // check for a reasonable request
+ if (count <= 0)
+ return count;
+
+ // skip input data if the input buffer is bigger than the ring-buffer
+ if (count > buffer_size)
+ {
+ //DebugWriteln('Write skip data:' + inttostr(count) +',count:'+ inttostr(BufferCount) + '/size:' + inttostr(BufferSize));
+ buffer += count - buffer_size;
+ count = buffer_size;
+ }
+
+ // first step: copy to the area between the write-position and the end of the buffer
+ int part_count = (count < buffer_size - write_pos) ? count : (buffer_size - write_pos);
+ memcpy(ring_buffer + write_pos, buffer, part_count);
+
+ // second step: copy data to front of buffer
+ if (part_count < count)
+ memcpy(ring_buffer, buffer + part_count, count - part_count);
+
+ // update info
+ buffer_count = (buffer_count + count < buffer_size) ? (buffer_count + count) : buffer_size;
+ write_pos = (write_pos + count) % buffer_size;
+
+ // if the buffer is full, we have to reposition the read-position
+ if (buffer_count == buffer_size)
+ read_pos = write_pos;
+
+ return count;
+ }
+
+ int RingBuffer::get_available()
+ {
+ return buffer_count;
+ }
+
+ int RingBuffer::get_size()
+ {
+ return buffer_size;
+ }
+
+ void RingBuffer::flush()
+ {
+ read_pos = 0;
+ write_pos = 0;
+ buffer_count = 0;
+ }
+};
diff --git a/src/base/ringbuffer.hpp b/src/base/ringbuffer.hpp
new file mode 100644
index 00000000..f3e9ebd5
--- /dev/null
+++ b/src/base/ringbuffer.hpp
@@ -0,0 +1,52 @@
+/*
+ * UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef RINGBUFFER_HPP
+#define RINGBUFFER_HPP
+
+namespace usdx
+{
+ class RingBuffer
+ {
+ private:
+ char *ring_buffer;
+ int buffer_count;
+ int buffer_size;
+ int write_pos;
+ int read_pos;
+ public:
+ RingBuffer(int size);
+ ~RingBuffer();
+
+ int read(char* buffer, int count);
+ int write(char *buffer, int count);
+ int get_size();
+ int get_available();
+ void flush(void);
+ };
+};
+
+#endif