From f3f3f15d90ae9c0a8fec183efdfd0dcb8bd054eb Mon Sep 17 00:00:00 2001 From: Winfried Ritsch Date: Tue, 3 May 2005 07:18:08 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2884, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/iem/iemstream/; revision=2885 --- fifo.h | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 fifo.h (limited to 'fifo.h') diff --git a/fifo.h b/fifo.h new file mode 100644 index 0000000..0ed7843 --- /dev/null +++ b/fifo.h @@ -0,0 +1,142 @@ +/************************************************************* + * + * streaming external for PD + * + * File: fifo.h + * + * Description: Implementation of a FIFO template class + * + * Author: Thomas Grill (t.grill@gmx.net) + * + *************************************************************/ + +#ifndef _FIFO_H_ +#define _FIFO_H_ + +#include + +#include +#define ASSERT assert + + +/*! FIFO class + \note not thread-safe +*/ +template +class Fifo +{ +public: + Fifo(int n = 0): size(n), arr(new T[n]),rd(0),wr(0),have(0) {} + ~Fifo() { if(arr) delete[] arr; } + + //! Clear fifo + void Clear() { rd = wr = have = 0; } + + //! Get total fifo size + int Size() const { return size; } + //! Get number of items in fifo + int Have() const { return have; } + //! Get free fifo size + int Free() const { return size-have; } + + //! Get pointer to beginning of contained data + T *ReadPtr() const { return arr+rd; } + //! Get number of items from read pos to end of contiguous space + int ReadSamples() const { return size-rd; } + //! Get pointer to beginning of free space + T *WritePtr() const { return arr+wr; } + //! Get number of items from write pos to end of contiguous space + int WriteSamples() const { return size-wr; } + + /*! Resize FIFO + \param nsz new FIFO size + \param keep keep data? + \return true if all data could be kept + */ + bool Resize(int nsz,bool keep) + { + if(keep) { + bool all = true; + T *narr = new T[nsz]; + // try to keep newest data + int s = Have()-nsz; + if(s > 0) { + // skip items that don't fit into new buffer + all = false; + int r = Read(s,NULL); + ASSERT(r == s); + } + s = Have(); + int r = Read(s,narr); + ASSERT(r == s); + + delete[] arr; + arr = narr; size = nsz; + Clear(); + return all; + } + else { + delete[] arr; + arr = new T[size = nsz]; + Clear(); + return true; + } + } + + /*! Write data to fifo + \param n number of items to write + \param buf memory buffer containing items + \return number of written items + */ + int Write(int n,const T *buf) + { + if(n > Free()) n = Free(); + + if(wr+n >= size) { + // wrap-over + int ch1 = size-wr; + memcpy(arr+wr,buf,ch1*sizeof(T)); + wr = n-ch1; + memcpy(arr,buf+ch1,wr*sizeof(T)); + } + else { + memcpy(arr+wr,buf,n*sizeof(T)); + wr += n; + } + + have += n; + return n; + } + + /*! Read data from fifo + \param n number of items to read + \param buf memory buffer to store items (NULL to simply skip items) + \return number of read items + */ + int Read(int n,T *buf) + { + if(n > Have()) n = Have(); + + if(rd+n >= size) { + // wrap-over + int ch1 = size-rd; + if(buf) memcpy(buf,arr+rd,ch1*sizeof(T)); + rd = n-ch1; + if(buf) memcpy(buf+ch1,arr,rd*sizeof(T)); + } + else { + if(buf) memcpy(buf,arr+rd,n*sizeof(T)); + rd += n; + } + + have -= n; + return n; + } + +protected: + int size; + int rd,wr,have; + mutable T *arr; +}; + +#endif -- cgit v1.2.1