diff options
Diffstat (limited to 'gr-trellis/src')
-rwxr-xr-x | gr-trellis/src/examples/test_pccc_turbo1.py | 119 | ||||
-rw-r--r-- | gr-trellis/src/lib/.gitignore | 9 | ||||
-rw-r--r-- | gr-trellis/src/lib/Makefile.am | 3 | ||||
-rw-r--r-- | gr-trellis/src/lib/core_algorithms.cc | 252 | ||||
-rw-r--r-- | gr-trellis/src/lib/core_algorithms.h | 9 | ||||
-rw-r--r-- | gr-trellis/src/lib/generate_trellis.py | 2 | ||||
-rw-r--r-- | gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t | 124 | ||||
-rw-r--r-- | gr-trellis/src/lib/trellis_pccc_decoder_X.h.t | 102 | ||||
-rw-r--r-- | gr-trellis/src/lib/trellis_pccc_decoder_X.i.t | 60 |
9 files changed, 624 insertions, 56 deletions
diff --git a/gr-trellis/src/examples/test_pccc_turbo1.py b/gr-trellis/src/examples/test_pccc_turbo1.py new file mode 100755 index 000000000..1173d0734 --- /dev/null +++ b/gr-trellis/src/examples/test_pccc_turbo1.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import trellis +from gnuradio import eng_notation +import math +import sys +import random +import fsm_utils + + +def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed): + tb = gr.top_block () + + + # TX + src = gr.lfsr_32k_source_s() + src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts + s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality + #src = gr.vector_source_s([0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],False) + enc = trellis.pccc_encoder_ss(fo,0,fi,0,interleaver,K) + code = gr.vector_sink_s() + mod = gr.chunks_to_symbols_sf(constellation,dimensionality) + + # CHANNEL + add = gr.add_ff() + noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed) + + # RX + metrics_in = trellis.metrics_f(fi.O()*fo.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO + scale = gr.multiply_const_ff(1.0/N0) + dec = trellis.pccc_decoder_s(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM) + + fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts + dst = gr.check_lfsr_32k_s() + + tb.connect (src,src_head,s2fsmi,enc,mod) + #tb.connect (src,enc,mod) + #tb.connect(enc,code) + tb.connect (mod,(add,0)) + tb.connect (noise,(add,1)) + tb.connect (add,metrics_in,scale,dec,fsmi2s,dst) + + tb.run() + + #print code.data() + + ntotal = dst.ntotal () + nright = dst.nright () + runlength = dst.runlength () + return (ntotal,ntotal-nright) + + +def main(args): + nargs = len (args) + if nargs == 5: + fname_out=args[0] + fname_in=args[1] + esn0_db=float(args[2]) # Es/No in dB + IT=int(args[3]) + rep=int(args[4]) # number of times the experiment is run to collect enough errors + else: + sys.stderr.write ('usage: test_pccc_turbo.py fsm_name_1 fsm_fname_2 Es/No_db iterations repetitions\n') + sys.exit (1) + + # system parameters + Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short) + fo=trellis.fsm(fname_out) # get the outer FSM specification from a file + fi=trellis.fsm(fname_in) # get the innner FSM specification from a file + bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol + if fo.I() != fi.I(): + sys.stderr.write ('Incompatible input cardinality between two FSMs.\n') + sys.exit (1) + K=Kb/bitspersymbol # packet size in trellis steps + interleaver=trellis.interleaver(K,666) # construct a random interleaver + #modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations + dimensionality = 4 + constellation = [ 1, 0, 1, 0,\ + 1, 0,-1, 0,\ + 1, 0, 0, 1,\ + 1, 0, 0,-1,\ + -1, 0, 1, 0,\ + -1, 0,-1, 0,\ + -1, 0, 0, 1,\ + -1, 0, 0,-1,\ + 0, 1, 1, 0,\ + 0, 1,-1, 0,\ + 0, 1, 0, 1,\ + 0, 1, 0,-1,\ + 0,-1, 1, 0,\ + 0,-1,-1, 0,\ + 0,-1, 0, 1,\ + 0,-1, 0,-1,] # equivalent to 2 QPSK symbols + if len(constellation)/dimensionality != fi.O()*fo.O(): + sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n') + sys.exit (1) + # calculate average symbol energy + Es = 0 + for i in range(len(constellation)): + Es = Es + constellation[i]**2 + Es = Es / (len(constellation)/dimensionality) + N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance + + tot_s=0 # total number of transmitted shorts + terr_s=0 # total number of shorts in error + terr_p=0 # total number of packets in error + for i in range(rep): + (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations + tot_s=tot_s+s + terr_s=terr_s+e + terr_p=terr_p+(terr_s!=0) + if ((i+1)%10==0): # display progress + print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s) + # estimate of the (short or bit) error rate + print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s) + + +if __name__ == '__main__': + main (sys.argv[1:]) diff --git a/gr-trellis/src/lib/.gitignore b/gr-trellis/src/lib/.gitignore index 8120aad94..40e0ebd74 100644 --- a/gr-trellis/src/lib/.gitignore +++ b/gr-trellis/src/lib/.gitignore @@ -140,6 +140,15 @@ /trellis_sccc_decoder_i.h /trellis_sccc_decoder_i.i /trellis_sccc_decoder_i.cc +/trellis_pccc_decoder_b.h +/trellis_pccc_decoder_b.i +/trellis_pccc_decoder_b.cc +/trellis_pccc_decoder_s.h +/trellis_pccc_decoder_s.i +/trellis_pccc_decoder_s.cc +/trellis_pccc_decoder_i.h +/trellis_pccc_decoder_i.i +/trellis_pccc_decoder_i.cc /trellis_pccc_encoder_bb.cc /trellis_pccc_encoder_bb.h /trellis_pccc_encoder_bb.i diff --git a/gr-trellis/src/lib/Makefile.am b/gr-trellis/src/lib/Makefile.am index 42ea17aca..05cffb7b1 100644 --- a/gr-trellis/src/lib/Makefile.am +++ b/gr-trellis/src/lib/Makefile.am @@ -50,6 +50,9 @@ core_generator = \ trellis_sccc_decoder_X.cc.t \ trellis_sccc_decoder_X.h.t \ trellis_sccc_decoder_X.i.t \ + trellis_pccc_decoder_X.cc.t \ + trellis_pccc_decoder_X.h.t \ + trellis_pccc_decoder_X.i.t \ trellis_viterbi_X.cc.t \ trellis_viterbi_X.h.t \ trellis_viterbi_X.i.t diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc index b7037926e..91ac8fbdf 100644 --- a/gr-trellis/src/lib/core_algorithms.cc +++ b/gr-trellis/src/lib/core_algorithms.cc @@ -22,6 +22,8 @@ #include <cstring> #include <stdexcept> +//#include <cstdio> +#include <iostream> #include "core_algorithms.h" #include "calc_metric.h" @@ -976,93 +978,92 @@ void sccc_decoder( const float *iprioro, T *data ) { - -//allocate space for priori, and posti of inner FSM -std::vector<float> ipriori(blocklength*FSMi.I(),0.0); -std::vector<float> iposti(blocklength*FSMi.I()); - -//allocate space for priori, prioro and posto of outer FSM -std::vector<float> opriori(blocklength*FSMo.I(),0.0); -std::vector<float> oprioro(blocklength*FSMo.O()); -std::vector<float> oposti(blocklength*FSMo.I()); -std::vector<float> oposto(blocklength*FSMo.O()); - -for(int rep=0;rep<repetitions;rep++) { - // run inner SISO - siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), + //allocate space for priori, and posti of inner FSM + std::vector<float> ipriori(blocklength*FSMi.I(),0.0); + std::vector<float> iposti(blocklength*FSMi.I()); + + //allocate space for priori, prioro and posto of outer FSM + std::vector<float> opriori(blocklength*FSMo.I(),0.0); + std::vector<float> oprioro(blocklength*FSMo.O()); + std::vector<float> oposti(blocklength*FSMo.I()); + std::vector<float> oposto(blocklength*FSMo.O()); + + for(int rep=0;rep<repetitions;rep++) { + // run inner SISO + siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), blocklength, STi0,STiK, true, false, p2mymin, &(ipriori[0]), &(iprioro[0]), &(iposti[0]) - ); + ); - //interleave soft info inner -> outer - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; - //} - memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float)); - } + //interleave soft info inner -> outer + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.DEINTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; + //} + memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float)); + } - // run outer SISO + // run outer SISO - if(rep<repetitions-1) { // do not produce posti - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + if(rep<repetitions-1) { // do not produce posti + siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), blocklength, STo0,SToK, false, true, p2mymin, &(opriori[0]), &(oprioro[0]), &(oposto[0]) - ); - - //interleave soft info outer --> inner - for(int k=0;k<blocklength;k++) { - int ki = INTERLEAVER.DEINTER()[k]; - //for(int i=0;i<FSMi.I();i++) { - //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; - //} - memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float)); - } - } - else // produce posti but not posto + ); + + //interleave soft info outer --> inner + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.DEINTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; + //} + memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float)); + } + } + else {// produce posti but not posto - siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), blocklength, STo0,SToK, true, false, p2mymin, &(opriori[0]), &(oprioro[0]), &(oposti[0]) - ); + ); - /* - viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + /* + viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), blocklength, STo0,SToK, &(oprioro[0]), data - ); - */ - -} + ); + */ + } + } // end repetitions -// generate hard decisions -for(int k=0;k<blocklength;k++) { - float min=INF; - int mini=0; - for(int i=0;i<FSMo.I();i++) { - if(oposti[k*FSMo.I()+i]<min) { - min=oposti[k*FSMo.I()+i]; - mini=i; + // generate hard decisions + for(int k=0;k<blocklength;k++) { + float min=INF; + int mini=0; + for(int i=0;i<FSMo.I();i++) { + if(oposti[k*FSMo.I()+i]<min) { + min=oposti[k*FSMo.I()+i]; + mini=i; + } } + data[k]=(T)mini; } - data[k]=(T)mini; -} @@ -1097,3 +1098,142 @@ void sccc_decoder<int>( const float *iprioro, int *data ); + +//==================================================== + +template<class T> +void pccc_decoder( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + const float *cprioro, T *data +) +{ + + //allocate space for priori, prioro and posti of FSM1 + std::vector<float> priori1(blocklength*FSM1.I(),0.0); + std::vector<float> prioro1(blocklength*FSM1.O()); + std::vector<float> posti1(blocklength*FSM1.I()); + + //allocate space for priori, prioro and posti of FSM2 + std::vector<float> priori2(blocklength*FSM2.I(),0.0); + std::vector<float> prioro2(blocklength*FSM2.O()); + std::vector<float> posti2(blocklength*FSM2.I()); + + //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...) + for (int k=0;k<blocklength;k++) { + //std::cout << k << std::endl; + for(int i=0;i<FSM1.O();i++) { + float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0]; + for(int j=1;j<FSM2.O();j++) + x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]); + prioro1[k*FSM1.O()+i]=x; + //std::cout << prioro1[k*FSM1.O()+i] << ", "; + } + //std::cout << std::endl; + for(int i=0;i<FSM2.O();i++) { + float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i]; + for(int j=1;j<FSM1.O();j++) + x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]); + prioro2[k*FSM2.O()+i]=x; + } + } + + for(int rep=0;rep<repetitions;rep++) { + // run SISO 1 + siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(), + FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(), + blocklength, + ST10,ST1K, + true, false, + p2mymin, + &(priori1[0]), &(prioro1[0]), &(posti1[0]) + ); + + //for(int k=0;k<blocklength;k++){ + //for(int i=0;i<FSM1.I();i++) + //std::cout << posti1[k*FSM1.I()+i] << ", "; + //std::cout << std::endl; + //} + + //interleave soft info 1 -> 2 + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.INTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; + //} + memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float)); + } + + // run SISO 2 + siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(), + FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(), + blocklength, + ST20,ST2K, + true, false, + p2mymin, + &(priori2[0]), &(prioro2[0]), &(posti2[0]) + ); + + //interleave soft info 2 --> 1 + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.INTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; + //} + memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float)); + } + + } // end repetitions + + // generate hard decisions + for(int k=0;k<blocklength;k++) { + for(int i=0;i<FSM1.I();i++) + posti1[k*FSM1.I()+i] = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]); + float min=INF; + int mini=0; + for(int i=0;i<FSM1.I();i++) { + if(posti1[k*FSM1.I()+i]<min) { + min=posti1[k*FSM1.I()+i]; + mini=i; + } + } + data[k]=(T)mini; + //std::cout << data[k] << ", "<< std::endl; + } + //std::cout << std::endl; + + + +} + +//---------------- + +template +void pccc_decoder<unsigned char>( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + const float *cprioro, unsigned char *data +); + +template +void pccc_decoder<short>( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + const float *cprioro, short *data +); + +template +void pccc_decoder<int>( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + const float *cprioro, int *data +); + diff --git a/gr-trellis/src/lib/core_algorithms.h b/gr-trellis/src/lib/core_algorithms.h index e52a22b8e..fdb5f398e 100644 --- a/gr-trellis/src/lib/core_algorithms.h +++ b/gr-trellis/src/lib/core_algorithms.h @@ -114,6 +114,15 @@ void sccc_decoder( ); +template<class T> +void pccc_decoder( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + const float *cprioro, T *data +); + #endif diff --git a/gr-trellis/src/lib/generate_trellis.py b/gr-trellis/src/lib/generate_trellis.py index 32cf54db7..9f845f74a 100644 --- a/gr-trellis/src/lib/generate_trellis.py +++ b/gr-trellis/src/lib/generate_trellis.py @@ -35,6 +35,7 @@ other_roots = [ 'trellis_viterbi_combined_XX', 'trellis_sccc_decoder_combined_XX', 'trellis_sccc_decoder_X', + 'trellis_pccc_decoder_X', ] other_signatures = ( @@ -46,6 +47,7 @@ other_signatures = ( ['sb','ss','si','ib','is','ii','fb','fs','fi','cb','cs','ci'], ['fb','fs','fi','cb','cs','ci'], ['b','s','i'], + ['b','s','i'], ) diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t new file mode 100644 index 000000000..34dd2eb87 --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t @@ -0,0 +1,124 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME@.h> +#include <gr_io_signature.h> +#include <assert.h> +#include <iostream> +#include "core_algorithms.h" + + +static const float INF = 1.0e9; + +@SPTR_NAME@ +trellis_make_@BASE_NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE +) +{ + return gnuradio::get_initial_sptr (new @NAME@ ( + FSM1, ST10, ST1K, + FSM2, ST20, ST2K, + INTERLEAVER, + blocklength, + repetitions, + SISO_TYPE + )); +} + +@NAME@::@NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE +) + : gr_block ("@BASE_NAME@", + gr_make_io_signature (1, 1, sizeof (float)), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@))), + d_FSM1 (FSM1), d_ST10 (ST10), d_ST1K (ST1K), + d_FSM2 (FSM2), d_ST20 (ST20), d_ST2K (ST2K), + d_INTERLEAVER (INTERLEAVER), + d_blocklength (blocklength), + d_repetitions (repetitions), + d_SISO_TYPE (SISO_TYPE) +{ + assert(d_FSM1.I() == d_FSM2.I()); + set_relative_rate (1.0 / ((double) d_FSM1.O() * d_FSM2.O())); + set_output_multiple (d_blocklength); +} + + +void +@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + assert (noutput_items % d_blocklength == 0); + int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items ; + ninput_items_required[0] = input_required; +} + + + +//=========================================================== + +int +@NAME@::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + assert (noutput_items % d_blocklength == 0); + int nblocks = noutput_items / d_blocklength; + + float (*p2min)(float, float) = NULL; + if(d_SISO_TYPE == TRELLIS_MIN_SUM) + p2min = &min; + else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT) + p2min = &min_star; + + + const float *in = (const float *) input_items[0]; + @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]; + for (int n=0;n<nblocks;n++) { + pccc_decoder( + d_FSM1, d_ST10, d_ST1K, + d_FSM2, d_ST20, d_ST2K, + d_INTERLEAVER, d_blocklength, d_repetitions, + p2min, + &(in[n*d_blocklength*d_FSM1.O()*d_FSM2.O()]),&(out[n*d_blocklength]) + ); + } + + consume_each (d_FSM1.O() * d_FSM2.O() * noutput_items ); + return noutput_items; +} diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t new file mode 100644 index 000000000..ff4b7a1f8 --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t @@ -0,0 +1,102 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include "fsm.h" +#include "interleaver.h" +#include <gr_block.h> +#include <vector> +#include "siso_type.h" + +class @NAME@; +typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; + +@SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE // perform "min-sum" or "sum-product" combining +); + + +/*! + * \ingroup coding_blk + */ +class @NAME@ : public gr_block +{ + fsm d_FSM1; + fsm d_FSM2; + int d_ST10; + int d_ST1K; + int d_ST20; + int d_ST2K; + interleaver d_INTERLEAVER; + int d_blocklength; + int d_repetitions; + trellis_siso_type_t d_SISO_TYPE; + std::vector<float> d_buffer; + + friend @SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE + ); + + @NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE + ); + +public: + fsm FSM1 () const { return d_FSM1; } + fsm FSM2 () const { return d_FSM2; } + int ST10 () const { return d_ST10; } + int ST1K () const { return d_ST1K; } + int ST20 () const { return d_ST20; } + int ST2K () const { return d_ST2K; } + interleaver INTERLEAVER () const { return d_INTERLEAVER; } + int blocklength () const { return d_blocklength; } + int repetitions () const { return d_repetitions; } + trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; } + + void forecast (int noutput_items, + gr_vector_int &ninput_items_required); + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t new file mode 100644 index 000000000..83d7fe969 --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@); + +@SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE +); + + +class @NAME@ : public gr_block +{ +private: + @NAME@ ( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE + ); + +public: + fsm FSM1 () const { return d_FSM1; } + fsm FSM2 () const { return d_FSM2; } + int ST10 () const { return d_ST10; } + int ST1K () const { return d_ST1K; } + int ST20 () const { return d_ST20; } + int ST2K () const { return d_ST2K; } + interleaver INTERLEAVER () const { return d_INTERLEAVER; } + int blocklength () const { return d_blocklength; } + int repetitions () const { return d_repetitions; } + trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; } +}; |