00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2002 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 */ 00022 00023 #ifndef _CONVOLUTIONAL_INTERLEAVER_H_ 00024 #define _CONVOLUTIONAL_INTERLEAVER_H_ 00025 00026 #include <vector> 00027 #include <interleaver_fifo.h> 00028 00033 template<class symbol_type> 00034 class convolutional_interleaver { 00035 public: 00036 00037 convolutional_interleaver (bool interleave_p, int nbanks, int fifo_size_incr); 00038 virtual ~convolutional_interleaver (); 00039 00041 void reset (); 00042 00044 void sync () { m_commutator = 0; } 00045 00047 int end_to_end_delay (); 00048 00050 symbol_type transform (symbol_type input){ 00051 symbol_type retval = m_fifo[m_commutator]->stuff (input); 00052 m_commutator++; 00053 if (m_commutator >= m_nbanks) 00054 m_commutator = 0; 00055 return retval; 00056 } 00057 00059 void transform (symbol_type *out, const symbol_type *in, int nsymbols); 00060 00061 protected: 00062 int m_commutator; 00063 int m_nbanks; 00064 int m_fifo_size_incr; 00065 std::vector<interleaver_fifo<symbol_type> *> m_fifo; 00066 }; 00067 00068 template<class symbol_type> 00069 convolutional_interleaver<symbol_type>::convolutional_interleaver ( 00070 bool interleave_p, 00071 int nbanks, 00072 int fifo_size_incr) 00073 { 00074 assert (nbanks >= 1); 00075 assert (fifo_size_incr >= 1); 00076 00077 m_nbanks = nbanks; 00078 m_fifo_size_incr = fifo_size_incr; 00079 00080 m_fifo.resize (nbanks); 00081 00082 if (interleave_p){ // configure as interleaver 00083 for (int i = 0; i < nbanks; i++) 00084 m_fifo[i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr); 00085 } 00086 else { // configure as de-interleaver 00087 for (int i = 0; i < nbanks; i++) 00088 m_fifo[nbanks - 1 - i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr); 00089 } 00090 sync (); 00091 } 00092 00093 template<class symbol_type> 00094 convolutional_interleaver<symbol_type>::~convolutional_interleaver () 00095 { 00096 for (int i = 0; i < m_nbanks; i++) 00097 delete m_fifo[i]; 00098 } 00099 00100 template<class symbol_type> void 00101 convolutional_interleaver<symbol_type>::reset () 00102 { 00103 sync (); 00104 for (int i = 0; i < m_nbanks; i++) 00105 m_fifo[i]->reset (); 00106 } 00107 00108 template<class symbol_type> int 00109 convolutional_interleaver<symbol_type>::end_to_end_delay () 00110 { 00111 int m = m_nbanks * m_fifo_size_incr; 00112 return m * (m_nbanks - 1); 00113 } 00114 00115 template<class symbol_type> void 00116 convolutional_interleaver<symbol_type>::transform (symbol_type *out, 00117 const symbol_type *in, 00118 int nsymbols) 00119 { 00120 // we may want to unroll this a couple of times... 00121 for (int i = 0; i < nsymbols; i++) 00122 out[i] = transform (in[i]); 00123 } 00124 00125 #endif /* _CONVOLUTIONAL_INTERLEAVER_H_ */