yutong look here
Dependencies: FastAnalogIn fastADC
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 }
Generated on Thu Jul 14 2022 01:36:45 by 1.7.2