00001 /* 00002 * circular.h 00003 * 00004 * Copyright (C) 2008 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Template for a circular buffer 00032 */ 00033 00034 #ifndef WAVEPACKET_UTIL_CIRCULAR_H__ 00035 #define WAVEPACKET_UTIL_CIRCULAR_H__ 00036 00037 00038 /// \ingroup util 00039 /// Simple circular buffer. 00040 /// You can repeatedly add samples, and this class will keep only the most 00041 /// current N samples in the buffer. You can ask for the number of samples in 00042 /// the buffer, and iterate through them. Starting at index 0 means you will 00043 /// always walk forward from the oldest to the newest sample in the buffer. 00044 template <class T> 00045 class circular_buffer_t { 00046 public: 00047 // constructor --------------------------------------------------------- 00048 circular_buffer_t(IN int size) { 00049 ASSERT(size > 0, "Bad size: %d", size); 00050 m_buffer.reserve(size); 00051 m_idx = 0; 00052 m_max = size; 00053 m_size = 0; 00054 } 00055 00056 // circular_buffer_t - public class methods ---------------------------- 00057 void addSample(IN const T& t) { 00058 m_buffer[m_idx] = t; 00059 00060 // if buffer isn't full, increment size 00061 if (m_size < m_max) { 00062 ++m_size; 00063 } 00064 00065 // increment index 00066 m_idx = (m_idx + 1) % m_max; 00067 } 00068 00069 int size(void) const throw() { return m_size; } 00070 00071 /// idx = 0 is the oldest sample, always 00072 const T& getSample(IN int idx) const throw() { 00073 idx = this->getActualIndex(idx); 00074 return m_buffer[idx]; 00075 } 00076 00077 /// idx = 0 is the oldest sample, always 00078 T& getSample(IN int idx) throw() { 00079 idx = this->getActualIndex(idx); 00080 return m_buffer[idx]; 00081 } 00082 00083 private: 00084 typedef std::vector<T> vec_type_t; 00085 00086 int getActualIndex(IN int idx) const throw() { 00087 ASSERT(idx >= 0, "Bad index: %d", idx); 00088 ASSERT(idx < m_size, "Bad index: %d", idx); 00089 00090 if (m_size >= m_max) { 00091 idx += m_idx; 00092 idx = idx % m_max; 00093 } 00094 return idx; 00095 } 00096 00097 vec_type_t m_buffer; 00098 int m_max; ///<- max allowed size 00099 int m_idx; ///<- current index 00100 int m_size; ///<- current size 00101 }; 00102 00103 00104 00105 #endif // WAVEPACKET_UTIL_CIRCULAR_H__ 00106