3 # Copyright 2004 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
29 from gnuradio import trellis
33 ######################################################################
34 # Decimal to any base conversion.
35 # Convert 'num' to a list of 'l' numbers representing 'num'
36 # to base 'base' (most significant symbol first).
37 ######################################################################
38 def dec2base(num,base,l):
45 print 'Number ', num, ' requires more than ', l, 'digits.'
49 ######################################################################
50 # Conversion from any base to decimal.
51 # Convert a list 's' of symbols to a decimal number
52 # (most significant symbol first)
53 ######################################################################
56 for i in range(len(s)):
61 ######################################################################
62 # Generate a new FSM representing the concatenation of two FSMs
63 ######################################################################
64 def fsm_concatenate(f1,f2):
66 print "Not compatible FSMs\n"
72 for s1 in range(f1.S()):
73 for s2 in range(f2.S()):
74 for i in range(f1.I()):
75 ns1=f1.NS()[s1*f1.I()+i]
76 o1=f1.OS()[s1*f1.I()+i]
77 ns2=f2.NS()[s2*f2.I()+o1]
78 o2=f2.OS()[s2*f2.I()+o1]
86 f=trellis.fsm(I,S,O,nsm,osm)
89 ######################################################################
90 # Generate a new FSM representing n stages through the original FSM
91 ######################################################################
98 for s in range(f.S()):
100 ii=dec2base(i,f.I(),n)
104 oo[k]=f.OS()[ns*f.I()+ii[k]]
105 ns=f.NS()[ns*f.I()+ii[k]]
108 osm[s*I+i]=base2dec(oo,f.O())
111 f=trellis.fsm(I,S,O,nsm,osm)
117 ######################################################################
118 # Automatically generate the lookup table that maps the FSM outputs
119 # to channel inputs corresponding to a channel 'channel' and a modulation
120 # 'mod'. Optional normalization of channel to unit energy.
121 # This table is used by the 'metrics' block to translate
122 # channel outputs to metrics for use with the Viterbi algorithm.
123 # Limitations: currently supports only one-dimensional modulations.
124 ######################################################################
125 def make_isi_lookup(mod,channel,normalize):
127 constellation = mod[1]
131 for i in range(len(channel)):
132 p = p + channel[i]**2
133 for i in range(len(channel)):
134 channel[i] = channel[i]/math.sqrt(p)
136 lookup=range(len(constellation)**len(channel))
137 for o in range(len(constellation)**len(channel)):
138 ss=dec2base(o,len(constellation),len(channel))
140 for i in range(len(channel)):
141 ll=ll+constellation[ss[i]]*channel[i]
150 ######################################################################
151 # A list of common modulations.
152 # Format: (dimensionality,constellation)
153 ######################################################################
155 pam4 = (1,[-3, -1, 3, 1]) # includes Gray mapping
156 pam8 = (1,[-7, -5, -3, -1, 1, 3, 5, 7])
161 -1, 0]) # includes Gray mapping
162 psk8=(2,[math.cos(2*math.pi*0/8), math.sin(2*math.pi*0/8), \
163 math.cos(2*math.pi*1/8), math.sin(2*math.pi*1/8), \
164 math.cos(2*math.pi*2/8), math.sin(2*math.pi*2/8), \
165 math.cos(2*math.pi*3/8), math.sin(2*math.pi*3/8), \
166 math.cos(2*math.pi*4/8), math.sin(2*math.pi*4/8), \
167 math.cos(2*math.pi*5/8), math.sin(2*math.pi*5/8), \
168 math.cos(2*math.pi*6/8), math.sin(2*math.pi*6/8), \
169 math.cos(2*math.pi*7/8), math.sin(2*math.pi*7/8)])
173 orth4=(4,[1, 0, 0, 0, \
178 ######################################################################
179 # A list of channels to be tested
180 ######################################################################
182 # C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001)
183 c_channel = [0.227, 0.460, 0.688, 0.460, 0.227]
194 if __name__ == '__main__':
195 f1=trellis.fsm('fsm_files/awgn1o2_4.fsm')
196 #f2=trellis.fsm('fsm_files/awgn2o3_4.fsm')
197 print f1.I(), f1.S(), f1.O()
200 #print f2.I(), f2.S(), f2.O()
203 ##f1.write_trellis_svg('f1.svg',4)
204 #f2.write_trellis_svg('f2.svg',4)
205 #f=fsm_concatenate(f1,f2)
209 print f.I(), f.S(), f.O()
212 #f.write_trellis_svg('f.svg',4)