summaryrefslogtreecommitdiff
path: root/gr-trellis
diff options
context:
space:
mode:
authorBen Reynwar2011-06-13 13:30:19 -0700
committerBen Reynwar2011-06-13 13:30:19 -0700
commitf73984a6b43af4c4795af4b91657cc7b1ff49dae (patch)
treef7ed1390445a1a3e8905dba741163a3876ad40f2 /gr-trellis
parent2c8b1d999e7388c4513149615b5c7ebedb854d35 (diff)
parent5ce630cbce6460b739b175257ce0d717095a55f4 (diff)
downloadgnuradio-f73984a6b43af4c4795af4b91657cc7b1ff49dae.tar.gz
gnuradio-f73984a6b43af4c4795af4b91657cc7b1ff49dae.tar.bz2
gnuradio-f73984a6b43af4c4795af4b91657cc7b1ff49dae.zip
Merge branch '8psk' of https://github.com/trondeau/gnuradio into 8psk
Diffstat (limited to 'gr-trellis')
-rw-r--r--gr-trellis/doc/gr-trellis.xml34
-rw-r--r--gr-trellis/src/examples/Makefile.am2
-rw-r--r--gr-trellis/src/examples/README24
-rwxr-xr-xgr-trellis/src/examples/test_pccc_turbo1.py119
-rwxr-xr-xgr-trellis/src/examples/test_sccc_hard.py1
-rwxr-xr-xgr-trellis/src/examples/test_sccc_soft.py1
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo.py9
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo1.py (renamed from gr-trellis/src/examples/test_tcm2.py)75
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo2.py101
-rwxr-xr-xgr-trellis/src/examples/test_tcm.py30
-rwxr-xr-xgr-trellis/src/examples/test_tcm_bit.py (renamed from gr-trellis/src/examples/test_tcm1.py)32
-rwxr-xr-xgr-trellis/src/examples/test_tcm_combined.py29
-rwxr-xr-xgr-trellis/src/examples/test_tcm_parallel.py29
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization.py1
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization1.py1
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization2.py1
-rwxr-xr-xgr-trellis/src/examples/test_viterbi_equalization.py1
-rwxr-xr-xgr-trellis/src/examples/test_viterbi_equalization1.py1
-rw-r--r--gr-trellis/src/lib/.gitignore72
-rw-r--r--gr-trellis/src/lib/Makefile.am24
-rw-r--r--gr-trellis/src/lib/Makefile.gen72
-rw-r--r--gr-trellis/src/lib/calc_metric.cc (renamed from gr-trellis/src/lib/trellis_calc_metric.cc)2
-rw-r--r--gr-trellis/src/lib/calc_metric.h (renamed from gr-trellis/src/lib/trellis_calc_metric.h)6
-rw-r--r--gr-trellis/src/lib/core_algorithms.cc1239
-rw-r--r--gr-trellis/src/lib/core_algorithms.h128
-rw-r--r--gr-trellis/src/lib/generate_trellis.py10
-rw-r--r--gr-trellis/src/lib/interleaver.cc2
-rw-r--r--gr-trellis/src/lib/metric_type.h31
-rw-r--r--gr-trellis/src/lib/siso_type.h (renamed from gr-trellis/src/lib/trellis_siso_type.h)0
-rw-r--r--gr-trellis/src/lib/trellis.i3
-rw-r--r--gr-trellis/src/lib/trellis_metrics_X.cc.t2
-rw-r--r--gr-trellis/src/lib/trellis_metrics_X.h.t2
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t124
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.h.t102
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.i.t60
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t90
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t83
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t50
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t124
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.h.t102
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.i.t60
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t147
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t124
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t73
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t91
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t83
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t50
-rw-r--r--gr-trellis/src/lib/trellis_siso_combined_f.cc9
-rw-r--r--gr-trellis/src/lib/trellis_siso_combined_f.h5
-rw-r--r--gr-trellis/src/lib/trellis_siso_f.cc7
-rw-r--r--gr-trellis/src/lib/trellis_siso_f.h3
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_X.cc.t15
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_X.h.t9
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t3
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t3
55 files changed, 3350 insertions, 151 deletions
diff --git a/gr-trellis/doc/gr-trellis.xml b/gr-trellis/doc/gr-trellis.xml
index ed53715a8..5f1921343 100644
--- a/gr-trellis/doc/gr-trellis.xml
+++ b/gr-trellis/doc/gr-trellis.xml
@@ -279,6 +279,15 @@ The fourth way is specific to FSMs resulting from shift registers, and the outpu
</programlisting>
</listitem>
+<listitem>
+<para>
+I have added other constructors as well, eg, one that constructs an FSM appropriate for modeling an arbitrary CPM scheme; one that constructs the radix-n version of a given FSM; one that constructs the "concatenation" of two FSMs, etc.
+</para>
+</listitem>
+
+
+
+
</itemizedlist>
@@ -397,8 +406,8 @@ r<subscript>k</subscript>=
evaluates
</para>
<para>
-i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
-argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
+i<subscript>0</subscript>= argmin<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
+argmin<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
</para>
<para>
and outputs a sequence of O floats of the form (0,...,0,1,0,...,0), where the
@@ -413,8 +422,8 @@ r<subscript>k</subscript>=
evaluates
</para>
<para>
-i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
-argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> (r<subscript>k,j</subscript>-c<subscript>i,j</subscript>)<superscript>2</superscript>
+i<subscript>0</subscript>= argmin<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
+argmin<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> (r<subscript>k,j</subscript>-c<subscript>i,j</subscript>)<superscript>2</superscript>
</para>
<para>
and outputs a sequence of O floats of the form (d<subscript>1</subscript>,d<subscript>2</subscript>,...,d<subscript>O</subscript>), where the
@@ -813,7 +822,7 @@ The modulated symbols are filtered by the ISI channel and AWGN with appropriate
<para>
Since the output alphabet of the equivalent FSM is quite large (1024) we chose to utilize the combined metrics calculator and Viterbi algorithm block.
-also note that the first L observations are irrelevant and tus can be skipped.
+Also note that the first L observations are irrelevant and thus can be skipped.
</para>
<programlisting>
33 # RX
@@ -863,7 +872,20 @@ The function returns the number of symbols and the number of symbols in error. O
<sect1 id="turbo"><title>Support for Concatenated Coding and Turbo Decoding</title>
<para>
-To do...
+Soft versions of the algorithms have been implemented.
+Also examples of turbo equalization/decoding and of sccc can
+be found in the examples directory.
+
+Recently we added gnuradio blocks for sccc and pccc encoders and
+turbo decoders.
+Although these can be generated by existing gr-trellis blocks (in particular,
+the SISO blocks, as done in some of the python examples) there is an advantage
+in having this functionality as a single block. To see why, think of a turbo decoder with 10 iterations. Previously we needed to concatenate 10 x 2 SISO blocks
+(for a sccc decoder) to emulate the passing of soft information between SISOs over 10 iterartions. With the new block however, only a single such block is needed that internally loops through 10 iterations; this results in space savings
+and possibly time saving as well (since queueing at the input/ouput of the gr-blocks is avoided).
+
+
+Still need to document them...
</para>
diff --git a/gr-trellis/src/examples/Makefile.am b/gr-trellis/src/examples/Makefile.am
index 8fb727acd..92aeadfad 100644
--- a/gr-trellis/src/examples/Makefile.am
+++ b/gr-trellis/src/examples/Makefile.am
@@ -31,8 +31,6 @@ dist_ourdata_DATA = \
dist_ourdata_SCRIPTS = \
fsm_utils.py \
test_tcm.py \
- test_tcm1.py \
- test_tcm2.py \
test_tcm_parallel.py \
test_tcm_combined.py \
test_sccc_hard.py \
diff --git a/gr-trellis/src/examples/README b/gr-trellis/src/examples/README
index d5bad85f5..bd28e3d61 100644
--- a/gr-trellis/src/examples/README
+++ b/gr-trellis/src/examples/README
@@ -6,28 +6,10 @@ fsm_utils.py contains several useful functions.
fsm_files is a directory with some FSM definitions
-If you just want to see what these programs do, run each of the following:
+If you just want to see what these programs do run them;
+in your terminal you will see something like this:
-./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm1.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm2.py 6.0 1000
-./test_tcm_combined.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm_parallel.py fsm_files/awgn1o2_4.fsm 6.0 1000
-
-./test_sccc_hard.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 10.0 100
-./test_sccc_soft.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 8.0 100
-./test_sccc_turbo.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 5.0 100
-
-./test_viterbi_equalization.py 12.0 100
-./test_viterbi_equalization1.py 12.0 100
-./test_turbo_equalization1.py fsm_files/awgn1o2_4.fsm 8.0 100
-./test_turbo_equalization2.py fsm_files/awgn1o2_4.fsm 8.0 100
-
-
-In your terminal you will see something like this:
-
-
-$ ./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
+$ ./test_tcm.py --esn0 6.0 --repetitions 1000
100 98 9.80e-01 102400 9 8.79e-05
200 198 9.90e-01 204800 20 9.77e-05
300 298 9.93e-01 307200 40 1.30e-04
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/examples/test_sccc_hard.py b/gr-trellis/src/examples/test_sccc_hard.py
index a7933a18e..1a81bc59b 100755
--- a/gr-trellis/src/examples/test_sccc_hard.py
+++ b/gr-trellis/src/examples/test_sccc_hard.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_sccc_soft.py b/gr-trellis/src/examples/test_sccc_soft.py
index d96d36e3f..ea296e1e9 100755
--- a/gr-trellis/src/examples/test_sccc_soft.py
+++ b/gr-trellis/src/examples/test_sccc_soft.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_sccc_turbo.py b/gr-trellis/src/examples/test_sccc_turbo.py
index f3a856de7..703ee410b 100755
--- a/gr-trellis/src/examples/test_sccc_turbo.py
+++ b/gr-trellis/src/examples/test_sccc_turbo.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
@@ -92,13 +91,14 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
def main(args):
nargs = len (args)
- if nargs == 4:
+ if nargs == 5:
fname_out=args[0]
fname_in=args[1]
esn0_db=float(args[2]) # Es/No in dB
- rep=int(args[3]) # number of times the experiment is run to collect enough errors
+ 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_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n')
+ sys.stderr.write ('usage: test_sccc_turbo.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
sys.exit (1)
# system parameters
@@ -123,7 +123,6 @@ def main(args):
Es = Es + constellation[i]**2
Es = Es / (len(constellation)/dimensionality)
N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
- IT = 3 # number of turbo iterations
tot_s=0 # total number of transmitted shorts
terr_s=0 # total number of shorts in error
diff --git a/gr-trellis/src/examples/test_tcm2.py b/gr-trellis/src/examples/test_sccc_turbo1.py
index e527fc5ed..8a630c0d4 100755
--- a/gr-trellis/src/examples/test_tcm2.py
+++ b/gr-trellis/src/examples/test_sccc_turbo1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
@@ -9,20 +8,15 @@ import sys
import random
import fsm_utils
-def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
+ tb = gr.top_block ()
# TX
- #packet = [0]*Kb
- #for i in range(Kb-1*16): # last 16 bits = 0 to drive the final state to 0
- #packet[i] = random.randint(0, 1) # random 0s and 1s
- #src = gr.vector_source_s(packet,False)
src = gr.lfsr_32k_source_s()
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
- #b2s = gr.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
- s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
- enc = trellis.encoder_ss(f,0) # initial state = 0
+ s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+ enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
@@ -30,65 +24,54 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
# RX
- metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
+ dec = trellis.sccc_decoder_combined_fs(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM,dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN,1.0)
fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- #s2b = gr.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
- #dst = gr.vector_sink_s();
dst = gr.check_lfsr_32k_s()
-
+ #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
tb.connect (src,src_head,s2fsmi,enc,mod)
- #tb.connect (src,b2s,s2fsmi,enc,mod)
tb.connect (mod,(add,0))
tb.connect (noise,(add,1))
- tb.connect (add,metrics)
- tb.connect (metrics,va,fsmi2s,dst)
- #tb.connect (metrics,va,fsmi2s,s2b,dst)
-
+ #tb.connect (add,head)
+ #tb.connect (tail,fsmi2s,dst)
+ tb.connect (add,dec,fsmi2s,dst)
tb.run()
+
+ #print enc_out.ST(), enc_in.ST()
- # A bit of cheating: run the program once and print the
- # final encoder state..
- # Then put it as the last argument in the viterbi block
- #print "final state = " , enc.ST()
-
ntotal = dst.ntotal ()
nright = dst.nright ()
runlength = dst.runlength ()
- #ntotal = len(packet)
- #if len(dst.data()) != ntotal:
- #print "Error: not enough data\n"
- #nright = 0;
- #for i in range(ntotal):
- #if packet[i]==dst.data()[i]:
- #nright=nright+1
- #else:
- #print "Error in ", i
return (ntotal,ntotal-nright)
-
-
def main(args):
nargs = len (args)
- if nargs == 2:
- esn0_db=float(args[0]) # Es/No in dB
- rep=int(args[1]) # number of times the experiment is run to collect enough errors
+ 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_tcm2.py Es/No_db repetitions\n')
+ sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
sys.exit (1)
# system parameters
- f=trellis.fsm(1,2,[5,7]) # generate FSM specification from the generator matrix
Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
+ 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.O() != fi.I():
+ sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
+ sys.exit (1)
K=Kb/bitspersymbol # packet size in trellis steps
- modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
+ interleaver=trellis.interleaver(K,666) # construct a random interleaver
+ modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
dimensionality = modulation[0]
constellation = modulation[1]
- if len(constellation)/dimensionality != f.O():
+ if len(constellation)/dimensionality != fi.O():
sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
sys.exit (1)
# calculate average symbol energy
@@ -102,11 +85,11 @@ def main(args):
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(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
+ (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)%100==0) : # display progress
+ 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)
diff --git a/gr-trellis/src/examples/test_sccc_turbo2.py b/gr-trellis/src/examples/test_sccc_turbo2.py
new file mode 100755
index 000000000..a47f6400e
--- /dev/null
+++ b/gr-trellis/src/examples/test_sccc_turbo2.py
@@ -0,0 +1,101 @@
+#!/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
+ enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
+ 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(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
+ scale = gr.multiply_const_ff(1.0/N0)
+ dec = trellis.sccc_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_out,inter,enc_in,mod)
+ tb.connect (src,src_head,s2fsmi,enc,mod)
+ tb.connect (mod,(add,0))
+ tb.connect (noise,(add,1))
+ #tb.connect (add,head)
+ #tb.connect (tail,fsmi2s,dst)
+ tb.connect (add,metrics_in,scale,dec,fsmi2s,dst)
+
+ tb.run()
+
+ #print enc_out.ST(), enc_in.ST()
+
+ 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_tcm.py fsm_name_out fsm_fname_in 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.O() != fi.I():
+ sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\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 = modulation[0]
+ constellation = modulation[1]
+ if len(constellation)/dimensionality != fi.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/examples/test_tcm.py b/gr-trellis/src/examples/test_tcm.py
index 62e0c413a..d2e3c6271 100755
--- a/gr-trellis/src/examples/test_tcm.py
+++ b/gr-trellis/src/examples/test_tcm.py
@@ -1,13 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import random
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -71,18 +72,25 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
+ # alternatively you can specify the fsm from its generator matrix
+ #f=trellis.fsm(1,2,[5,7])
Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
K=Kb/bitspersymbol # packet size in trellis steps
@@ -115,4 +123,4 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm1.py b/gr-trellis/src/examples/test_tcm_bit.py
index 746bd9336..008e1e6f0 100755
--- a/gr-trellis/src/examples/test_tcm1.py
+++ b/gr-trellis/src/examples/test_tcm_bit.py
@@ -1,13 +1,15 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import random
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -74,15 +76,21 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
+
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
@@ -100,7 +108,7 @@ def main(args):
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); # noise variance
+ 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
@@ -118,4 +126,4 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm_combined.py b/gr-trellis/src/examples/test_tcm_combined.py
index d2d42b40b..f9b698ae9 100755
--- a/gr-trellis/src/examples/test_tcm_combined.py
+++ b/gr-trellis/src/examples/test_tcm_combined.py
@@ -1,12 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -52,15 +54,20 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm_combined.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
@@ -96,5 +103,5 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm_parallel.py b/gr-trellis/src/examples/test_tcm_parallel.py
index 8e2f5a230..94761fd01 100755
--- a/gr-trellis/src/examples/test_tcm_parallel.py
+++ b/gr-trellis/src/examples/test_tcm_parallel.py
@@ -1,12 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
tb = gr.top_block ()
@@ -58,15 +60,20 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
@@ -102,5 +109,5 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_turbo_equalization.py b/gr-trellis/src/examples/test_turbo_equalization.py
index 612f6951c..0bf691222 100755
--- a/gr-trellis/src/examples/test_turbo_equalization.py
+++ b/gr-trellis/src/examples/test_turbo_equalization.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_turbo_equalization1.py b/gr-trellis/src/examples/test_turbo_equalization1.py
index 8d2feec8a..feae4ce89 100755
--- a/gr-trellis/src/examples/test_turbo_equalization1.py
+++ b/gr-trellis/src/examples/test_turbo_equalization1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_turbo_equalization2.py b/gr-trellis/src/examples/test_turbo_equalization2.py
index f1731016e..ff14299c6 100755
--- a/gr-trellis/src/examples/test_turbo_equalization2.py
+++ b/gr-trellis/src/examples/test_turbo_equalization2.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_viterbi_equalization.py b/gr-trellis/src/examples/test_viterbi_equalization.py
index 86fc00674..eda692024 100755
--- a/gr-trellis/src/examples/test_viterbi_equalization.py
+++ b/gr-trellis/src/examples/test_viterbi_equalization.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_viterbi_equalization1.py b/gr-trellis/src/examples/test_viterbi_equalization1.py
index d26f73bc0..3a65b9363 100755
--- a/gr-trellis/src/examples/test_viterbi_equalization1.py
+++ b/gr-trellis/src/examples/test_viterbi_equalization1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/lib/.gitignore b/gr-trellis/src/lib/.gitignore
index 5dcb1c2c7..816b0aab8 100644
--- a/gr-trellis/src/lib/.gitignore
+++ b/gr-trellis/src/lib/.gitignore
@@ -57,6 +57,24 @@
/trellis_viterbi_i.cc
/trellis_encoder_bb.h
/trellis_encoder_bb.i
+/trellis_sccc_encoder_bb.cc
+/trellis_sccc_encoder_bb.h
+/trellis_sccc_encoder_bb.i
+/trellis_sccc_encoder_bi.cc
+/trellis_sccc_encoder_bi.h
+/trellis_sccc_encoder_bi.i
+/trellis_sccc_encoder_bs.cc
+/trellis_sccc_encoder_bs.h
+/trellis_sccc_encoder_bs.i
+/trellis_sccc_encoder_ii.cc
+/trellis_sccc_encoder_ii.h
+/trellis_sccc_encoder_ii.i
+/trellis_sccc_encoder_si.cc
+/trellis_sccc_encoder_si.h
+/trellis_sccc_encoder_si.i
+/trellis_sccc_encoder_ss.cc
+/trellis_sccc_encoder_ss.h
+/trellis_sccc_encoder_ss.i
/trellis_metrics_s.cc
/trellis_viterbi_combined_fs.h
/trellis_viterbi_combined_fs.i
@@ -94,6 +112,60 @@
/trellis_viterbi_combined_ss.i
/trellis_viterbi_combined_ib.cc
/trellis_viterbi_combined_sb.cc
+/trellis_sccc_decoder_combined_fb.h
+/trellis_sccc_decoder_combined_fb.i
+/trellis_sccc_decoder_combined_fb.cc
+/trellis_sccc_decoder_combined_fs.h
+/trellis_sccc_decoder_combined_fs.i
+/trellis_sccc_decoder_combined_fs.cc
+/trellis_sccc_decoder_combined_fi.h
+/trellis_sccc_decoder_combined_fi.i
+/trellis_sccc_decoder_combined_fi.cc
+/trellis_sccc_decoder_combined_cb.h
+/trellis_sccc_decoder_combined_cb.i
+/trellis_sccc_decoder_combined_cb.cc
+/trellis_sccc_decoder_combined_cs.h
+/trellis_sccc_decoder_combined_cs.i
+/trellis_sccc_decoder_combined_cs.cc
+/trellis_sccc_decoder_combined_ci.h
+/trellis_sccc_decoder_combined_ci.i
+/trellis_sccc_decoder_combined_ci.cc
+/trellis_sccc_decoder_b.h
+/trellis_sccc_decoder_b.i
+/trellis_sccc_decoder_b.cc
+/trellis_sccc_decoder_s.h
+/trellis_sccc_decoder_s.i
+/trellis_sccc_decoder_s.cc
+/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
+/trellis_pccc_encoder_bi.cc
+/trellis_pccc_encoder_bi.h
+/trellis_pccc_encoder_bi.i
+/trellis_pccc_encoder_bs.cc
+/trellis_pccc_encoder_bs.h
+/trellis_pccc_encoder_bs.i
+/trellis_pccc_encoder_ii.cc
+/trellis_pccc_encoder_ii.h
+/trellis_pccc_encoder_ii.i
+/trellis_pccc_encoder_si.cc
+/trellis_pccc_encoder_si.h
+/trellis_pccc_encoder_si.i
+/trellis_pccc_encoder_ss.cc
+/trellis_pccc_encoder_ss.h
+/trellis_pccc_encoder_ss.i
/trellis_generated.i
/generate-stamp
/stamp-*
diff --git a/gr-trellis/src/lib/Makefile.am b/gr-trellis/src/lib/Makefile.am
index d48486448..2f249f62f 100644
--- a/gr-trellis/src/lib/Makefile.am
+++ b/gr-trellis/src/lib/Makefile.am
@@ -41,12 +41,27 @@ core_generator = \
trellis_encoder_XX.cc.t \
trellis_encoder_XX.h.t \
trellis_encoder_XX.i.t \
+ trellis_sccc_encoder_XX.cc.t \
+ trellis_sccc_encoder_XX.h.t \
+ trellis_sccc_encoder_XX.i.t \
+ trellis_pccc_encoder_XX.cc.t \
+ trellis_pccc_encoder_XX.h.t \
+ trellis_pccc_encoder_XX.i.t \
trellis_metrics_X.cc.t \
trellis_metrics_X.h.t \
trellis_metrics_X.i.t \
trellis_viterbi_combined_XX.cc.t \
trellis_viterbi_combined_XX.h.t \
trellis_viterbi_combined_XX.i.t \
+ trellis_sccc_decoder_combined_XX.cc.t \
+ trellis_sccc_decoder_combined_XX.h.t \
+ trellis_sccc_decoder_combined_XX.i.t \
+ 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
@@ -67,9 +82,11 @@ grinclude_HEADERS = \
quicksort_index.h \
base.h \
interleaver.h \
- trellis_calc_metric.h \
+ metric_type.h \
+ calc_metric.h \
+ core_algorithms.h \
trellis_permutation.h \
- trellis_siso_type.h \
+ siso_type.h \
trellis_siso_f.h \
trellis_siso_combined_f.h \
trellis_constellation_metrics_cf.h \
@@ -82,7 +99,8 @@ libgnuradio_trellis_la_SOURCES = \
quicksort_index.cc \
base.cc \
interleaver.cc \
- trellis_calc_metric.cc \
+ calc_metric.cc \
+ core_algorithms.cc \
trellis_permutation.cc \
trellis_siso_f.cc \
trellis_siso_combined_f.cc \
diff --git a/gr-trellis/src/lib/Makefile.gen b/gr-trellis/src/lib/Makefile.gen
index 6a3f83387..534a7466e 100644
--- a/gr-trellis/src/lib/Makefile.gen
+++ b/gr-trellis/src/lib/Makefile.gen
@@ -12,6 +12,30 @@ GENERATED_H = \
trellis_metrics_f.h \
trellis_metrics_i.h \
trellis_metrics_s.h \
+ trellis_pccc_decoder_b.h \
+ trellis_pccc_decoder_i.h \
+ trellis_pccc_decoder_s.h \
+ trellis_pccc_encoder_bb.h \
+ trellis_pccc_encoder_bi.h \
+ trellis_pccc_encoder_bs.h \
+ trellis_pccc_encoder_ii.h \
+ trellis_pccc_encoder_si.h \
+ trellis_pccc_encoder_ss.h \
+ trellis_sccc_decoder_b.h \
+ trellis_sccc_decoder_combined_cb.h \
+ trellis_sccc_decoder_combined_ci.h \
+ trellis_sccc_decoder_combined_cs.h \
+ trellis_sccc_decoder_combined_fb.h \
+ trellis_sccc_decoder_combined_fi.h \
+ trellis_sccc_decoder_combined_fs.h \
+ trellis_sccc_decoder_i.h \
+ trellis_sccc_decoder_s.h \
+ trellis_sccc_encoder_bb.h \
+ trellis_sccc_encoder_bi.h \
+ trellis_sccc_encoder_bs.h \
+ trellis_sccc_encoder_ii.h \
+ trellis_sccc_encoder_si.h \
+ trellis_sccc_encoder_ss.h \
trellis_viterbi_b.h \
trellis_viterbi_combined_cb.h \
trellis_viterbi_combined_ci.h \
@@ -39,6 +63,30 @@ GENERATED_I = \
trellis_metrics_f.i \
trellis_metrics_i.i \
trellis_metrics_s.i \
+ trellis_pccc_decoder_b.i \
+ trellis_pccc_decoder_i.i \
+ trellis_pccc_decoder_s.i \
+ trellis_pccc_encoder_bb.i \
+ trellis_pccc_encoder_bi.i \
+ trellis_pccc_encoder_bs.i \
+ trellis_pccc_encoder_ii.i \
+ trellis_pccc_encoder_si.i \
+ trellis_pccc_encoder_ss.i \
+ trellis_sccc_decoder_b.i \
+ trellis_sccc_decoder_combined_cb.i \
+ trellis_sccc_decoder_combined_ci.i \
+ trellis_sccc_decoder_combined_cs.i \
+ trellis_sccc_decoder_combined_fb.i \
+ trellis_sccc_decoder_combined_fi.i \
+ trellis_sccc_decoder_combined_fs.i \
+ trellis_sccc_decoder_i.i \
+ trellis_sccc_decoder_s.i \
+ trellis_sccc_encoder_bb.i \
+ trellis_sccc_encoder_bi.i \
+ trellis_sccc_encoder_bs.i \
+ trellis_sccc_encoder_ii.i \
+ trellis_sccc_encoder_si.i \
+ trellis_sccc_encoder_ss.i \
trellis_viterbi_b.i \
trellis_viterbi_combined_cb.i \
trellis_viterbi_combined_ci.i \
@@ -66,6 +114,30 @@ GENERATED_CC = \
trellis_metrics_f.cc \
trellis_metrics_i.cc \
trellis_metrics_s.cc \
+ trellis_pccc_decoder_b.cc \
+ trellis_pccc_decoder_i.cc \
+ trellis_pccc_decoder_s.cc \
+ trellis_pccc_encoder_bb.cc \
+ trellis_pccc_encoder_bi.cc \
+ trellis_pccc_encoder_bs.cc \
+ trellis_pccc_encoder_ii.cc \
+ trellis_pccc_encoder_si.cc \
+ trellis_pccc_encoder_ss.cc \
+ trellis_sccc_decoder_b.cc \
+ trellis_sccc_decoder_combined_cb.cc \
+ trellis_sccc_decoder_combined_ci.cc \
+ trellis_sccc_decoder_combined_cs.cc \
+ trellis_sccc_decoder_combined_fb.cc \
+ trellis_sccc_decoder_combined_fi.cc \
+ trellis_sccc_decoder_combined_fs.cc \
+ trellis_sccc_decoder_i.cc \
+ trellis_sccc_decoder_s.cc \
+ trellis_sccc_encoder_bb.cc \
+ trellis_sccc_encoder_bi.cc \
+ trellis_sccc_encoder_bs.cc \
+ trellis_sccc_encoder_ii.cc \
+ trellis_sccc_encoder_si.cc \
+ trellis_sccc_encoder_ss.cc \
trellis_viterbi_b.cc \
trellis_viterbi_combined_cb.cc \
trellis_viterbi_combined_ci.cc \
diff --git a/gr-trellis/src/lib/trellis_calc_metric.cc b/gr-trellis/src/lib/calc_metric.cc
index 0d03fd1a7..0e8f9c2d5 100644
--- a/gr-trellis/src/lib/trellis_calc_metric.cc
+++ b/gr-trellis/src/lib/calc_metric.cc
@@ -22,7 +22,7 @@
#include <float.h>
#include <stdexcept>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
diff --git a/gr-trellis/src/lib/trellis_calc_metric.h b/gr-trellis/src/lib/calc_metric.h
index b9eacb086..d628f44e0 100644
--- a/gr-trellis/src/lib/trellis_calc_metric.h
+++ b/gr-trellis/src/lib/calc_metric.h
@@ -20,12 +20,12 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_TRELLIS_CALC_METRIC_H
-#define INCLUDED_TRELLIS_CALC_METRIC_H
+#ifndef INCLUDED_CALC_METRIC_H
+#define INCLUDED_CALC_METRIC_H
#include <vector>
#include <gr_complex.h>
-#include <gr_metric_type.h>
+#include <metric_type.h>
template <class T>
diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc
new file mode 100644
index 000000000..91ac8fbdf
--- /dev/null
+++ b/gr-trellis/src/lib/core_algorithms.cc
@@ -0,0 +1,1239 @@
+/* -*- 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.
+ */
+
+#include <cstring>
+#include <stdexcept>
+//#include <cstdio>
+#include <iostream>
+#include "core_algorithms.h"
+#include "calc_metric.h"
+
+static const float INF = 1.0e9;
+
+float min(float a, float b)
+{
+ return a <= b ? a : b;
+}
+
+float min_star(float a, float b)
+{
+ return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a));
+}
+
+
+
+
+template <class T>
+void viterbi_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, T *out)//,
+ //std::vector<int> &trace)
+{
+ std::vector<int> trace(S*K);
+ std::vector<float> alpha(S*2);
+ int alphai;
+ float norm,mm,minm;
+ int minmi;
+ int st;
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ alphai=0;
+ for(int k=0;k<K;k++) {
+ norm=INF;
+ for(int j=0;j<S;j++) { // for each next state do ACS
+ minm=INF;
+ minmi=0;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ if((mm=alpha[alphai*S+PS[j][i]]+in[k*O+OS[PS[j][i]*I+PI[j][i]]])<minm)
+ minm=mm,minmi=i;
+ }
+ trace[k*S+j]=minmi;
+ alpha[((alphai+1)%2)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode
+ alphai=(alphai+1)%2;
+ }
+
+ if(SK<0) { // final state not specified
+ minm=INF;
+ minmi=0;
+ for(int i=0;i<S;i++)
+ if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i;
+ st=minmi;
+ }
+ else {
+ st=SK;
+ }
+
+ for(int k=K-1;k>=0;k--) { // traceback
+ int i0=trace[k*S+st];
+ out[k]= (T) PI[st][i0];
+ st=PS[st][i0];
+ }
+
+}
+
+
+template
+void viterbi_algorithm<unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, unsigned char *out);
+
+
+template
+void viterbi_algorithm<short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, short *out);
+
+template
+void viterbi_algorithm<int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, int *out);
+
+
+
+//==============================================
+
+template <class Ti, class To>
+void viterbi_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<Ti> &TABLE,
+ trellis_metric_type_t TYPE,
+ const Ti *in, To *out
+)
+{
+ std::vector<int> trace(S*K);
+ std::vector<float> alpha(S*2);
+ float *metric = new float[O];
+ int alphai;
+ float norm,mm,minm;
+ int minmi;
+ int st;
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ alphai=0;
+ for(int k=0;k<K;k++) {
+ calc_metric(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+ norm=INF;
+ for(int j=0;j<S;j++) { // for each next state do ACS
+ minm=INF;
+ minmi=0;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ if((mm=alpha[alphai*S+PS[j][i]]+metric[OS[PS[j][i]*I+PI[j][i]]])<minm)
+ minm=mm,minmi=i;
+ }
+ trace[k*S+j]=minmi;
+ alpha[((alphai+1)%2)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode
+ alphai=(alphai+1)%2;
+ }
+
+ if(SK<0) { // final state not specified
+ minm=INF;
+ minmi=0;
+ for(int i=0;i<S;i++)
+ if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i;
+ st=minmi;
+ }
+ else {
+ st=SK;
+ }
+
+ for(int k=K-1;k>=0;k--) { // traceback
+ int i0=trace[k*S+st];
+ out[k]= (To) PI[st][i0];
+ st=PS[st][i0];
+ }
+
+ delete [] metric;
+
+}
+
+// Ti = s i f c
+// To = b s i
+
+//---------------
+
+template
+void viterbi_algorithm_combined<short,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<int,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<float,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, unsigned char *out
+);
+
+//---------------
+
+template
+void viterbi_algorithm_combined<short,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<int,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<float,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, short *out
+);
+
+//--------------
+
+template
+void viterbi_algorithm_combined<short,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<int,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<float,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, int *out
+);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//===============================================
+
+
+void siso_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ const float *priori, const float *prioro, float *post//,
+ //std::vector<float> &alpha,
+ //std::vector<float> &beta
+ )
+{
+ float norm,mm,minm;
+ std::vector<float> alpha(S*(K+1));
+ std::vector<float> beta(S*(K+1));
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ for(int k=0;k<K;k++) { // forward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ alpha[(k+1)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+ if(SK<0) { // final state not specified
+ for(int i=0;i<S;i++) beta[K*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) beta[K*S+i]=INF;
+ beta[K*S+SK]=0.0;
+ }
+
+ for(int k=K-1;k>=0;k--) { // backward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(int i=0;i<I;i++) {
+ int i0 = j*I+i;
+ mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ beta[k*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ beta[k*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+
+if (POSTI && POSTO)
+{
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*(I+O)+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*(I+O)+i]-=norm; // normalize metrics
+ }
+
+
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*(I+O)+I+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*(I+O)+I+n]-=norm; // normalize metrics
+ }
+}
+else if(POSTI)
+{
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*I+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*I+i]-=norm; // normalize metrics
+ }
+}
+else if(POSTO)
+{
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*O+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*O+n]-=norm; // normalize metrics
+ }
+}
+else
+ throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+}
+
+
+//===========================================================
+
+template <class T>
+void siso_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<T> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const T *observations, float *post
+)
+{
+ float norm,mm,minm;
+ std::vector<float> alpha(S*(K+1));
+ std::vector<float> beta(S*(K+1));
+ float *prioro = new float[O*K];
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ for(int k=0;k<K;k++) { // forward recursion
+ calc_metric(O, D, TABLE, &(observations[k*D]), &(prioro[k*O]),TYPE); // calc metrics
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ alpha[(k+1)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+ if(SK<0) { // final state not specified
+ for(int i=0;i<S;i++) beta[K*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) beta[K*S+i]=INF;
+ beta[K*S+SK]=0.0;
+ }
+
+ for(int k=K-1;k>=0;k--) { // backward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(int i=0;i<I;i++) {
+ int i0 = j*I+i;
+ mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ beta[k*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ beta[k*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+
+ if (POSTI && POSTO)
+ {
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*(I+O)+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*(I+O)+i]-=norm; // normalize metrics
+ }
+
+
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*(I+O)+I+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*(I+O)+I+n]-=norm; // normalize metrics
+ }
+ }
+ else if(POSTI)
+ {
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*I+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*I+i]-=norm; // normalize metrics
+ }
+ }
+ else if(POSTO)
+ {
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*O+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*O+n]-=norm; // normalize metrics
+ }
+ }
+ else
+ throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+ delete [] prioro;
+
+}
+
+//---------
+
+template
+void siso_algorithm_combined<short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const short *observations, float *post
+);
+
+template
+void siso_algorithm_combined<int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const int *observations, float *post
+);
+
+template
+void siso_algorithm_combined<float>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const float *observations, float *post
+);
+
+template
+void siso_algorithm_combined<gr_complex>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const gr_complex *observations, float *post
+);
+
+//=========================================================
+
+template<class Ti, class To>
+void sccc_decoder_combined(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<Ti> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const Ti *observations, To *data
+)
+{
+
+//allocate space for priori, prioro and posti of inner FSM
+std::vector<float> ipriori(blocklength*FSMi.I(),0.0);
+std::vector<float> iprioro(blocklength*FSMi.O());
+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());
+
+// turn observations to neg-log-priors
+for(int k=0;k<blocklength;k++) {
+ calc_metric(FSMi.O(), D, TABLE, &(observations[k*D]), &(iprioro[k*FSMi.O()]),METRIC_TYPE);
+ iprioro[k*FSMi.O()] *= scaling;
+}
+
+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));
+ }
+
+ // run outer SISO
+
+ 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
+
+ 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(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ &(oprioro[0]), data
+ );
+ */
+
+}
+
+
+// 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]=(To)mini;
+}
+
+
+
+}
+
+//-------
+
+template
+void sccc_decoder_combined<float,unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, unsigned char *data
+);
+
+template
+void sccc_decoder_combined<float,short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, short *data
+);
+
+template
+void sccc_decoder_combined<float,int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, int *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, unsigned char *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, short *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, int *data
+);
+
+
+
+//=========================================================
+
+template<class T>
+void sccc_decoder(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ 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(),
+ 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));
+ }
+
+ // run outer SISO
+
+ 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
+
+ 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(),
+ 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;
+ }
+ }
+ data[k]=(T)mini;
+ }
+
+
+
+}
+
+//-------
+
+template
+void sccc_decoder<unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, unsigned char *data
+);
+
+template
+void sccc_decoder<short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, short *data
+);
+
+template
+void sccc_decoder<int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ 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
new file mode 100644
index 000000000..fdb5f398e
--- /dev/null
+++ b/gr-trellis/src/lib/core_algorithms.h
@@ -0,0 +1,128 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_CORE_ALGORITHMS_H
+#define INCLUDED_CORE_ALGORITHMS_H
+
+#include <cmath>
+#include <vector>
+//#include <gr_complex.h>
+#include "metric_type.h"
+#include "fsm.h"
+#include "interleaver.h"
+
+
+float min(float a, float b);
+float min_star(float a, float b);
+
+template <class T>
+void viterbi_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, T *out
+);
+
+template <class Ti, class To>
+void viterbi_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<Ti> &TABLE,
+ trellis_metric_type_t TYPE,
+ const Ti *in, To *out
+);
+
+
+
+void siso_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ const float *priori, const float *prioro, float *post
+);
+
+
+template <class T>
+void siso_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<T> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const T *observations, float *post
+);
+
+
+template<class Ti, class To>
+void sccc_decoder_combined(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<Ti> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const Ti *observations, To *data
+);
+
+
+template<class T>
+void sccc_decoder(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, T *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
+);
+
+
+
+#endif
diff --git a/gr-trellis/src/lib/generate_trellis.py b/gr-trellis/src/lib/generate_trellis.py
index a4206d268..9f845f74a 100644
--- a/gr-trellis/src/lib/generate_trellis.py
+++ b/gr-trellis/src/lib/generate_trellis.py
@@ -28,16 +28,26 @@ import re
other_roots = [
'trellis_encoder_XX',
+ 'trellis_sccc_encoder_XX',
+ 'trellis_pccc_encoder_XX',
'trellis_metrics_X',
'trellis_viterbi_X',
'trellis_viterbi_combined_XX',
+ 'trellis_sccc_decoder_combined_XX',
+ 'trellis_sccc_decoder_X',
+ 'trellis_pccc_decoder_X',
]
other_signatures = (
['bb','bs','bi','ss','si','ii'],
+ ['bb','bs','bi','ss','si','ii'],
+ ['bb','bs','bi','ss','si','ii'],
['s','i','f','c'],
['b','s','i'],
['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/interleaver.cc b/gr-trellis/src/lib/interleaver.cc
index ff15eeadc..131dcb07b 100644
--- a/gr-trellis/src/lib/interleaver.cc
+++ b/gr-trellis/src/lib/interleaver.cc
@@ -124,7 +124,7 @@ interleaver::interleaver(int K, int seed)
//######################################################################
-//# Write an INTERLEAVER specification from a file.
+//# Write an INTERLEAVER specification to a file.
//# Format
//# K
//# blank line
diff --git a/gr-trellis/src/lib/metric_type.h b/gr-trellis/src/lib/metric_type.h
new file mode 100644
index 000000000..a1040f108
--- /dev/null
+++ b/gr-trellis/src/lib/metric_type.h
@@ -0,0 +1,31 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_TRELLIS_METRIC_TYPE_H
+#define INCLUDED_TRELLIS_METRIC_TYPE_H
+
+typedef enum {
+ TRELLIS_EUCLIDEAN = 200, TRELLIS_HARD_SYMBOL, TRELLIS_HARD_BIT
+} trellis_metric_type_t;
+
+#endif
+
diff --git a/gr-trellis/src/lib/trellis_siso_type.h b/gr-trellis/src/lib/siso_type.h
index 3a7163d02..3a7163d02 100644
--- a/gr-trellis/src/lib/trellis_siso_type.h
+++ b/gr-trellis/src/lib/siso_type.h
diff --git a/gr-trellis/src/lib/trellis.i b/gr-trellis/src/lib/trellis.i
index 7e379a918..84b77a286 100644
--- a/gr-trellis/src/lib/trellis.i
+++ b/gr-trellis/src/lib/trellis.i
@@ -41,7 +41,8 @@
%include "trellis_siso_f.i"
%include "trellis_siso_combined_f.i"
-%include "trellis_siso_type.h"
+%include "metric_type.h"
+%include "siso_type.h"
%include "trellis_constellation_metrics_cf.i"
diff --git a/gr-trellis/src/lib/trellis_metrics_X.cc.t b/gr-trellis/src/lib/trellis_metrics_X.cc.t
index 4bdaabc22..cd66df6fb 100644
--- a/gr-trellis/src/lib/trellis_metrics_X.cc.t
+++ b/gr-trellis/src/lib/trellis_metrics_X.cc.t
@@ -22,7 +22,7 @@
// @WARNING@
-#ifndef HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/gr-trellis/src/lib/trellis_metrics_X.h.t b/gr-trellis/src/lib/trellis_metrics_X.h.t
index f862a032d..45d4ace10 100644
--- a/gr-trellis/src/lib/trellis_metrics_X.h.t
+++ b/gr-trellis/src/lib/trellis_metrics_X.h.t
@@ -26,7 +26,7 @@
#define @GUARD_NAME@
#include <gr_block.h>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
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; }
+};
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t
new file mode 100644
index 000000000..40dcd4105
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t
@@ -0,0 +1,90 @@
+/* -*- 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 <iostream>
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (FSM1,ST1,FSM2,ST2,INTERLEAVER,blocklength));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSM1 (FSM1),
+ d_ST1 (ST1),
+ d_FSM2 (FSM2),
+ d_ST2 (ST2),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength)
+{
+ assert(d_FSM1.I() == d_FSM2.I());
+ set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
+
+
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert(noutput_items%d_blocklength ==0);
+ for (int b = 0 ; b<noutput_items/d_blocklength; b++) {
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0]+b*d_blocklength;
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]+b*d_blocklength;
+
+ int ST1_tmp = d_ST1;
+ int ST2_tmp = d_ST2;
+ for (int i = 0; i < d_blocklength; i++){
+ int k = d_INTERLEAVER.INTER()[i];
+ int o1 = d_FSM1.OS()[ST1_tmp*d_FSM1.I()+in[i]];
+ ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
+ int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
+ ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
+ out[i] = (@O_TYPE@) (o1*d_FSM1.O() + o2);
+ }
+ }
+ return noutput_items;
+}
+
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t
new file mode 100644
index 000000000..68ccf75db
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t
@@ -0,0 +1,83 @@
+/* -*- 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 <vector>
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+/*!
+ * \brief SCCC encoder.
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_sync_block
+{
+private:
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+ fsm d_FSM1;
+ int d_ST1;
+ fsm d_FSM2;
+ int d_ST2;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
+ @NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ int ST1 () const { return d_ST1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST2 () const { return d_ST2; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t
new file mode 100644
index 000000000..c02ee428a
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t
@@ -0,0 +1,50 @@
+/* -*- 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 ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+class @NAME@ : public gr_sync_block
+{
+private:
+ @NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ int ST1 () const { return d_ST1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST2 () const { return d_ST2; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t
new file mode 100644
index 000000000..4a0f471fa
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (
+ FSMo, STo0, SToK,
+ FSMi, STi0, STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE
+ ));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ 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_FSMo (FSMo), d_STo0 (STo0), d_SToK (SToK),
+ d_FSMi (FSMi), d_STi0 (STi0), d_STiK (STiK),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength),
+ d_repetitions (repetitions),
+ d_SISO_TYPE (SISO_TYPE)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_relative_rate (1.0 / ((double) d_FSMi.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_FSMi.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++) {
+ sccc_decoder(
+ d_FSMo, d_STo0, d_SToK,
+ d_FSMi, d_STi0, d_STiK,
+ d_INTERLEAVER, d_blocklength, d_repetitions,
+ p2min,
+ &(in[n*d_blocklength*d_FSMi.O()]),&(out[n*d_blocklength])
+ );
+ }
+
+ consume_each (d_FSMi.O() * noutput_items );
+ return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t
new file mode 100644
index 000000000..3adb8a5b7
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ 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_FSMo;
+ fsm d_FSMi;
+ int d_STo0;
+ int d_SToK;
+ int d_STi0;
+ int d_STiK;
+ 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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ 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_sccc_decoder_X.i.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.i.t
new file mode 100644
index 000000000..a4392ee6f
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+);
+
+
+class @NAME@ : public gr_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ 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; }
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t
new file mode 100644
index 000000000..2927e3fe3
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t
@@ -0,0 +1,147 @@
+/* -*- 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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (
+ FSMo, STo0, SToK,
+ FSMi, STi0, STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE,
+ D,
+ TABLE,METRIC_TYPE,
+ scaling
+ ));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSMo (FSMo), d_STo0 (STo0), d_SToK (SToK),
+ d_FSMi (FSMi), d_STi0 (STi0), d_STiK (STiK),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength),
+ d_repetitions (repetitions),
+ d_SISO_TYPE (SISO_TYPE),
+ d_D (D),
+ d_TABLE (TABLE),
+ d_METRIC_TYPE (METRIC_TYPE),
+ d_scaling (scaling)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_relative_rate (1.0 / ((double) d_D));
+ set_output_multiple (d_blocklength);
+}
+
+void @NAME@::set_scaling(float scaling)
+{
+ d_scaling = scaling;
+}
+
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int input_required = d_D * 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 @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ for (int n=0;n<nblocks;n++) {
+ sccc_decoder_combined(
+ d_FSMo, d_STo0, d_SToK,
+ d_FSMi, d_STi0, d_STiK,
+ d_INTERLEAVER, d_blocklength, d_repetitions,
+ p2min,
+ d_D,d_TABLE,
+ d_METRIC_TYPE,
+ d_scaling,
+ &(in[n*d_blocklength*d_D]),&(out[n*d_blocklength])
+ );
+ }
+
+ consume_each (d_D * noutput_items );
+ return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t
new file mode 100644
index 000000000..146c26516
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t
@@ -0,0 +1,124 @@
+/* -*- 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 "calc_metric.h"
+#include "siso_type.h"
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE, // perform "min-sum" or "sum-product" combining
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+);
+
+
+/*!
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_block
+{
+ fsm d_FSMo;
+ fsm d_FSMi;
+ int d_STo0;
+ int d_SToK;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ trellis_siso_type_t d_SISO_TYPE;
+ int d_D;
+ std::vector<@I_TYPE@> d_TABLE;
+ trellis_metric_type_t d_METRIC_TYPE;
+ float d_scaling;
+ std::vector<float> d_buffer;
+
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ int D () const { return d_D; }
+ std::vector<@I_TYPE@> TABLE () const { return d_TABLE; }
+ trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+ float scaling () const { return d_scaling; }
+ void set_scaling (float scaling);
+
+ 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_sccc_decoder_combined_XX.i.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t
new file mode 100644
index 000000000..84f2eb07d
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t
@@ -0,0 +1,73 @@
+/* -*- 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 &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+);
+
+
+class @NAME@ : public gr_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ int D () const { return d_D; }
+ std::vector<@I_TYPE@> TABLE () const { return d_TABLE; }
+ trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+ float scaling() const { return d_scaling; }
+ void set_scaling (float scaling);
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t
new file mode 100644
index 000000000..b1a46ca60
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t
@@ -0,0 +1,91 @@
+/* -*- 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 <iostream>
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (FSMo,STo,FSMi,STi,INTERLEAVER,blocklength));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSMo (FSMo),
+ d_STo (STo),
+ d_FSMi (FSMi),
+ d_STi (STi),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
+
+
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert(noutput_items%d_blocklength ==0);
+ for (int b = 0 ; b<noutput_items/d_blocklength; b++) {
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0]+b*d_blocklength;
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]+b*d_blocklength;
+
+ int STo_tmp = d_STo;
+ for (int i = 0; i < d_blocklength; i++){
+ d_buffer[i] = d_FSMo.OS()[STo_tmp*d_FSMo.I()+in[i]];
+ STo_tmp = (int) d_FSMo.NS()[STo_tmp*d_FSMo.I()+in[i]];
+ }
+ int STi_tmp = d_STi;
+ for (int i = 0; i < d_blocklength; i++){
+ int k = d_INTERLEAVER.INTER()[i];
+ out[i] = (@O_TYPE@) d_FSMi.OS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+ STi_tmp = (int) d_FSMi.NS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+ }
+ }
+ return noutput_items;
+}
+
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t
new file mode 100644
index 000000000..a9e4dc454
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t
@@ -0,0 +1,83 @@
+/* -*- 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 <vector>
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+/*!
+ * \brief SCCC encoder.
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_sync_block
+{
+private:
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+ fsm d_FSMo;
+ int d_STo;
+ fsm d_FSMi;
+ int d_STi;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
+ @NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ int STo () const { return d_STo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STi () const { return d_STi; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t
new file mode 100644
index 000000000..ca6b56199
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t
@@ -0,0 +1,50 @@
+/* -*- 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 &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+class @NAME@ : public gr_sync_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+public:
+ fsm FSMo () const { return d_FSMo; }
+ int STo () const { return d_STo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STi () const { return d_STi; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+};
diff --git a/gr-trellis/src/lib/trellis_siso_combined_f.cc b/gr-trellis/src/lib/trellis_siso_combined_f.cc
index 708608b16..2a4cfa123 100644
--- a/gr-trellis/src/lib/trellis_siso_combined_f.cc
+++ b/gr-trellis/src/lib/trellis_siso_combined_f.cc
@@ -125,6 +125,13 @@ trellis_siso_combined_f::forecast (int noutput_items, gr_vector_int &ninput_item
}
}
+
+
+
+
+/*
+
+
inline float min(float a, float b)
{
return a <= b ? a : b;
@@ -286,7 +293,7 @@ void siso_algorithm_combined(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_siso_combined_f.h b/gr-trellis/src/lib/trellis_siso_combined_f.h
index 6432c2262..786e79386 100644
--- a/gr-trellis/src/lib/trellis_siso_combined_f.h
+++ b/gr-trellis/src/lib/trellis_siso_combined_f.h
@@ -24,8 +24,9 @@
#define INCLUDED_TRELLIS_SISO_COMBINED_F_H
#include "fsm.h"
-#include "trellis_siso_type.h"
-#include "trellis_calc_metric.h"
+#include "siso_type.h"
+#include "calc_metric.h"
+#include "core_algorithms.h"
#include <gr_block.h>
class trellis_siso_combined_f;
diff --git a/gr-trellis/src/lib/trellis_siso_f.cc b/gr-trellis/src/lib/trellis_siso_f.cc
index c8fa8231d..d478c13a3 100644
--- a/gr-trellis/src/lib/trellis_siso_f.cc
+++ b/gr-trellis/src/lib/trellis_siso_f.cc
@@ -116,6 +116,11 @@ trellis_siso_f::forecast (int noutput_items, gr_vector_int &ninput_items_require
}
}
+
+
+
+/* Moved it to "core_algorithms.cc" */
+/*
inline float min(float a, float b)
{
return a <= b ? a : b;
@@ -270,7 +275,7 @@ else
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_siso_f.h b/gr-trellis/src/lib/trellis_siso_f.h
index 3e2c2498b..0e2cba67a 100644
--- a/gr-trellis/src/lib/trellis_siso_f.h
+++ b/gr-trellis/src/lib/trellis_siso_f.h
@@ -24,7 +24,8 @@
#define INCLUDED_TRELLIS_SISO_F_H
#include "fsm.h"
-#include "trellis_siso_type.h"
+#include "siso_type.h"
+#include "core_algorithms.h"
#include <gr_block.h>
class trellis_siso_f;
diff --git a/gr-trellis/src/lib/trellis_viterbi_X.cc.t b/gr-trellis/src/lib/trellis_viterbi_X.cc.t
index 178215362..2254f6450 100644
--- a/gr-trellis/src/lib/trellis_viterbi_X.cc.t
+++ b/gr-trellis/src/lib/trellis_viterbi_X.cc.t
@@ -73,9 +73,22 @@ void
}
}
+/*
+template
+void viterbi_algorithm<@O_TYPE@>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, @O_TYPE@ *out);
+*/
+/* Moved it to "core_algorithms.cc" */
+/*
void viterbi_algorithm(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -141,7 +154,7 @@ void viterbi_algorithm(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_viterbi_X.h.t b/gr-trellis/src/lib/trellis_viterbi_X.h.t
index 67b46a8ee..362d3f57e 100644
--- a/gr-trellis/src/lib/trellis_viterbi_X.h.t
+++ b/gr-trellis/src/lib/trellis_viterbi_X.h.t
@@ -27,6 +27,7 @@
#include "fsm.h"
#include <gr_block.h>
+#include "core_algorithms.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
@@ -78,4 +79,12 @@ public:
gr_vector_void_star &output_items);
};
+
+
+
+
+
+
+
+
#endif
diff --git a/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t b/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
index d365de75f..e883a0ba7 100644
--- a/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
+++ b/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
@@ -90,6 +90,7 @@ void
+/*
void viterbi_algorithm_combined(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -162,7 +163,7 @@ void viterbi_algorithm_combined(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t b/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
index 21307d0e3..35e6c4ce0 100644
--- a/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
+++ b/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
@@ -27,7 +27,8 @@
#include "fsm.h"
#include <gr_block.h>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
+#include "core_algorithms.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;