![]() |
ccsoft
0.0.0
Convolutional codes library with soft decision decoding
|
00001 /* 00002 Copyright 2013 Edouard Griffiths <f4exb at free dot fr> 00003 00004 This file is part of CCSoft. A Convolutional Codes Soft Decoding library 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA 00019 00020 Convolutional encoder class 00021 00022 */ 00023 #ifndef __CC_ENCODING_BASE_H__ 00024 #define __CC_ENCODING_BASE_H__ 00025 00026 #include "CCSoft_Exception.h" 00027 #include <vector> 00028 #include <iostream> 00029 00030 namespace ccsoft 00031 { 00032 00039 template<typename T_Register> 00040 void print_register(const T_Register& reg, std::ostream& os) 00041 { 00042 os << std::hex << reg; 00043 os << std::dec; 00044 } 00045 00051 template<> 00052 void print_register<unsigned char>(const unsigned char& reg, std::ostream& os); 00053 00060 template<typename T_IOSymbol> 00061 void print_symbol(const T_IOSymbol& sym, std::ostream& os) 00062 { 00063 os << std::dec << sym; 00064 } 00065 00071 template<> 00072 void print_symbol<unsigned char>(const unsigned char& sym, std::ostream& os); 00073 00081 template<typename T_Register, typename T_IOSymbol> 00082 class CC_Encoding_base 00083 { 00084 public: 00085 00086 //============================================================================================= 00096 CC_Encoding_base(const std::vector<unsigned int>& _constraints, const std::vector<std::vector<T_Register> >& _genpoly_representations) : 00097 k(_constraints.size()), 00098 constraints(_constraints), 00099 genpoly_representations(_genpoly_representations), 00100 m(0) 00101 { 00102 if (k < 1) 00103 { 00104 throw CCSoft_Exception("There must be at least one constraint size"); 00105 } 00106 00107 if (k > sizeof(T_IOSymbol)*8) 00108 { 00109 throw CCSoft_Exception("Number of input bits not supported by I/O symbol type"); 00110 } 00111 00112 if (genpoly_representations.size() != k) 00113 { 00114 throw CCSoft_Exception("Generator polynomial representations size error"); 00115 } 00116 00117 unsigned int min_nb_outputs = genpoly_representations[0].size(); 00118 00119 for (unsigned int ci=0; ci < constraints.size(); ci++) 00120 { 00121 if (constraints[ci] > sizeof(T_Register)*8) 00122 { 00123 throw CCSoft_Exception("One constraint size is too large for the size of the registers"); 00124 } 00125 00126 if (genpoly_representations[ci].size() < min_nb_outputs) 00127 { 00128 min_nb_outputs = genpoly_representations[ci].size(); 00129 } 00130 00131 if (constraints[ci] > m) 00132 { 00133 m = constraints[ci]; 00134 } 00135 } 00136 00137 n = min_nb_outputs; 00138 00139 if (n <= k) 00140 { 00141 throw CCSoft_Exception("The number of outputs must be larger than the number of inputs"); 00142 } 00143 00144 if (n > sizeof(T_IOSymbol)*8) 00145 { 00146 throw CCSoft_Exception("Number of output bits not supported by I/O symbol type"); 00147 } 00148 } 00149 00150 //============================================================================================= 00154 virtual ~CC_Encoding_base() 00155 {} 00156 00157 //============================================================================================= 00162 virtual T_Register& get_register(unsigned int index) = 0; 00163 00164 //============================================================================================= 00172 bool encode(const T_IOSymbol& in_symbol, T_IOSymbol& out_symbol, bool no_step = false) 00173 { 00174 T_IOSymbol w_in = in_symbol; 00175 00176 // load registers with new symbol bits 00177 for (unsigned int ki=0; ki<k; ki++) 00178 { 00179 if (no_step) 00180 { 00181 get_register(ki) >>= 1; // flush bit 00182 } 00183 get_register(ki) <<= 1; // make room for bit 00184 get_register(ki) += w_in & 1; // insert bit 00185 w_in >>= 1; // move to next input bit 00186 } 00187 00188 out_symbol = 0; 00189 T_IOSymbol symbol_bit; 00190 00191 for (unsigned int ni=0; ni<n; ni++) 00192 { 00193 symbol_bit = 0; 00194 00195 for (unsigned int ki=0; ki<k; ki++) 00196 { 00197 symbol_bit ^= (xorbits(get_register(ki)&genpoly_representations[ki][ni]) ? 1 : 0); 00198 } 00199 00200 out_symbol += symbol_bit << ni; 00201 } 00202 00203 return true; 00204 } 00205 00206 //============================================================================================= 00211 void print(std::ostream& os) 00212 { 00213 std::cout << "k=" << k << ", n=" << n << ", m=" << m << std::endl; 00214 00215 for (unsigned int ci=0; ci<k; ci++) 00216 { 00217 os << ci << " (" << constraints[ci] << ") : "; 00218 00219 for (unsigned int gi=0; gi<n; gi++) 00220 { 00221 print_register(genpoly_representations[ci][gi], os); 00222 os << " "; 00223 } 00224 00225 os << std::endl; 00226 } 00227 } 00228 00232 unsigned int get_k() const 00233 { 00234 return k; 00235 } 00236 00240 unsigned int get_n() const 00241 { 00242 return n; 00243 } 00244 00248 unsigned int get_m() const 00249 { 00250 return m; 00251 } 00252 00253 protected: 00254 00261 bool xorbits(const T_Register& reg) 00262 { 00263 T_Register w_reg = reg; 00264 unsigned int nb_ones = 0; 00265 00266 while(w_reg != 0) 00267 { 00268 nb_ones += w_reg % 2; 00269 w_reg /= 2; 00270 } 00271 00272 return (nb_ones % 2) == 1; 00273 } 00274 00275 unsigned int k; 00276 unsigned int n; 00277 unsigned int m; 00278 std::vector<unsigned int> constraints; 00279 std::vector<std::vector<T_Register> > genpoly_representations; 00280 }; 00281 00282 } // namespace ccsoft 00283 00284 00285 #endif // __CC_ENCODING_H__