diff options
Diffstat (limited to '')
-rw-r--r-- | src/base/URingBuffer.pas | 165 | ||||
-rw-r--r-- | src/base/ringbuffer.cpp | 127 | ||||
-rw-r--r-- | src/base/ringbuffer.hpp | 52 |
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 |