commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r3470 - in gnuradio/branches/developers/jcorgan/wip: g


From: jcorgan
Subject: [Commit-gnuradio] r3470 - in gnuradio/branches/developers/jcorgan/wip: gnuradio-examples/python/channel-coding gr-error-correcting-codes gr-error-correcting-codes/examples gr-error-correcting-codes/src/lib gr-error-correcting-codes/src/lib/libecc/mld gr-error-correcting-codes/src/python gr-trellis/doc gr-trellis/src/lib gr-wxgui/src/python
Date: Sun, 3 Sep 2006 16:41:05 -0600 (MDT)

Author: jcorgan
Date: 2006-09-03 16:41:04 -0600 (Sun, 03 Sep 2006)
New Revision: 3470

Added:
   
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization.py
   
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization1.py
   
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization2.py
   gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_ecc.py
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.h
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.i
Removed:
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/qa_ecc.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_coding_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_coding_2.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_2.py
Modified:
   
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_sccc_turbo.py
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h
   
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/Makefile.am
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/gr-trellis.xml
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py.xml
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/Makefile.am
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/interleaver.cc
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis.i
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.h
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_X.cc.t
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_c.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_f.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_i.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_s.cc
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.cc
   gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.h
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_X.cc.t
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_b.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_i.cc
   
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_s.cc
   gnuradio/branches/developers/jcorgan/wip/gr-wxgui/src/python/waterfallsink.py
Log:
Merged r3441:3469 from trunk into jcorgan/wip

Modified: 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_sccc_turbo.py
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_sccc_turbo.py
 2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_sccc_turbo.py
 2006-09-03 22:41:04 UTC (rev 3470)
@@ -21,29 +21,33 @@
     siso_in=[]
     siso_out=[]
 
-    for it in range(IT-1):
+    # generate all blocks
+    for it in range(IT):
       inter.append( 
trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) 
)
-      siso_in.append( trellis.siso_f(fi,K,0,3,True,False,type) )
+      siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
       deinter.append( 
trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
 )
-      siso_out.append( trellis.siso_f(fo,K,0,3,False,True,type) )
-      fg.connect (inter[it],(siso_in[it],0))
-      fg.connect (gnd,(siso_out[it],0))
-      fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+      if it < IT-1:
+        siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
+      else:
+        siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs 
needed
 
-    inter.append( 
trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) 
)
-    siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
-    deinter.append( 
trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
 )
-    siso_out.append( trellis.viterbi_s(fo,K,0,-1) )
-    fg.connect (inter[IT-1],(siso_in[IT-1],0))
-    fg.connect (siso_in[IT-1],deinter[IT-1],siso_out[IT-1])
-
     # connect first stage
     fg.connect (gnd,inter[0])
     fg.connect (metrics_in,scale)
     fg.connect (scale,(siso_in[0],1))
-    for it in range(IT-1):
-      fg.connect (siso_out[it],inter[it+1])
-      fg.connect (metrics_in,(siso_in[it+1],1))
+
+    # connect the rest
+    for it in range(IT):
+      if it < IT-1:
+        fg.connect (metrics_in,(siso_in[it+1],1))
+        fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+        fg.connect (gnd,(siso_out[it],0))
+        fg.connect (siso_out[it],inter[it+1])
+        fg.connect (inter[it],(siso_in[it],0))
+      else:
+        fg.connect (siso_in[it],deinter[it],siso_out[it])
+        fg.connect (inter[it],(siso_in[it],0))
+
     return (metrics_in,siso_out[IT-1])
 
 

Copied: 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization.py
 (from rev 3469, 
gnuradio/trunk/gnuradio-examples/python/channel-coding/test_turbo_equalization.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization.py
                         (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization.py
 2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,141 @@
+#!/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
+
+
+def 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
+    metrics_in = 
trellis.metrics_f(fi.O(),dimensionality,tot_constellation,trellis.TRELLIS_EUCLIDEAN)
 # data preprocessing to generate metrics for innner SISO
+    scale = gr.multiply_const_ff(1.0/N0)
+    gnd = gr.vector_source_f([0],True);
+
+    inter=[]
+    deinter=[]
+    siso_in=[]
+    siso_out=[]
+
+    # generate all blocks
+    for it in range(IT):
+      inter.append( 
trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) 
)
+      siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
+      deinter.append( 
trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
 )
+      if it < IT-1:
+        siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
+      else:
+        siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs 
needed
+
+    # connect first stage
+    fg.connect (gnd,inter[0])
+    fg.connect (metrics_in,scale)
+    fg.connect (scale,(siso_in[0],1))
+
+    # connect the rest
+    for it in range(IT):
+      if it < IT-1:
+        fg.connect (metrics_in,(siso_in[it+1],1))
+        fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+        fg.connect (gnd,(siso_out[it],0))
+        fg.connect (siso_out[it],inter[it+1])
+        fg.connect (inter[it],(siso_in[it],0))
+      else:
+        fg.connect (siso_in[it],deinter[it],siso_out[it])
+        fg.connect (inter[it],(siso_in[it],0))
+   
+    return (metrics_in,siso_out[IT-1])
+
+
+def run_test 
(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,tot_constellation,Es,N0,IT,seed):
+    fg = gr.flow_graph ()
+
+    # 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 iouter FSM input cardinality
+    enc_out = trellis.encoder_ss(fo,0) # initial state = 0
+    inter = 
trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
+    enc_in = trellis.encoder_ss(fi,0) # initial state = 0
+    # essentially here we implement the combination of modulation and channel 
as a memoryless modulation (the memory induced by the channel is hidden in the 
innner FSM)
+    mod = gr.chunks_to_symbols_sf(tot_constellation,dimensionality)
+
+    # CHANNEL
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+    
+    # RX
+    (head,tail) = 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,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(); 
+    
+    fg.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
+    fg.connect (mod,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,head)
+    fg.connect (tail,fsmi2s,dst)
+    
+    fg.run()
+
+    ntotal = dst.ntotal ()
+    nright = dst.nright ()
+    runlength = dst.runlength ()
+    #print ntotal,nright,runlength 
+    
+    return (ntotal,ntotal-nright)
+
+
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 3:
+        fname_out=args[0]
+        esn0_db=float(args[1])
+        rep=int(args[2])
+    else:
+        sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out 
Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    Kb=64*16  # packet size in bits (multiple of 16)
+    modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined 
modulations
+    channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined 
test channels
+    fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+    fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM 
automatically
+    if fo.O() != fi.I():
+        sys.stderr.write ('Incompatible cardinality between outer and inner 
FSM.\n')
+        sys.exit (1)
+    bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM 
input symbol
+    K=Kb/bitspersymbol # packet size in trellis steps
+    interleaver=trellis.interleaver(K,666) # construct a random interleaver
+    tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # 
generate the lookup table (normalize energy to 1)
+    dimensionality = tot_channel[0]
+    tot_constellation = tot_channel[1]
+    if len(tot_constellation)/dimensionality != fi.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and lookup 
table size.\n')
+        sys.exit (1)
+    N0=pow(10.0,-esn0_db/10.0); # 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
+    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,tot_constellation,1,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:])
+

Copied: 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization1.py
 (from rev 3469, 
gnuradio/trunk/gnuradio-examples/python/channel-coding/test_turbo_equalization1.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization1.py
                                (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization1.py
        2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,147 @@
+#!/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
+
+def 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
+    metrics_in = 
trellis.metrics_f(fi.O(),dimensionality,tot_constellation,trellis.TRELLIS_EUCLIDEAN)
 # data preprocessing to generate metrics for innner SISO
+    scale = gr.multiply_const_ff(1.0/N0)
+    gnd = gr.vector_source_f([0],True);
+
+    inter=[]
+    deinter=[]
+    siso_in=[]
+    siso_out=[]
+
+    # generate all blocks
+    for it in range(IT):
+      inter.append( 
trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) 
)
+      siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
+      deinter.append( 
trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
 )
+      if it < IT-1:
+        siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
+      else:
+        siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs 
needed
+
+    # connect first stage
+    fg.connect (gnd,inter[0])
+    fg.connect (metrics_in,scale)
+    fg.connect (scale,(siso_in[0],1))
+
+    # connect the rest
+    for it in range(IT):
+      if it < IT-1:
+        fg.connect (scale,(siso_in[it+1],1))
+        fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+        fg.connect (gnd,(siso_out[it],0))
+        fg.connect (siso_out[it],inter[it+1])
+        fg.connect (inter[it],(siso_in[it],0))
+      else:
+        fg.connect (siso_in[it],deinter[it],siso_out[it])
+        fg.connect (inter[it],(siso_in[it],0))
+
+    return (metrics_in,siso_out[IT-1])
+
+
+def run_test 
(fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,Es,N0,IT,seed):
+    fg = gr.flow_graph ()
+    L = len(channel)
+
+    # TX
+    # this for loop is TOO slow in python!!!
+    packet = [0]*(K)
+    random.seed(seed)
+    for i in range(len(packet)):
+        packet[i] = random.randint(0, 2**bitspersymbol - 1) # random symbols
+    src = gr.vector_source_s(packet,False)
+    enc_out = trellis.encoder_ss(fo,0) # initial state = 0
+    inter = 
trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
+    mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+
+    # CHANNEL
+    isi = gr.fir_filter_fff(1,channel)
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+    
+    # RX
+    (head,tail) = 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
 
+    dst = gr.vector_sink_s(); 
+    
+    fg.connect (src,enc_out,inter,mod)
+    fg.connect (mod,isi,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,head)
+    fg.connect (tail,dst)
+    
+    fg.run()
+
+    data = dst.data()
+    ntotal = len(data)
+    nright=0
+    for i in range(ntotal):
+        if packet[i]==data[i]:
+            nright=nright+1
+        #else:
+            #print "Error in ", i
+ 
+    return (ntotal,ntotal-nright)
+
+
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 3:
+        fname_out=args[0]
+        esn0_db=float(args[1])
+        rep=int(args[2])
+    else:
+        sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out 
Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    Kb=64*16  # packet size in bits (multiple of 16)
+    modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined 
modulations
+    channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined 
test channels
+    fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+    fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM 
automatically
+    if fo.O() != fi.I():
+        sys.stderr.write ('Incompatible cardinality between outer and inner 
FSM.\n')
+        sys.exit (1)
+    bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM 
input symbol
+    K=Kb/bitspersymbol # packet size in trellis steps
+    interleaver=trellis.interleaver(K,666) # construct a random interleaver
+    tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # 
generate the lookup table (normalize energy to 1)
+    dimensionality = tot_channel[0]
+    tot_constellation = tot_channel[1]
+    if len(tot_constellation)/dimensionality != fi.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and lookup 
table size.\n')
+        sys.exit (1)
+    N0=pow(10.0,-esn0_db/10.0); # 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
+    terr_p=0 # total number of packets in error
+
+    for i in range(rep):
+        
(s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,1,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:])
+

Copied: 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization2.py
 (from rev 3469, 
gnuradio/trunk/gnuradio-examples/python/channel-coding/test_turbo_equalization2.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization2.py
                                (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gnuradio-examples/python/channel-coding/test_turbo_equalization2.py
        2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,147 @@
+#!/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
+
+def 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,type):
+    scale = gr.multiply_const_ff(math.sqrt(1.0/N0))
+    gnd = gr.vector_source_f([0],True);
+
+    inter=[]
+    deinter=[]
+    siso_in=[]
+    siso_out=[]
+
+    # generate all blocks
+    for it in range(IT):
+      inter.append( 
trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) 
)
+      siso_in.append( 
trellis.siso_combined_f(fi,K,0,-1,True,False,type,dimensionality,tot_constellation,trellis.TRELLIS_EUCLIDEAN)
 )
+      deinter.append( 
trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
 )
+      if it < IT-1:
+        siso_out.append( trellis.siso_f(fo,K,0,-1,False,True,type) )
+      else:
+        siso_out.append( trellis.viterbi_s(fo,K,0,-1) ) # no soft outputs 
needed
+
+    # connect first stage
+    fg.connect (gnd,inter[0])
+    fg.connect (scale,(siso_in[0],1))
+
+    # connect the rest
+    for it in range(IT):
+      if it < IT-1:
+        fg.connect (scale,(siso_in[it+1],1))
+        fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+        fg.connect (gnd,(siso_out[it],0))
+        fg.connect (siso_out[it],inter[it+1])
+        fg.connect (inter[it],(siso_in[it],0))
+      else:
+        fg.connect (siso_in[it],deinter[it],siso_out[it])
+        fg.connect (inter[it],(siso_in[it],0))
+
+    return (scale,siso_out[IT-1])
+
+
+def run_test 
(fo,fi,interleaver,Kb,bitspersymbol,K,channel,modulation,dimensionality,tot_constellation,Es,N0,IT,seed):
+    fg = gr.flow_graph ()
+    L = len(channel)
+
+    # TX
+    # this for loop is TOO slow in python!!!
+    packet = [0]*(K)
+    random.seed(seed)
+    for i in range(len(packet)):
+        packet[i] = random.randint(0, 2**bitspersymbol - 1) # random symbols
+    src = gr.vector_source_s(packet,False)
+    enc_out = trellis.encoder_ss(fo,0) # initial state = 0
+    inter = 
trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
+    mod = gr.chunks_to_symbols_sf(modulation[1],modulation[0])
+
+    # CHANNEL
+    isi = gr.fir_filter_fff(1,channel)
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+    
+    # RX
+    (head,tail) = 
make_rx(fg,fo,fi,dimensionality,tot_constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
 
+    dst = gr.vector_sink_s(); 
+    
+    fg.connect (src,enc_out,inter,mod)
+    fg.connect (mod,isi,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,head)
+    fg.connect (tail,dst)
+    
+    fg.run()
+
+    data = dst.data()
+    ntotal = len(data)
+    nright=0
+    for i in range(ntotal):
+        if packet[i]==data[i]:
+            nright=nright+1
+        #else:
+            #print "Error in ", i
+ 
+    return (ntotal,ntotal-nright)
+
+
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 3:
+        fname_out=args[0]
+        esn0_db=float(args[1])
+        rep=int(args[2])
+    else:
+        sys.stderr.write ('usage: test_turbo_equalization.py fsm_name_out 
Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    Kb=64*16  # packet size in bits (multiple of 16)
+    modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined 
modulations
+    channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined 
test channels
+    fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+    fi=trellis.fsm(len(modulation[1]),len(channel)) # generate the FSM 
automatically
+    if fo.O() != fi.I():
+        sys.stderr.write ('Incompatible cardinality between outer and inner 
FSM.\n')
+        sys.exit (1)
+    bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM 
input symbol
+    K=Kb/bitspersymbol # packet size in trellis steps
+    interleaver=trellis.interleaver(K,666) # construct a random interleaver
+    tot_channel = fsm_utils.make_isi_lookup(modulation,channel,True) # 
generate the lookup table (normalize energy to 1)
+    dimensionality = tot_channel[0]
+    N0=pow(10.0,-esn0_db/10.0); # noise variance
+    tot_constellation =[0]*len(tot_channel[1])  
+    for i in range(len(tot_channel[1])):
+      tot_constellation[i] = tot_channel[1][i] * math.sqrt(1.0/N0)
+    if len(tot_constellation)/dimensionality != fi.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and lookup 
table size.\n')
+        sys.exit (1)
+    IT = 3 # number of turbo iterations
+
+    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,channel,modulation,dimensionality,tot_constellation,1,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:])
+

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples 
(from rev 3469, gnuradio/trunk/gr-error-correcting-codes/examples)

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py
 (from rev 3469, 
gnuradio/trunk/gr-error-correcting-codes/examples/qa_test_coding_1.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py
                             (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_1.py
     2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or 
/dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", 
default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(src_out_chan))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = src.output_signature().sizeof_stream_item(1)
+       frame_size = 1000
+       do_mux_outputs = 0
+       enc_code_in_chan = src_out_chan
+       code_generators = [05, 06] #, 03, 04] # , 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       if do_mux_outputs == 1:
+           enc_dec_chan = 1
+       else:
+           enc_dec_chan = enc_code_out_chan
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+# for now
+       ss2s = gr.streams_to_stream (1, enc_dec_chan);
+       ns = gr.null_sink (1);
+# end for now
+
+#      ss_dec = error-correcting-codes.frames_to_streams (audio_el_size, 1, 
1000)
+
+       for i in range (src_out_chan):
+           self.connect ((src, i), (ss_enc, i))
+# for now
+       for i in range (enc_dec_chan):
+           self.connect ((ss_enc, i), (ss2s, i))
+       self.connect (ss2s, ns)
+# end for now
+
+#      for i in range (enc_dec_chan):
+#          self.connect ((ss_enc, i), (ss_dec, i))
+
+#      for i in range (dst_in_chan):
+#          self.connect ((ss_dec, i), (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py
 (from rev 3469, 
gnuradio/trunk/gr-error-correcting-codes/examples/qa_test_coding_2.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py
                             (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_coding_2.py
     2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+#
+# Copyright 2006 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or 
/dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", 
default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       enc_chan_in = 2
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(enc_chan_in))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = dst.input_signature().sizeof_stream_item(0)
+       frame_size = 10
+       enc_code_in_chan = enc_chan_in
+       code_generators = [05, 06] #, 03, 04] #, 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+
+       for i in range (src_out_chan):
+           p2up = gr.packed_to_unpacked_bb (1, 1)
+           self.connect ((src, i), p2up, (ss_enc, i))
+
+       tau_bits = 0  # 0 -> decode all first
+       ss_dec = error-correcting-codes.dec_blk_conv_soft_full (audio_el_size,
+                                            frame_size,
+                                            do_termination,
+                                            do_mux_outputs,
+                                            enc_code_in_chan,
+                                            enc_code_out_chan,
+                                            code_generators)
+        up2bf0 = gr.chunks_to_symbols_bf ([1.0, -1.0])
+        self.connect ((ss_enc, 0), p2up0, up2bf0, (ss_dec, 0))
+        if enc_dec_chan > 1:
+           p2up1 = gr.packed_to_unpacked_bb (1, 1)
+           up2bf1 = gr.chunks_to_symbols_bf ([1.0, -1.0])
+           self.connect ((ss_enc, 1), p2up1, up2bf1, (ss_dec, 1))
+
+       for i in range (dst_in_chan):
+           self.connect ((ss_dec, i), (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py
 (from rev 3469, 
gnuradio/trunk/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py
                              (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_1.py
      2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or 
/dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", 
default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(src_out_chan))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = src.output_signature().sizeof_stream_item(1)
+       frame_size = 10
+       enc_code_in_chan = src_out_chan
+       code_generators = [05, 06] #, 03, 04] # , 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+       for i in range (enc_code_in_chan):
+           self.connect ((src, i), (ss_enc, i))
+
+       for i in range (enc_code_out_chan):
+           ns = gr.null_sink (1)
+           self.connect ((ss_enc, i), ns)
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py
 (from rev 3469, 
gnuradio/trunk/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py
                              (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/examples/qa_test_encoder_convolutional_2.py
      2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# Copyright 2006 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+import ecc
+
+def main ():
+       e1 = ecc.streams_encode_convolutional (100, 3, 2, [1, 0, 5, 0, 1, 6])
+
+       e2 = ecc.streams_encode_convolutional (100, 2, 3, [1, 0, 0, 1, 5, 6])
+
+       e3 = ecc.streams_encode_convolutional_feedback (100, 2, 3, [1, 7, 0, 1, 
5, 6], [1, 1, 1, 1, 017, 017])
+
+if __name__ == '__main__':
+    main ()

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc
       2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc
       2006-09-03 22:41:04 UTC (rev 3470)
@@ -23,78 +23,15 @@
 #include <n2bs.h>
 #include <iostream>
 
-static const int g_num_bits_per_byte = 8;
-
-std::string DoIt (long long number, char digits)
+std::string _n2bs_helper(unsigned long long  v, size_t nbinary_digits)
 {
-  std::string retVal (digits, '0');
-  if (number != 0)
-    for (char n = digits-1; n >= 0; n--) {
-      if (number & 1) {
+  std::string retVal (nbinary_digits, '0');
+  if (v != 0)
+    for (int n = int(nbinary_digits) - 1; n >= 0; n--) {
+      if (v & 1) {
        retVal[n] = '1';
       }
-      number >>= 1;
+      v >>= 1;
     }
   return (retVal);
 }
-
-std::string n2bs (char number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (char) * g_num_bits_per_byte))
-    digits = sizeof (char) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (short number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (short) * g_num_bits_per_byte))
-    digits = sizeof (short) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (int number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (int) * g_num_bits_per_byte))
-    digits = sizeof (int) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (long number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (long long) * g_num_bits_per_byte))
-    digits = sizeof (long long) * g_num_bits_per_byte;
-  return DoIt (number, (char) digits);
-}
-std::string n2bs (long long number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (long long) * g_num_bits_per_byte))
-    digits = sizeof (long long) * g_num_bits_per_byte;
-  return DoIt (number, (char) digits);
-}
-std::string n2bs (unsigned char number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (unsigned char) * g_num_bits_per_byte))
-    digits = sizeof (unsigned char) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (unsigned short number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (unsigned short) * g_num_bits_per_byte))
-    digits = sizeof (unsigned short) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (unsigned int number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (unsigned int) * g_num_bits_per_byte))
-    digits = sizeof (unsigned int) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (unsigned long number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (unsigned long long) * 
g_num_bits_per_byte))
-    digits = sizeof (unsigned long long) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}
-std::string n2bs (unsigned long long number, unsigned char digits)
-{
-  if (digits > (unsigned char)(sizeof (unsigned long long) * 
g_num_bits_per_byte))
-    digits = sizeof (unsigned long long) * g_num_bits_per_byte;
-  return DoIt ((long long) number, (char) digits);
-}

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h
        2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h
        2006-09-03 22:41:04 UTC (rev 3470)
@@ -24,205 +24,14 @@
 #define INCLUDED_N2BS_H
 
 #include <string>
+#include <algorithm>
 
-std::string n2bs (char number, unsigned char digits);
-std::string n2bs (short number, unsigned char digits);
-std::string n2bs (int number, unsigned char digits);
-std::string n2bs (long number, unsigned char digits);
-std::string n2bs (long long number, unsigned char digits);
-std::string n2bs (unsigned char number, unsigned char digits);
-std::string n2bs (unsigned short number, unsigned char digits);
-std::string n2bs (unsigned int number, unsigned char digits);
-std::string n2bs (unsigned long number, unsigned char digits);
-std::string n2bs (unsigned long long number, unsigned char digits);
+std::string _n2bs_helper(unsigned long long v, size_t nbinary_digits);
 
-inline std::string n2bs (char number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, char digits)
-{return (n2bs (number, (unsigned char) digits));};
+template<class T>
+std::string n2bs(T v, size_t nbinary_digits)
+{
+  return _n2bs_helper((unsigned long long)v, std::min(nbinary_digits, 8 * 
sizeof(T)));
+}
 
-inline std::string n2bs (char number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, unsigned short digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, short digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, unsigned int digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, int digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, unsigned long digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, long digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, unsigned long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-
-inline std::string n2bs (char number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (short number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (int number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (long long number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned char number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned short number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned int number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-inline std::string n2bs (unsigned long long number, long long digits)
-{return (n2bs (number, (unsigned char) digits));};
-
 #endif /* INCLUDED_N2BS_H */

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/lib/qa_ecc.py

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/Makefile.am
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/Makefile.am
   2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/Makefile.am
   2006-09-03 22:41:04 UTC (rev 3470)
@@ -23,10 +23,9 @@
 
 EXTRA_DIST = run_tests.in
 
-# Disabled until fix for finding an audio module in build tree
-# TESTS = run_tests
+TESTS = run_tests
 
-noinst_PYTHON =  qa_test_coding_1.py qa_test_coding_2.py
+noinst_PYTHON =  qa_ecc.py
 
 grpython_PYTHON =
 

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_ecc.py
 (from rev 3469, gnuradio/trunk/gr-error-correcting-codes/src/python/qa_ecc.py)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_ecc.py
                             (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_ecc.py
     2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright 2006 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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+import ecc
+
+class qa_ecc (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have drivers, etc.  Don't try to run anything"""
+        pass
+
+if __name__ == '__main__':
+    gr_unittest.main ()

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_coding_1.py

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_coding_2.py

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py

Deleted: 
gnuradio/branches/developers/jcorgan/wip/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_2.py

Modified: gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/gr-trellis.xml
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/gr-trellis.xml      
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/gr-trellis.xml      
2006-09-03 22:41:04 UTC (rev 3470)
@@ -178,12 +178,18 @@
   std::vector&lt;int&gt; d_OS;
   std::vector&lt;int&gt; d_PS;
   std::vector&lt;int&gt; d_PI;
+  std::vector&lt;int&gt; d_TMi;
+  std::vector&lt;int&gt; d_TMl;
+  void generate_PS_PI ();
+  void generate_TM ();
+  bool find_es(int es);
 public:
   fsm();
   fsm(const fsm &amp;FSM);
-  fsm(const int I, const int S, const int O, const std::vector&lt;int&gt; 
&amp;NS, const std::vector&lt;int&gt; &amp;OS);
+  fsm(int I, int S, int O, const std::vector&lt;int&gt; &amp;NS, const 
std::vector&lt;int&gt; &amp;OS);
   fsm(const char *name);
-  fsm(const int mod_size, const int ch_length);
+  fsm(int k, int n, const std::vector&lt;int&gt; &amp;G);
+  fsm(int mod_size, int ch_length);
   int I () const { return d_I; }
   int S () const { return d_S; }
   int O () const { return d_O; }
@@ -191,6 +197,8 @@
   const std::vector&lt;int&gt; &amp; OS () const { return d_OS; }
   const std::vector&lt;int&gt; &amp; PS () const { return d_PS; }
   const std::vector&lt;int&gt; &amp; PI () const { return d_PI; }
+  const std::vector&lt;int&gt; &amp; TMi () const { return d_TMi; }
+  const std::vector&lt;int&gt; &amp; TMl () const { return d_TMl; }
 };
 </programlisting>
 
@@ -247,10 +255,26 @@
 </para>
 </listitem>
 
+
 <listitem>
-<para>The third way is specific to FSMs resulting from shift registers, and 
the output symbol being the entire transition (ie, current_state and 
current_input). These FSMs are usefull when describibg ISI channels. In 
particular the state is comprised of the.....
+<para>
+The third way is specific to FSMs representing binary (n,k) conolutional 
codes. These FSMs are specified by the number of input bits k, the number of 
output bits n, and the generator matrix, which is a k x n matrix of integers 
+G = [g<subscript>i,j</subscript>]<subscript>i=1:k, j=1:n</subscript>, given as 
an one-dimensional STL vector.
+Each integer g<subscript>i,j</subscript> is the decimal representation of the 
+polynomial g<subscript>i,j</subscript>(D) (e.g., g<subscript>i,j</subscript>= 
6 = 110<subscript>2</subscript> is interpreted as 
g<subscript>i,j</subscript>(D)=1+D) describing the connections from  the 
sequence x<subscript>i</subscript> to 
+y<subscript>j</subscript> (e.g., in the above example 
y<subscript>j</subscript>(k) = x<subscript>i</subscript>(k) + 
x<subscript>i</subscript>(k-1)).
 </para>
 <programlisting>
+  fsm(int k, int n, const std::vector&lt;int&gt; &amp;G);
+</programlisting>
+</listitem>
+
+
+<listitem>
+<para>
+The fourth way is specific to FSMs resulting from shift registers, and the 
output symbol being the entire transition (ie, current_state and 
current_input). These FSMs are usefull when describibg ISI channels. In 
particular the state is comprised of the input symbols x(k-1), 
x(k-2),...,x(k-L), where L = ch_length-1 and each x(i) belongs to an alphabet 
of size mod_size. The output is taken to be x(k), x(k-1), x(k-2),...,x(k-L) (in 
decimal format)
+</para>
+<programlisting>
   fsm(const int mod_size, const int ch_length);
 </programlisting>
 </listitem>
@@ -259,7 +283,7 @@
 
 
 <para>
-Finally, as can be seen from the above description, there are
+As can be seen from the above description, there are
 two more variables included in the FSM class implementation, 
 the PS and the PI matrices. These are computed internally 
 when an FSM is instantiated and their meaning is as follows.
@@ -289,12 +313,146 @@
 </para>
 
 
+<para>
+Finally, there are
+two more variables included in the FSM class implementation,
+the TMl and the TMi matrices. These are both S x S matrices (represented as 
STL vectors) computed internally
+when an FSM is instantiated and their meaning is as follows.
+TMl(i,j) is the minimum number of trellis steps required to go from state i to 
state j.
+Similarly, TMi(i,j) is the initial input required to get you from state i to 
state j in the minimum number of steps. As an example, if TMl(1,4)=2, it means 
that you need 2 steps in the trellis to get from state 1 to state 4. Further,
+if TMi(1,4)=0 it means that the first such step will be followed if when at 
state 1 the input is 0. Furthermore, suppose that NS(1,0)=2. Then, TMl(2,4) 
should be 1 (ie, one more step is needed when starting from state 2 and having 
state 4 as the final destination). Finally, TMi(2,4) will give us the second 
input required to complete the path from 1 to 4.
+These matrices are useful when we want to implement an encoder with proper 
state termination. For instance, based on these matrices we can evaluate how 
many 
+additional input symbols (and which particular inputs) are required to be 
appended at the end of an input sequence so that the final state is always 0.
+
+</para>
+
+
 </sect1>
 
 
 
+<!--=====================================================-->
+<sect1 id="blocks"><title>Blocks Using the FSM structure</title>
 
+<para>
+In this section we give a brief description of the basic blocks implemented 
that make use of the previously described FSM structure.
+</para>
 
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="encoder"><title>Trellis Encoder</title>
+<para>
+The trellis.encoder_XX(FSM, ST) block instantiates an FSM encoder 
corresponding to the fsm FSM and having initial state ST. The input and output 
is a sequence of bytes, shorts or integers. 
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="decoder"><title>Viterbi Decoder</title>
+<para>
+The trellis.viterbi_X(FSM, K, S0, SK) block instantiates a Viterbi decoder 
+for a sequence of K trellis steps generated by the given FSM and with initial 
and final states set to S0 and SK, respectively (S0 and/or SK are set to -1
+if the corresponding states are not fixed/known at the receiver side).
+The output of this block is a sequence of K bytes, shorts or integers 
representing the estimated input (i.e., uncoded) sequence.
+The input is a sequence of K x FSM.O( ) floats, where the k x K + i 
+float represents the cost associated with the k-th
+step in the trellis and the i-th FSM output.
+Observe that these inputs are generated externally and thus the Viterbi block 
is not informed of their meaning (they can be genarated as soft or hard inputs, 
etc); the only requirement is that they represent additive costs.
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="metrics"><title>Metrics Calculator</title>
+<para>
+The trellis.metrics_X(O,D,TABLE,TYPE) block is responsible for 
+transforming the channel output to the stream of metrics appropriate as 
+inputs to the Viterbi block described above. For each D input 
bytes/shorts/integers/floats/complexes it produces O output floats 
+
+</para>
+
+<para>
+
+The parameter TYPE dictates how these metrics are generated:
+
+<itemizedlist>
+<listitem><para>
+TRELLIS_EUCLIDEAN: for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</subscript>)
 
+evaluates
+</para>
+<para>
+||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript>
 = sum<subscript>j=1</subscript><superscript>D</superscript> 
|r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
+</para>
+<para>
+for each of the O hypothesized ouput
+symbols c<subscript>i</subscript> = 
(c<subscript>i,1</subscript>,c<subscript>i,2</subscript>,...,c<subscript>i,D</subscript>)
 defined in the vector TABLE,
+where TABLE[i * D + j] = c<subscript>i,j</subscript>.
+</para></listitem>
+
+
+<listitem><para>
+TRELLIS_HARD_SYMBOL: for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</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>
+</para>
+<para>
+and outputs a sequence of O floats of the form (0,...,0,1,0,...,0), where the 
+i<subscript>0</subscript> position is set to 1. This corresponds to generating 
hard inputs (based on the symbol-wise Hamming distance) to the Viterbi 
algorithm.
+</para></listitem>
+
+
+<listitem><para>
+TRELLIS_HARD_BIT (not yet implemented): for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</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>
+</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 
+d<subscript>i</subscript> is the bitwise Hamming distance between i and  
i<subscript>0</subscript>. This corresponds to generating hard inputs (based on 
the bit-wise Hamming distance) to the Viterbi algorithm.
+</para></listitem>
+
+
+</itemizedlist>
+
+
+</para>
+</sect2>
+
+
+
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="viterbi_combined"><title>Combined Metrics Calculator and Viterbi 
Decoder</title>
+<para>
+Although the separation of metric calculation and Viterbi algorithm blocks
+is consistent with our goal of providing general blocks that can be easily 
+reused, this separation might result in large input/output buffer sizes
+betwen blocks. Indeed for an FSM with a large output alphabet, the 
+output of the metric block/input of the Viterbi block is FSM.O( ) floats for
+each trellis step. Sometimes this results in buffer overflow even for
+moderate sequence lengths.
+To overcome this problem we provide a block that incorporates the metric 
calculation and Viterbi algorithm into a single GNU Radio block, namely
+trellis.viterbi_combined_X( FSM, K, S0, SK, D, TABLE, TYPE) where the 
arguments are exactly those used in the aforementioned two blocks.
+</para>
+</sect2>
+
+
+
+
+
+</sect1>
+
+
 <!--=====================================================-->
 <sect1 id="tcm"><title>TCM: A Complete Example</title>
 
@@ -329,7 +487,7 @@
 The FSM is first intantiated in "main" by 
 </para>
 <programlisting>
- 62      f=trellis.fsm(fname) # get the FSM specification from a file (will 
hopefully be automated in the future...)
+ 62      f=trellis.fsm(fname) # get the FSM specification from a file
 </programlisting>
 
 
@@ -355,11 +513,11 @@
 
 
 <para>
-The FSM will produce K output symbols (remeber the FSM produces always one 
output symbol for each input symbol). Each of these symbols needs to be 
modulated. Since we are simulating the communication system, we need not 
simulate the actual waveforms. An M-ary, N-dimensional
-modulation is completely specified by a set of M, N-dimensional real vectors. 
In "fsm_utils.py" file we give a number of useful modulations with the 
following format: modulation = (N,constellation), where
-constellation=[c11,c12,...,c1N,c21,c22,...,c2N,...,cM1,cM2,...cMN].
+The FSM will produce K output symbols (remeber the FSM produces always one 
output symbol for each input symbol). Each of these symbols needs to be 
modulated. Since we are simulating the communication system, we need not 
simulate the actual waveforms. An M-ary, D-dimensional
+modulation is completely specified by a set of M, D-dimensional real vectors. 
In "fsm_utils.py" file we give a number of useful modulations with the 
following format: modulation = (D,constellation), where
+constellation=[c11,c12,...,c1D,c21,c22,...,c2D,...,cM1,cM2,...cMD].
 The meaning of the above is that every constellation point c_i
-is an N-dimnsional vector c_i=(ci1,ci2,...,ciN)
+is an D-dimnsional vector c_i=(ci1,ci2,...,ciD)
 For instance, 4-ary PAM is represented as
 (1,[-3, -1, 1, 3]), while QPSK is represented as
 (2,[1, 0, 0, 1, 0, -1, -1, 0]). In our example we choose QPSK modulation.
@@ -416,7 +574,7 @@
 We now need to modulate the FSM output symbols.
 The "chunks_to_symbols_sf" is essentially a memoryless mapper which 
 for each input symbol y_k 
-outputs a sequence of N numbers ci1,ci2,...,ciN  representing the 
+outputs a sequence of D numbers ci1,ci2,...,ciD  representing the 
 coordianates of the constellation symbol c_i with i=y_k.
 </para>
 <programlisting>
@@ -425,8 +583,8 @@
 
 <para>
 The channel is AWGN with appropriate noise variance.
-For each transmitted symbol c_k=(ck1,ck2,...,ckN) we receive a noisy version
-r_k=(rk1,rk2,...,rkN).
+For each transmitted symbol c_k=(ck1,ck2,...,ckD) we receive a noisy version
+r_k=(rk1,rk2,...,rkD).
 </para>
 <programlisting>
  22      # CHANNEL
@@ -451,10 +609,10 @@
 O such numbers (one for each possible output symbol y_k). 
 This is done 
 in "metrics_f". In particular, metrics_f is a memoryless device
-taking N inputs at a time and producing O outputs. The N inputs are
-rk1,rk2,...,rkN.
+taking D inputs at a time and producing O outputs. The D inputs are
+rk1,rk2,...,rkD.
 The O outputs
-are the costs associated with observations rk1,rk2,...,rkN and
+are the costs associated with observations rk1,rk2,...,rkD and
 hypothesized output symbols c_1,c_2,...,c_M. For instance,
 if we choose to perform soft-input VA, we need to evaluate
 the Euclidean distance between r_k and each of c_1,c_2,...,c_M,
@@ -514,21 +672,20 @@
 
 <listitem>
 <para>
-automate fsm generation from generator polynomials 
-(feedforward or feedback form).
+automate fsm generation from rational functions
+(feedback form).
 </para>
 </listitem>
 
 <listitem>
 <para>
-Optimize the VA code.
+Optimize the VA code if possible.
 </para>
 </listitem>
 
 <listitem>
 <para>
-Provide implementation of soft-input soft-output (SISO) decoders for 
-potential use in concatenated systems. Also a host of suboptimal
+A host of suboptimal
 decoders, eg, sphere decoding, M- and T- algorithms, sequential decoding, etc.
 can be implemented.
 </para>
@@ -542,6 +699,7 @@
 use the encoder, and SISO blocks and connect them
 through GNU radio or we should implement turbo-decoding
 as a single block (issues with buffering between blocks).
+So far the former has been implemented.
 </para>
 </listitem>
 

Modified: gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py 
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py 
2006-09-03 22:41:04 UTC (rev 3470)
@@ -59,7 +59,7 @@
         sys.exit (1)
 
     # system parameters
-    f=trellis.fsm(fname) # get the FSM specification from a file (will 
hopefully be automated in the future...)
+    f=trellis.fsm(fname) # get the FSM specification from a file
     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

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py.xml
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py.xml     
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/doc/test_tcm.py.xml     
2006-09-03 22:41:04 UTC (rev 3470)
@@ -61,7 +61,7 @@
  59          sys.exit (1)
  60  
  61      # system parameters
- 62      f=trellis.fsm(fname) # get the FSM specification from a file (will 
hopefully be automated in the future...)
+ 62      f=trellis.fsm(fname) # get the FSM specification from a file
  63      Kb=1024*16  # packet size in bits (make it multiple of 16 so it can 
be packed in a short)
  64      bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per 
FSM input symbol
  65      K=Kb/bitspersymbol # packet size in trellis steps

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/Makefile.am
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/Makefile.am     
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/Makefile.am     
2006-09-03 22:41:04 UTC (rev 3470)
@@ -70,6 +70,7 @@
         trellis_calc_metric.cc         \
         trellis_permutation.cc         \
        trellis_siso_f.cc               \
+       trellis_siso_combined_f.cc      \
        $(GENERATED_CC)                 
 
 # magic flags
@@ -96,6 +97,7 @@
         trellis_permutation.h          \
         trellis_siso_type.h            \
        trellis_siso_f.h                \
+       trellis_siso_combined_f.h               \
        $(GENERATED_H)                  
 
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/interleaver.cc
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/interleaver.cc  
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/interleaver.cc  
2006-09-03 22:41:04 UTC (rev 3470)
@@ -97,7 +97,7 @@
     d_INTER[i]=i;
     tmp[i] = rand(); 
   }
-  //quicksort_index <int> (tmp,d_INTER,0,d_K-1); got to resolve this...
+  //quicksort_index <int> (tmp,d_INTER,0,d_K-1); //got to resolve this...
   quicksort_index1 (tmp,d_INTER,0,d_K-1);
 
   // generate DEINTER table

Modified: gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis.i
===================================================================
--- gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis.i       
2006-09-03 20:27:42 UTC (rev 3469)
+++ gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis.i       
2006-09-03 22:41:04 UTC (rev 3470)
@@ -11,6 +11,7 @@
 #include "interleaver.h"
 #include "trellis_permutation.h"
 #include "trellis_siso_f.h"
+#include "trellis_siso_combined_f.h"
 #include <stdexcept>
 %}
 
@@ -20,6 +21,7 @@
 %include "interleaver.i"
 %include "trellis_permutation.i"
 %include "trellis_siso_f.i"
+%include "trellis_siso_combined_f.i"
 
 %include "trellis_metric_type.h"
 %include "trellis_siso_type.h"

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.cc
  2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.cc
  2006-09-03 22:41:04 UTC (rev 3470)
@@ -24,7 +24,9 @@
 #include <stdexcept>
 #include "trellis_calc_metric.h"
 
-void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short 
*in, float *metric, trellis_metric_type_t type)
+
+
+void calc_metric(int O, int D, const std::vector<short> &TABLE, const short 
*in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -64,8 +66,7 @@
 }
 
 
-
-void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, 
float *metric, trellis_metric_type_t type)
+void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *in, 
float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -106,7 +107,7 @@
 
 
 
-void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float 
*in, float *metric, trellis_metric_type_t type)
+void calc_metric(int O, int D, const std::vector<float> &TABLE, const float 
*in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -146,7 +147,7 @@
 }
 
 
-void calc_metric_c(int O, int D, const std::vector<gr_complex> &TABLE, const 
gr_complex *in, float *metric, trellis_metric_type_t type)
+void calc_metric(int O, int D, const std::vector<gr_complex> &TABLE, const 
gr_complex *in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -183,3 +184,47 @@
     throw std::runtime_error ("Invalid metric type.");
   }
 }
+
+
+/*
+template <class T> void calc_metric(int O, int D, const std::vector<T> &TABLE, 
const T *in, float *metric, trellis_metric_type_t type)
+{
+  float minm = FLT_MAX;
+  int minmi = 0;
+
+  switch (type){
+  case TRELLIS_EUCLIDEAN:
+    for(int o=0;o<O;o++) {
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        T s=in[m]-TABLE[o*D+m];
+        gr_complex sc(1.0*s,0);
+        metric[o]+=(s*conj(s)).real();
+      }
+    }
+    break;
+  case TRELLIS_HARD_SYMBOL:
+    for(int o=0;o<O;o++) {
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        T s=in[m]-TABLE[o*D+m];
+        gr_complex sc(1.0*s,0);
+        metric[o]+=(s*conj(s)).real();
+      }
+      if(metric[o]<minm) {
+        minm=metric[o];
+        minmi=o;
+      }
+    }
+    for(int o=0;o<O;o++) {
+      metric[o] = (o==minmi?0.0:1.0);
+    }
+    break;
+  case TRELLIS_HARD_BIT:
+    throw std::runtime_error ("Invalid metric type (not yet implemented).");
+    break;
+  default:
+    throw std::runtime_error ("Invalid metric type.");
+  }
+}
+*/

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.h
   2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_calc_metric.h
   2006-09-03 22:41:04 UTC (rev 3470)
@@ -27,12 +27,16 @@
 #include <gr_complex.h>
 #include <trellis_metric_type.h>
 
-void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short 
*in, float *metric, trellis_metric_type_t type);
 
-void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, 
float *metric, trellis_metric_type_t type);
+void calc_metric(int O, int D, const std::vector<short> &TABLE, const short 
*in, float *metric, trellis_metric_type_t type);
 
-void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float 
*in, float *metric, trellis_metric_type_t type);
+void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *in, 
float *metric, trellis_metric_type_t type);
 
-void calc_metric_c(int O, int D, const std::vector<gr_complex> &TABLE, const 
gr_complex *in, float *metric, trellis_metric_type_t type);
+void calc_metric(int O, int D, const std::vector<float> &TABLE, const float 
*in, float *metric, trellis_metric_type_t type);
 
+void calc_metric(int O, int D, const std::vector<gr_complex> &TABLE, const 
gr_complex *in, float *metric, trellis_metric_type_t type);
+
+
+//template <class T> void calc_metric(int O, int D, const std::vector<T> 
&TABLE, const T *in, float *metric, trellis_metric_type_t type);
+
 #endif

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_X.cc.t
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_X.cc.t
  2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_X.cc.t
  2006-09-03 22:41:04 UTC (rev 3470)
@@ -83,6 +83,7 @@
   float *out = (float *) output_items[m];
 
   for (int i = 0; i < noutput_items / d_O ; i++){
+/*
 #if @IS_SHORT@
     calc_metric_s(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #elif @IS_INT@
@@ -92,6 +93,8 @@
 #elif @IS_COMPLEX@
     calc_metric_c(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #endif
+*/
+    calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
   } 
 }
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_c.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_c.cc
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_c.cc
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -83,6 +83,7 @@
   float *out = (float *) output_items[m];
 
   for (int i = 0; i < noutput_items / d_O ; i++){
+/*
 #if 0
     calc_metric_s(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #elif 0
@@ -92,6 +93,8 @@
 #elif 1
     calc_metric_c(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #endif
+*/
+    calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
   } 
 }
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_f.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_f.cc
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_f.cc
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -83,6 +83,7 @@
   float *out = (float *) output_items[m];
 
   for (int i = 0; i < noutput_items / d_O ; i++){
+/*
 #if 0
     calc_metric_s(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #elif 0
@@ -92,6 +93,8 @@
 #elif 0
     calc_metric_c(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #endif
+*/
+    calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
   } 
 }
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_i.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_i.cc
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_i.cc
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -83,6 +83,7 @@
   float *out = (float *) output_items[m];
 
   for (int i = 0; i < noutput_items / d_O ; i++){
+/*
 #if 0
     calc_metric_s(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #elif 1
@@ -92,6 +93,8 @@
 #elif 0
     calc_metric_c(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #endif
+*/
+    calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
   } 
 }
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_s.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_s.cc
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_metrics_s.cc
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -83,6 +83,7 @@
   float *out = (float *) output_items[m];
 
   for (int i = 0; i < noutput_items / d_O ; i++){
+/*
 #if 1
     calc_metric_s(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #elif 0
@@ -92,6 +93,8 @@
 #elif 0
     calc_metric_c(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
 #endif
+*/
+    calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]),&(out[i*d_O]), d_TYPE);
   } 
 }
 

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.cc
 (from rev 3469, gnuradio/trunk/gr-trellis/src/lib/trellis_siso_combined_f.cc)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.cc
                              (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.cc
      2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,350 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <trellis_siso_combined_f.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <assert.h>
+#include <iostream>
+  
+static const float INF = 1.0e9;
+
+trellis_siso_combined_f_sptr 
+trellis_make_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE)
+{
+  return trellis_siso_combined_f_sptr (new trellis_siso_combined_f 
(FSM,K,S0,SK,POSTI,POSTO,SISO_TYPE,D,TABLE,TYPE));
+}
+
+trellis_siso_combined_f::trellis_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE)
+  : gr_block ("siso_combined_f",
+                         gr_make_io_signature (1, -1, sizeof (float)),
+                         gr_make_io_signature (1, -1, sizeof (float))),  
+  d_FSM (FSM),
+  d_K (K),
+  d_S0 (S0),
+  d_SK (SK),
+  d_POSTI (POSTI),
+  d_POSTO (POSTO),
+  d_SISO_TYPE (SISO_TYPE),
+  d_D (D),
+  d_TABLE (TABLE),
+  d_TYPE (TYPE)//,
+  //d_alpha(FSM.S()*(K+1)),
+  //d_beta(FSM.S()*(K+1))
+{
+    int multiple;
+    if (d_POSTI && d_POSTO) 
+        multiple = d_FSM.I()+d_FSM.O();
+    else if(d_POSTI)
+        multiple = d_FSM.I();
+    else if(d_POSTO)
+        multiple = d_FSM.O();
+    else
+        throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+    //printf("constructor: Multiple = %d\n",multiple);
+    set_output_multiple (d_K*multiple);
+    //what is the meaning of relative rate for a block with 2 inputs?
+    //set_relative_rate ( multiple / ((double) d_FSM.I()) );
+    // it turns out that the above gives problems in the scheduler, so 
+    // let's try (assumption O>I)
+    //set_relative_rate ( multiple / ((double) d_FSM.O()) );
+    // I am tempted to automate like this
+    if(d_FSM.I() <= d_D)
+      set_relative_rate ( multiple / ((double) d_D) );
+    else
+      set_relative_rate ( multiple / ((double) d_FSM.I()) ); 
+}
+
+
+void
+trellis_siso_combined_f::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+{
+  int multiple;
+  if (d_POSTI && d_POSTO)
+      multiple = d_FSM.I()+d_FSM.O();
+  else if(d_POSTI)
+      multiple = d_FSM.I();
+  else if(d_POSTO)
+      multiple = d_FSM.O();
+  else
+      throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+  //printf("forecast: Multiple = %d\n",multiple); 
+  assert (noutput_items % (d_K*multiple) == 0);
+  int input_required1 =  d_FSM.I() * (noutput_items/multiple) ;
+  int input_required2 =  d_D * (noutput_items/multiple) ;
+  //printf("forecast: Output requirements:  %d\n",noutput_items);
+  //printf("forecast: Input requirements:  %d   
%d\n",input_required1,input_required2);
+  unsigned ninputs = ninput_items_required.size();
+  assert(ninputs % 2 == 0);
+  for (unsigned int i = 0; i < ninputs/2; i++) {
+    ninput_items_required[2*i] = input_required1;
+    ninput_items_required[2*i+1] = input_required2;
+  }
+}
+
+inline float min(float a, float b)
+{
+  return a <= b ? a : b;
+}
+
+inline float min_star(float a, float b)
+{
+  return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a));
+}
+
+void siso_algorithm_combined(int I, int S, int O, 
+             const std::vector<int> &NS,
+             const std::vector<int> &OS,
+             const std::vector<int> &PS,
+             const 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//,
+             //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));
+  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(int i=0;i<I;i++) {
+              int i0 = j*I+i;
+              
mm=alpha[k*S+PS[i0]]+priori[k*I+PI[i0]]+prioro[k*O+OS[PS[i0]*I+PI[i0]]];
+              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;
+
+}
+
+
+
+
+
+
+int
+trellis_siso_combined_f::general_work (int noutput_items,
+                        gr_vector_int &ninput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  assert (input_items.size() == 2*output_items.size());
+  int nstreams = output_items.size();
+  //printf("general_work:Streams:  %d\n",nstreams); 
+  int multiple;
+  if (d_POSTI && d_POSTO)
+      multiple = d_FSM.I()+d_FSM.O();
+  else if(d_POSTI)
+      multiple = d_FSM.I();
+  else if(d_POSTO)
+      multiple = d_FSM.O();
+  else
+      throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+  assert (noutput_items % (d_K*multiple) == 0);
+  int nblocks = noutput_items / (d_K*multiple);
+  //printf("general_work:Blocks:  %d\n",nblocks); 
+  //for(int i=0;i<ninput_items.size();i++)
+      //printf("general_work:Input items available:  %d\n",ninput_items[i]);
+
+  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;
+
+
+  for (int m=0;m<nstreams;m++) {
+    const float *in1 = (const float *) input_items[2*m];
+    const float *in2 = (const float *) input_items[2*m+1];
+    float *out = (float *) output_items[m];
+    for (int n=0;n<nblocks;n++) {
+      siso_algorithm_combined(d_FSM.I(),d_FSM.S(),d_FSM.O(),
+        d_FSM.NS(),d_FSM.OS(),d_FSM.PS(),d_FSM.PI(),
+        d_K,d_S0,d_SK,
+        d_POSTI,d_POSTO,
+        p2min,
+        d_D,d_TABLE,d_TYPE,
+        &(in1[n*d_K*d_FSM.I()]),&(in2[n*d_K*d_D]),
+        &(out[n*d_K*multiple])//,
+        //d_alpha,d_beta
+        );
+    }
+  }
+
+  for (unsigned int i = 0; i < input_items.size()/2; i++) {
+    consume(2*i,d_FSM.I() * noutput_items / multiple );
+    consume(2*i+1,d_D * noutput_items / multiple );
+  }
+
+  return noutput_items;
+}

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.h
 (from rev 3469, gnuradio/trunk/gr-trellis/src/lib/trellis_siso_combined_f.h)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.h
                               (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.h
       2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,109 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_TRELLIS_SISO_COMBINED_F_H
+#define INCLUDED_TRELLIS_SISO_COMBINED_F_H
+
+#include "fsm.h"
+#include "trellis_siso_type.h"
+#include "trellis_calc_metric.h"
+#include <gr_block.h>
+
+class trellis_siso_combined_f;
+typedef boost::shared_ptr<trellis_siso_combined_f> 
trellis_siso_combined_f_sptr;
+
+trellis_siso_combined_f_sptr trellis_make_siso_combined_f (
+    const fsm &FSM,    // underlying FSM
+    int K,             // block size in trellis steps
+    int S0,            // initial state (put -1 if not specified)
+    int SK,            // final state (put -1 if not specified)
+    bool POSTI,                // true if you want a-posteriori info about the 
input symbols to be mux-ed in the output
+    bool POSTO,                // true if you want a-posteriori info about the 
output symbols to be mux-ed in the output
+    trellis_siso_type_t d_SISO_TYPE, // perform "min-sum" or "sum-product" 
combining 
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE
+);
+
+
+
+class trellis_siso_combined_f : public gr_block
+{
+  fsm d_FSM;
+  int d_K;
+  int d_S0;
+  int d_SK;
+  bool d_POSTI;
+  bool d_POSTO;
+  trellis_siso_type_t d_SISO_TYPE;
+  int d_D;
+  std::vector<float> d_TABLE;
+  trellis_metric_type_t d_TYPE;
+  //std::vector<float> d_alpha;
+  //std::vector<float> d_beta;
+
+  friend trellis_siso_combined_f_sptr trellis_make_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t d_SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE);
+
+
+  trellis_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t d_SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE);
+
+
+public:
+  fsm FSM () const { return d_FSM; }
+  int K () const { return d_K; }
+  int S0 () const { return d_S0; }
+  int SK () const { return d_SK; }
+  bool POSTI () const { return d_POSTI; }
+  bool POSTO () const { return d_POSTO; }
+  trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+  int D () const { return d_D; }
+  std::vector<float> TABLE () const { return d_TABLE; }
+  trellis_metric_type_t TYPE () const { return d_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

Copied: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.i
 (from rev 3469, gnuradio/trunk/gr-trellis/src/lib/trellis_siso_combined_f.i)
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.i
                               (rev 0)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_combined_f.i
       2006-09-03 22:41:04 UTC (rev 3470)
@@ -0,0 +1,64 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(trellis,siso_combined_f);
+
+trellis_siso_combined_f_sptr trellis_make_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE);
+
+
+class trellis_siso_combined_f : public gr_block
+{
+private:
+  trellis_siso_combined_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE,
+    int D,
+    const std::vector<float> &TABLE,
+    trellis_metric_type_t TYPE);
+
+public:
+    fsm FSM () const { return d_FSM; }
+    int K () const { return d_K; }
+    int S0 () const { return d_S0; }
+    int SK () const { return d_SK; }
+    bool POSTI () const { return d_POSTI; }
+    bool POSTO () const { return d_POSTO; }
+    trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+    int D () const { return d_D; }
+    std::vector<float> TABLE () const { return d_TABLE; }
+    trellis_metric_type_t TYPE () const { return d_TYPE; }
+};

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.cc   
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.cc   
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -62,9 +62,9 @@
   d_SK (SK),
   d_POSTI (POSTI),
   d_POSTO (POSTO),
-  d_SISO_TYPE (SISO_TYPE),
-  d_alpha(FSM.S()*(K+1)),
-  d_beta(FSM.S()*(K+1))
+  d_SISO_TYPE (SISO_TYPE)//,
+  //d_alpha(FSM.S()*(K+1)),
+  //d_beta(FSM.S()*(K+1))
 {
     int multiple;
     if (d_POSTI && d_POSTO) 
@@ -77,10 +77,16 @@
         throw std::runtime_error ("Not both POSTI and POSTO can be false.");
     //printf("constructor: Multiple = %d\n",multiple);
     set_output_multiple (d_K*multiple);
-    //what is the meaning of relative rate for this?
-    // it was suggested to use the one furthest from 1.0
-    // let's do it.
-    set_relative_rate ( multiple / ((double) d_FSM.I()) );
+    //what is the meaning of relative rate for a block with 2 inputs?
+    //set_relative_rate ( multiple / ((double) d_FSM.I()) );
+    // it turns out that the above gives problems in the scheduler, so 
+    // let's try (assumption O>I)
+    //set_relative_rate ( multiple / ((double) d_FSM.O()) );
+    // I am tempted to automate like this
+    if(d_FSM.I() <= d_FSM.O())
+      set_relative_rate ( multiple / ((double) d_FSM.O()) );
+    else
+      set_relative_rate ( multiple / ((double) d_FSM.I()) ); 
 }
 
 
@@ -129,11 +135,14 @@
              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) 
+             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
@@ -309,8 +318,9 @@
         d_POSTI,d_POSTO,
         p2min,
         &(in1[n*d_K*d_FSM.I()]),&(in2[n*d_K*d_FSM.O()]),
-        &(out[n*d_K*multiple]),
-        d_alpha,d_beta);
+        &(out[n*d_K*multiple])//,
+        //d_alpha,d_beta
+        );
     }
   }
 

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.h    
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_siso_f.h    
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -31,13 +31,14 @@
 typedef boost::shared_ptr<trellis_siso_f> trellis_siso_f_sptr;
 
 trellis_siso_f_sptr trellis_make_siso_f (
-    const fsm &FSM, 
-    int K,
-    int S0,
-    int SK,
-    bool POSTI,
-    bool POSTO,
-    trellis_siso_type_t d_SISO_TYPE);
+    const fsm &FSM,    // underlying FSM
+    int K,             // block size in trellis steps
+    int S0,            // initial state (put -1 if not specified)
+    int SK,            // final state (put -1 if not specified)
+    bool POSTI,                // true if you want a-posteriori info about the 
input symbols to be mux-ed in the output
+    bool POSTO,                // true if you want a-posteriori info about the 
output symbols to be mux-ed in the output
+    trellis_siso_type_t d_SISO_TYPE // perform "min-sum" or "sum-product" 
combining 
+);
 
 
 
@@ -50,8 +51,8 @@
   bool d_POSTI;
   bool d_POSTO;
   trellis_siso_type_t d_SISO_TYPE;
-  std::vector<float> d_alpha;
-  std::vector<float> d_beta;
+  //std::vector<float> d_alpha;
+  //std::vector<float> d_beta;
 
   friend trellis_siso_f_sptr trellis_make_siso_f (
     const fsm &FSM,

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_X.cc.t
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_X.cc.t
 2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_X.cc.t
 2006-09-03 22:41:04 UTC (rev 3470)
@@ -114,7 +114,7 @@
 
   alphai=0;
   for(int k=0;k<K;k++) {
-      calc_metric_f(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+      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;

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_b.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_b.cc
   2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_b.cc
   2006-09-03 22:41:04 UTC (rev 3470)
@@ -114,7 +114,7 @@
 
   alphai=0;
   for(int k=0;k<K;k++) {
-      calc_metric_f(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+      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;

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_i.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_i.cc
   2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_i.cc
   2006-09-03 22:41:04 UTC (rev 3470)
@@ -114,7 +114,7 @@
 
   alphai=0;
   for(int k=0;k<K;k++) {
-      calc_metric_f(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+      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;

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_s.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_s.cc
   2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-trellis/src/lib/trellis_viterbi_combined_s.cc
   2006-09-03 22:41:04 UTC (rev 3470)
@@ -114,7 +114,7 @@
 
   alphai=0;
   for(int k=0;k<K;k++) {
-      calc_metric_f(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+      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;

Modified: 
gnuradio/branches/developers/jcorgan/wip/gr-wxgui/src/python/waterfallsink.py
===================================================================
--- 
gnuradio/branches/developers/jcorgan/wip/gr-wxgui/src/python/waterfallsink.py   
    2006-09-03 20:27:42 UTC (rev 3469)
+++ 
gnuradio/branches/developers/jcorgan/wip/gr-wxgui/src/python/waterfallsink.py   
    2006-09-03 22:41:04 UTC (rev 3470)
@@ -50,7 +50,7 @@
             self.avg_alpha = avg_alpha
         self.title = title
         self.input_is_real = input_is_real
-        (self.r_fd, self.w_fd) = os.pipe()
+        self.msgq = gr.msg_queue(2)         # queue up to 2 messages
 
     def set_average(self, average):
         self.average = average
@@ -91,7 +91,7 @@
         c2mag = gr.complex_to_mag(self.fft_size)
         self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
         log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size))
-        sink = gr.file_descriptor_sink(gr.sizeof_float * self.fft_size, 
self.w_fd)
+        sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, 
True)
 
         fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
         gr.hier_block.__init__(self, fg, s2p, sink)
@@ -120,7 +120,7 @@
         c2mag = gr.complex_to_mag(self.fft_size)
         self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
         log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size))
-        sink = gr.file_descriptor_sink(gr.sizeof_float * self.fft_size, 
self.w_fd)
+        sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, 
True)
 
         fg.connect(s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
         gr.hier_block.__init__(self, fg, s2p, sink)
@@ -146,10 +146,10 @@
 
 
 class input_watcher (threading.Thread):
-    def __init__ (self, file_descriptor, fft_size, event_receiver, **kwds):
+    def __init__ (self, msgq, fft_size, event_receiver, **kwds):
         threading.Thread.__init__ (self, **kwds)
         self.setDaemon (1)
-        self.file_descriptor = file_descriptor
+        self.msgq = msgq
         self.fft_size = fft_size
         self.event_receiver = event_receiver
         self.keep_running = True
@@ -157,12 +157,18 @@
 
     def run (self):
         while (self.keep_running):
-            s = gru.os_read_exactly (self.file_descriptor,
-                                     gr.sizeof_float * self.fft_size)
-            if not s:
-                self.keep_running = False
-                break
+            msg = self.msgq.delete_head()  # blocking read of message queue
+            itemsize = int(msg.arg1())
+            nitems = int(msg.arg2())
 
+            s = msg.to_string()            # get the body of the msg as a 
string
+
+            # There may be more than one FFT frame in the message.
+            # If so, we take only the last one
+            if nitems > 1:
+                start = itemsize * (nitems - 1)
+                s = s[start:start+itemsize]
+
             complex_data = Numeric.fromstring (s, Numeric.Float32)
             de = DataEvent (complex_data)
             wx.PostEvent (self.event_receiver, de)
@@ -195,7 +201,7 @@
         wx.EVT_CLOSE (self, self.on_close_window)
         self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
 
-        self.input_watcher = input_watcher(fftsink.r_fd, fftsink.fft_size, 
self)
+        self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, 
self)
 
 
     def on_close_window (self, event):





reply via email to

[Prev in Thread] Current Thread [Next in Thread]