yutong look here

Dependencies:   FastAnalogIn fastADC

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers circ_buff.hpp Source File

circ_buff.hpp

00001 #pragma once
00002 #include <cstddef>
00003 #include <stdio.h>
00004 #include <string>
00005 #include <cstring>
00006 
00007 #define DEFAULT_BUF_SIZE 512
00008 #define DEFAULT_AE_THRES 100
00009 #define DEFAULT_AF_THRES 412
00010 
00011 template <class T> 
00012 class CircularBuff{
00013     private: 
00014         int buffer_size;
00015         T* buffer;
00016         int read_index;
00017         int write_index;
00018         int window;
00019         int ae_thres;
00020         int af_thres;
00021     public:
00022         CircularBuff();
00023         CircularBuff(int buffsize);
00024         CircularBuff(int buffsize, int window_size);
00025         CircularBuff(int buffsize, int ae_threshold, int af_threshold);
00026         ~CircularBuff();
00027         bool is_full();
00028         bool is_empty();
00029         bool push(T input);
00030         bool push_buff(uint8_t* input_buf, int buf_size);
00031         bool window_possible();
00032         T* pop();
00033         int size();
00034         int capacity();
00035         void print();
00036         void clear();
00037         void set_AE_thres(int thres);
00038         T* read_window();
00039         int get_AE_thres();
00040         bool almost_empty();
00041         void set_AF_thres(int thres);
00042         int get_AF_thres();
00043         bool almost_full();
00044 };
00045 
00046 template <class T> 
00047 CircularBuff<T>::CircularBuff(){
00048     buffer_size = DEFAULT_BUF_SIZE+1;
00049     ae_thres = DEFAULT_AE_THRES;
00050     af_thres = DEFAULT_AF_THRES;
00051     buffer = new T[buffer_size];
00052     read_index = 0;
00053     write_index = 0;
00054 } 
00055 
00056 template <class T> 
00057 CircularBuff<T>::CircularBuff(int buffsize){
00058     buffer_size = buffsize+1;
00059     ae_thres = buffer_size/5;
00060     af_thres = buffer_size*4/5;
00061     buffer = new T[buffer_size];
00062     read_index = 0;
00063     write_index = 0;
00064 } 
00065 template <class T> 
00066 CircularBuff<T>::CircularBuff(int buffsize, int window_size){
00067     buffer_size = buffsize+1;
00068     window = window_size;
00069     buffer = new T[buffer_size];
00070     read_index = 0;
00071     write_index = 0;
00072 } 
00073 
00074 template <class T> 
00075 CircularBuff<T>::CircularBuff(int buffsize, int ae_threshold, int af_threshold){
00076     buffer_size = buffsize+1;
00077     ae_thres = ae_threshold;
00078     af_thres = af_threshold;
00079     buffer = new T[buffer_size];
00080     read_index = 0;
00081     write_index = 0;
00082 } 
00083 
00084 
00085 template <class T> 
00086 CircularBuff<T>::~CircularBuff(){
00087     delete [] buffer;
00088     buffer = NULL;
00089 }
00090 
00091 template <class T> 
00092 bool CircularBuff<T>::is_full(){
00093     if (size() == (buffer_size - 1)){
00094         return true;
00095     }
00096     else{
00097         return false;
00098     }
00099 }
00100 
00101 template <class T> 
00102 bool CircularBuff<T>::is_empty(){
00103     if (size() == 0){
00104         return true;
00105     }
00106     else{
00107         return false;
00108     }
00109 }
00110 
00111 //false if failed, true if success
00112 template <class T> 
00113 bool CircularBuff<T>::push(T input){
00114     if (!is_full()){
00115         buffer[write_index] = input;
00116         write_index = (write_index + 1) % buffer_size;
00117         return true;
00118     }
00119     else{
00120         return false;
00121     }
00122 }
00123 
00124 //false if failed, true if success
00125 //TODO: needs to be optimized
00126 template <class T> 
00127 bool CircularBuff<T>::push_buff(uint8_t* input_buf, int input_buf_size){
00128     int casted_input_buf_size = input_buf_size/sizeof(T);
00129 
00130     if (((size() + casted_input_buf_size) < capacity()) && ((input_buf_size % sizeof(T)) == 0)){
00131         T* casted_input_buf = (T*) input_buf;
00132 
00133         // printf("Buffer contents: [\n");
00134         // for(int i = 0; i < casted_input_buf_size; i++){
00135         //  //printf("%s,", std::to_string(buffer[i]).c_str());
00136         //  printf("%08x,", casted_input_buf[i]);
00137         // }
00138         // printf("\b\n]\n");
00139         int pre_wrap_size = 0;
00140         int post_wrap_size = 0;
00141 
00142         if(write_index + casted_input_buf_size > buffer_size){
00143             pre_wrap_size = buffer_size - write_index;
00144             post_wrap_size = casted_input_buf_size - pre_wrap_size;
00145         }
00146         else{
00147             pre_wrap_size = casted_input_buf_size;
00148         }
00149         std::memmove(buffer + write_index, casted_input_buf, pre_wrap_size * sizeof(T));
00150         std::memmove(buffer, casted_input_buf + pre_wrap_size, post_wrap_size * sizeof(T));
00151 
00152         write_index = (write_index + casted_input_buf_size) % buffer_size;
00153         return true;
00154     }
00155     else{
00156         if (input_buf_size % sizeof(T) != 0){
00157             printf("Buffer cannot be casted to CircularBuff's data type; make sure bytes are alined\n");
00158         }
00159         else{
00160             printf("Input buffer too large\n");
00161         }
00162         return false;
00163     }
00164 }
00165 
00166 //false if failed, true if success
00167 template <class T> 
00168 bool CircularBuff<T>::window_possible(){
00169     if (!is_full()){
00170         if (read_index < write_index){
00171             if ((write_index-1) >= read_index + window){
00172                 return true;
00173             }
00174             else{
00175                 return false;
00176             }
00177         }
00178         else if(write_index == 0){
00179             if (buffer_size-read_index >= window){
00180                     return true;
00181             }
00182             else{
00183                 return false;
00184             }
00185         }   
00186         else{
00187             if((write_index - 1 + (buffer_size-read_index)) >= window){
00188                 return true;
00189             }
00190             else{
00191                 return false;
00192             }
00193         }       
00194         return true;
00195     }
00196     else{
00197         return false;
00198     }
00199 }
00200 
00201 //false if failed, true if success
00202 template <class T> 
00203 T* CircularBuff<T>::pop(){
00204     T* retval;
00205     if (!is_empty()){
00206         retval = buffer + read_index;
00207         read_index = (read_index + 1) % buffer_size;
00208         return retval;
00209     }
00210     else{
00211         return NULL;
00212     }
00213 }
00214 
00215 template <class T> 
00216 int CircularBuff<T>::size(){
00217     return (size_t) ((write_index - read_index + buffer_size) % buffer_size);
00218 }
00219 
00220 template <class T> 
00221 int CircularBuff<T>::capacity(){
00222     return (size_t) buffer_size-1;
00223 }
00224 
00225 template<class T>
00226 void CircularBuff<T>::print(){
00227     printf("Buffer contents: [\n");
00228     for(int i = 0; i < buffer_size; i++){
00229         printf("%s,", std::to_string(buffer[i]).c_str());
00230         //printf("%08x,", buffer[i]);
00231     }
00232     printf("\b\n]\n");
00233     printf("Read index: %d \t Write index: %d \t Size: %d\n", read_index, write_index, size());
00234 }
00235 
00236 template<class T>
00237 void CircularBuff<T>::clear(){
00238     for(int i = 0; i < buffer_size; i++){
00239         buffer[i] = NULL;
00240     }
00241     read_index = 0;
00242     write_index = 0;
00243 }
00244 
00245 template<class T>
00246 void CircularBuff<T>::set_AE_thres(int thres){
00247     ae_thres = thres;
00248 }
00249 
00250 template<class T>
00251 int CircularBuff<T>::get_AE_thres(){
00252     return ae_thres;
00253 }
00254 
00255 template<class T>
00256 bool CircularBuff<T>::almost_empty(){
00257     return (size() < ae_thres);
00258 }
00259 
00260 template<class T>
00261 void CircularBuff<T>::set_AF_thres(int thres){
00262     af_thres = thres;
00263 }
00264 
00265 template<class T>
00266 T* CircularBuff<T>::read_window(){
00267     if(window_possible()){
00268         T* temp = buffer + read_index;
00269         read_index += window;
00270         return temp;
00271     }
00272 }
00273 
00274 template<class T>
00275 int CircularBuff<T>::get_AF_thres(){
00276     return af_thres;
00277 }
00278 
00279 template<class T>
00280 bool CircularBuff<T>::almost_full(){
00281     return (size() > af_thres);
00282 }